예제 #1
0
        private bool ParseRelUnits(ClockToken[] dt, ref System.Int32 parsePos, ClockRelTimespan diff)
        // time difference to evaluate
        {
            int pos = parsePos;

            if (pos + 2 < dt.Length && dt[pos].is_Renamed('+') && dt[pos + 1].UNumber && dt[pos + 2].Unit)
            {
                diff.addUnit(dt[pos + 2], dt[pos + 1].Int);
                parsePos = pos + 3;
                return true;
            }
            if (pos + 2 < dt.Length && dt[pos].is_Renamed('-') && dt[pos + 1].UNumber && dt[pos + 2].Unit)
            {
                diff.addUnit(dt[pos + 2], -dt[pos + 1].Int);
                parsePos = pos + 3;
                return true;
            }
            if (pos + 1 < dt.Length && dt[pos].UNumber && dt[pos + 1].Unit)
            {
                diff.addUnit(dt[pos + 1], dt[pos].Int);
                parsePos = pos + 2;
                return true;
            }
            else if (pos + 2 < dt.Length && dt[pos].is_Renamed(ClockToken.NEXT) && dt[pos + 1].UNumber && dt[pos + 2].Unit)
            {
                diff.addUnit(dt[pos + 2], dt[pos + 1].Int);
                parsePos = pos + 3;
                return true;
            }
            if (pos + 1 < dt.Length && dt[pos].is_Renamed(ClockToken.NEXT) && dt[pos + 1].Unit)
            {
                diff.addUnit(dt[pos + 1]);
                parsePos = pos + 2;
                return true;
            }
            if (pos < dt.Length && dt[pos].Unit)
            {
                diff.addUnit(dt[pos]);
                parsePos = pos + 1;
                return true;
            }
            return false;
        }
예제 #2
0
        private bool ParseOrdMonth(ClockToken[] dt, ref System.Int32 parsePos, ClockRelTimespan diff)
        // time difference to evaluate
        {
            int pos = parsePos;

            if (pos + 2 < dt.Length && dt[pos].is_Renamed(ClockToken.NEXT) && dt[pos + 1].UNumber && dt[pos + 2].is_Renamed(ClockToken.MONTH))
            {
                diff.addOrdMonth(dt[pos + 2].Int, dt[pos + 1].Int);
                parsePos = pos + 3;
                return true;
            }
            if (pos + 1 < dt.Length && dt[pos].is_Renamed(ClockToken.NEXT) && dt[pos + 1].is_Renamed(ClockToken.MONTH))
            {
                diff.addOrdMonth(dt[pos + 1].Int, 1);
                parsePos = pos + 2;
                return true;
            }
            return false;
        }
예제 #3
0
        private bool ParseRelSpec(ClockToken[] dt, ref System.Int32 parsePos, ClockRelTimespan diff)
        // time difference to evaluate
        {
            if (!ParseRelUnits(dt, ref parsePos, diff))
            {
                return false;
            }

            int pos = parsePos;
            if (pos < dt.Length && dt[pos].is_Renamed(ClockToken.AGO))
            {
                diff.negate();
                parsePos = pos + 1;
            }
            return true;
        }
예제 #4
0
        private bool ParseDay(ClockToken[] dt, ref System.Int32 parsePos, ClockRelTimespan diff)
        // time difference to evaluate
        {
            int pos = parsePos;

            if (pos + 2 < dt.Length && dt[pos].is_Renamed('+') && dt[pos + 1].UNumber && dt[pos + 2].is_Renamed(ClockToken.DAY))
            {
                diff.setWeekday(dt[pos + 2].Int, dt[pos + 1].Int);
                parsePos = pos + 3;
                return true;
            }
            if (pos + 2 < dt.Length && dt[pos].is_Renamed('-') && dt[pos + 1].UNumber && dt[pos + 2].is_Renamed(ClockToken.DAY))
            {
                diff.setWeekday(dt[pos + 2].Int, -dt[pos + 1].Int);
                parsePos = pos + 3;
                return true;
            }
            if (pos + 1 < dt.Length && dt[pos].is_Renamed(ClockToken.NEXT) && dt[pos + 1].is_Renamed(ClockToken.DAY))
            {
                diff.setWeekday(dt[pos + 1].Int, 2);
                parsePos = pos + 2;
                return true;
            }
            if (pos + 1 < dt.Length && dt[pos].is_Renamed(ClockToken.DAY) && dt[pos + 1].is_Renamed(','))
            {
                diff.setWeekday(dt[pos].Int);
                parsePos = pos + 2;
                return true;
            }
            if (pos + 1 < dt.Length && dt[pos].UNumber && dt[pos + 1].is_Renamed(ClockToken.DAY))
            {
                diff.setWeekday(dt[pos + 1].Int, dt[pos].Int);
                parsePos = pos + 2;
                return true;
            }
            if (pos < dt.Length && dt[pos].is_Renamed(ClockToken.DAY))
            {
                diff.setWeekday(dt[pos].Int);
                parsePos = pos + 1;
                return true;
            }
            return false;
        }
예제 #5
0
        private System.DateTime GetDate(string dateString, System.DateTime baseDate, bool useGMT)
        {
            if (useGMT)
            {
                baseDate = baseDate.ToUniversalTime();
            }
            TclDateTime calendar = new TclDateTime();
            calendar.dateTime = baseDate;
            calendar.hour = 0;
            calendar.minute = 0;
            calendar.second = 0;
            calendar.millisecond = 0;

            ClockToken[] dt = GetTokens(dateString, false);

            System.Int32 parsePos = 0;
            ClockRelTimespan diff = new ClockRelTimespan();
            int hasTime = 0;
            int hasZone = 0;
            int hasDate = 0;
            int hasDay = 0;
            int hasOrdMonth = 0;
            int hasRel = 0;

            while (parsePos < dt.Length)
            {
                if (ParseTime(dt, ref parsePos, calendar))
                {
                    hasTime++;
                }
                else if (ParseZone(dt, ref parsePos, calendar))
                {
                    hasZone++;
                }
                else if (ParseIso(dt, ref parsePos, calendar))
                {
                    hasDate++;
                }
                else if (ParseDate(dt, ref parsePos, calendar))
                {
                    hasDate++;
                }
                else if (ParseDay(dt, ref parsePos, diff))
                {
                    hasDay++;
                }
                else if (ParseOrdMonth(dt, ref parsePos, diff))
                {
                    hasOrdMonth++;
                }
                else if (ParseRelSpec(dt, ref parsePos, diff))
                {
                    hasRel++;
                }
                else if (ParseNumber(dt, ref parsePos, calendar, hasDate > 0 && hasTime > 0 && hasRel == 0))
                {
                    if (hasDate == 0 || hasTime == 0 || hasRel > 0)
                    {
                        hasTime++;
                    }
                }
                else if (ParseTrek(dt, ref parsePos, calendar))
                {
                    hasDate++;
                    hasTime++;
                }
                else
                {
                    goto failed;
                }
            }

            if (hasTime > 1 || hasZone > 1 || hasDate > 1 || hasDay > 1 || hasOrdMonth > 1)
            {
                goto failed;
            }

            // The following line handles years that are specified using
            // only two digits.  The line of code below implements a policy
            // defined by the X/Open workgroup on the millinium rollover.
            // Note: some of those dates may not actually be valid on some
            // platforms.  The POSIX standard startes that the dates 70-99
            // shall refer to 1970-1999 and 00-38 shall refer to 2000-2038.
            // This later definition should work on all platforms.

            int thisYear = calendar.year;
            if (thisYear < 100)
            {
                if (thisYear >= 69)
                {
                    calendar.year = thisYear + 1900;
                }
                else
                {
                    calendar.year = thisYear + 2000;
                }
            }

            if (hasRel > 0)
            {
                if (hasTime == 0 && hasDate == 0 && hasDay == 0)
                {
                    calendar.dateTime = baseDate;
                }
                // Certain JDK implementations are buggy WRT DST.
                // Work around this issue by adding a day instead
                // of a days worth of seconds.
                int seconds_in_day = (60 * 60 * 24);
                int seconds = diff.Seconds;
                bool negative_seconds = (seconds < 0);
                int days = 0;
                if (negative_seconds)
                    seconds *= (-1);
                while (seconds >= seconds_in_day)
                {
                    seconds -= seconds_in_day;
                    days++;
                }
                if (negative_seconds)
                {
                    seconds *= (-1);
                    days *= (-1);
                }
                if (days != 0)
                {

                    //					calendar.add(SupportClass.CalendarManager.DATE, days);
                }
                if (seconds != 0)
                {

                    //					calendar.add(SupportClass.CalendarManager.SECOND, seconds);
                }

                //				calendar.add(SupportClass.CalendarManager.MONTH, diff.Months);
            }

            if (hasDay > 0 && hasDate == 0)
            {
                SetWeekday(calendar, diff);
            }

            if (hasOrdMonth > 0)
            {
                SetOrdMonth(calendar, diff);
            }
            try
            {
                return calendar.dateTime;
            }
            catch (Exception)
            {
                throw new FormatException();
            }
        failed:
            throw new FormatException();
        }
예제 #6
0
        private void SetOrdMonth(TclDateTime calendar, ClockRelTimespan diff)
        // time difference to evaluate
        {
            int month = diff.Months;
            int ordMonth = diff.OrdMonth;

            //			calendar.add(SupportClass.CalendarManager.MONTH, 1); /* we want to get the next month... */
            //			while (SupportClass.CalendarManager.manager.Get(calendar, SupportClass.CalendarManager.MONTH) != month)
            //			{
            //				calendar.add(SupportClass.CalendarManager.MONTH, 1);
            //			}
            //			if (ordMonth > 1)
            //			{
            //				calendar.add(SupportClass.CalendarManager.YEAR, ordMonth - 1);
            //			}
            calendar.day = 1;
            calendar.hour = 0;
            calendar.minute = 0;
            calendar.second = 0;
        }
예제 #7
0
        private void SetWeekday(TclDateTime calendar, ClockRelTimespan diff)
        // time difference to evaluate
        {
            int weekday = diff.getWeekday();
            int dayOrdinal = diff.DayOrdinal;

            // ATK
            //			while (SupportClass.CalendarManager.manager.Get(calendar, SupportClass.CalendarManager.DAY_OF_WEEK) != weekday)
            //			{
            //				
            //				calendar.add(SupportClass.CalendarManager.DATE, 1);
            //			}
            //			if (dayOrdinal > 1)
            //			{
            //				
            //				calendar.add(SupportClass.CalendarManager.DATE, 7 * (dayOrdinal - 1));
            //			}
        }