Пример #1
0
        /// <summary>
        /// Computes the next lowest date in milliseconds based on a specification and the
        /// from-time passed in.
        /// </summary>
        /// <param name="spec">defines the schedule</param>
        /// <param name="afterTimeInMillis">defines the start time</param>
        /// <param name="timeZone">The time zone.</param>
        /// <param name="timeAbacus">The time abacus.</param>
        /// <returns>
        /// a long date tick value for the next schedule occurance matching the spec
        /// </returns>

        public static long ComputeNextOccurance(
            ScheduleSpec spec,
            long afterTimeInMillis,
            TimeZoneInfo timeZone,
            TimeAbacus timeAbacus)
        {
            if (ExecutionPathDebugLog.IsEnabled && Log.IsDebugEnabled)
            {
                Log.Debug(
                    ".computeNextOccurance Computing next occurance," +
                    "  afterTimeInTicks=" + afterTimeInMillis.TimeFromMillis(timeZone) +
                    "  as long=" + afterTimeInMillis +
                    "  spec=" + spec);
            }

            // Add the minimum resolution to the Start time to ensure we don't get the same exact time
            if (spec.UnitValues.ContainsKey(ScheduleUnit.SECONDS))
            {
                afterTimeInMillis += timeAbacus.GetOneSecond();
            }
            else
            {
                afterTimeInMillis += 60 * timeAbacus.GetOneSecond();
            }

            return(Compute(spec, afterTimeInMillis, timeZone, timeAbacus));
        }
Пример #2
0
 /// <summary>
 /// Computes the next lowest date in milliseconds based on a specification and the
 /// from-time passed in and returns the delta from the current time.
 /// </summary>
 /// <param name="spec">The schedule.</param>
 /// <param name="afterTimeInMillis">defines the start time.</param>
 /// <param name="timeZone">The time zone.</param>
 /// <param name="timeAbacus">The time abacus.</param>
 /// <returns>
 /// a long millisecond value representing the delta between current time and the next schedule occurance matching the spec
 /// </returns>
 public static long ComputeDeltaNextOccurance(
     ScheduleSpec spec,
     long afterTimeInMillis,
     TimeZoneInfo timeZone,
     TimeAbacus timeAbacus)
 {
     return(ComputeNextOccurance(spec, afterTimeInMillis, timeZone, timeAbacus) - afterTimeInMillis);
 }
Пример #3
0
        public void CheckCorrect(ScheduleSpec spec, String now, String expected)
        {
            var provider     = Thread.CurrentThread.CurrentCulture;
            var nowDate      = DateTimeOffset.ParseExact(now, "yyyy-MM-d H:mm:ss", provider);
            var expectedDate = DateTimeOffset.ParseExact(expected, "yyyy-MM-d H:mm:ss", provider);

            var result     = ScheduleComputeHelper.ComputeNextOccurance(spec, nowDate.TimeInMillis(), TimeZoneInfo.Local);
            var resultDate = result.TimeFromMillis(expectedDate.Offset);

            if (resultDate != expectedDate)
            {
                Log.Debug(".checkCorrect Difference in result found, spec=" + spec);
                Log.Debug(".checkCorrect      now=" + nowDate.ToString(TimeFormat) + " long=" + nowDate.TimeInMillis());
                Log.Debug(".checkCorrect expected=" + expectedDate.ToString(TimeFormat) + " long=" + expectedDate.TimeInMillis());
                Log.Debug(".checkCorrect   result=" + resultDate.ToString(TimeFormat) + " long=" + resultDate.TimeInMillis());
                Assert.Fail();
            }
        }
Пример #4
0
        public void CheckCorrectWZone(ScheduleSpec spec, String nowWZone, String expectedWZone)
        {
            var nowDate      = DateTimeParser.ParseDefaultMSecWZone(nowWZone);
            var nowDateJava  = DateTimeOffsetHelper.MillisToJavaMillis(nowDate);
            var expectedDate = DateTimeParser.ParseDefaultMSecWZone(expectedWZone);

            var result = ScheduleComputeHelper.ComputeNextOccurance(spec, nowDate, TimeZoneInfo.Local);

            var resultDate = result.TimeFromMillis(null);

            if (result != expectedDate)
            {
                Log.Debug(".checkCorrect Difference in result found, spec=" + spec);
                Log.Debug(".checkCorrect      now=" + nowDate.ToString(TimeFormat) + " long=" + nowDate);
                Log.Debug(".checkCorrect expected=" + expectedDate.ToString(TimeFormat) + " long=" + expectedDate);
                Log.Debug(".checkCorrect   result=" + resultDate.ToString(TimeFormat) + " long=" + resultDate);
                Assert.Fail();
            }
        }
Пример #5
0
        public void TestCompress()
        {
            IDictionary <ScheduleUnit, ICollection <int> > unitValues = new Dictionary <ScheduleUnit, ICollection <int> >();

            unitValues = (new ScheduleSpec()).UnitValues;

            // Populate Month with all valid values
            var monthValues = new SortedSet <int>();

            for (int i = ScheduleUnit.MONTHS.Min(); i <= ScheduleUnit.MONTHS.Max(); i++)
            {
                monthValues.Add(i);
            }
            unitValues.Put(ScheduleUnit.MONTHS, monthValues);

            // Construct spec, test that month was replaced with wildcards
            ScheduleSpec spec = new ScheduleSpec(unitValues, null, null, null);

            Assert.IsTrue(spec.UnitValues.Get(ScheduleUnit.MONTHS) == null);
        }
Пример #6
0
        public void CheckCorrectWZone(ScheduleSpec spec, String nowWZone, String expectedWZone)
        {
            var nowDateEx = DateTimeParser.ParseDefaultExWZone(nowWZone);
            var nowDate   = nowDateEx.TimeInMillis;
            //var nowDateJava = DateTimeOffsetHelper.MillisToJavaMillis(nowDate);

            var expectedDateEx = DateTimeParser.ParseDefaultExWZone(expectedWZone);
            var expectedDate   = expectedDateEx.TimeInMillis;

            var result   = ScheduleComputeHelper.ComputeNextOccurance(spec, nowDate, nowDateEx.TimeZone, TimeAbacusMilliseconds.INSTANCE);
            var resultEx = DateTimeEx.GetInstance(expectedDateEx.TimeZone, result);

            var resultDate = result.TimeFromMillis(null);

            if (result != expectedDate)
            {
                Log.Debug(".checkCorrect Difference in result found, spec=" + spec);
                Log.Debug(".checkCorrect      now=" + nowDate.ToString(TimeFormat) + " long=" + nowDate);
                Log.Debug(".checkCorrect expected=" + expectedDate.ToString(TimeFormat) + " long=" + expectedDate);
                Log.Debug(".checkCorrect   result=" + resultDate.ToString(TimeFormat) + " long=" + resultDate);
                Assert.Fail();
            }
        }
Пример #7
0
        public void TestCompute()
        {
            ScheduleSpec spec = null;

            // Try next "5 minutes past the hour"
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.MINUTES, 5);

            CheckCorrect(spec, "2004-12-9 15:45:01", "2004-12-9 16:05:00");
            CheckCorrect(spec, "2004-12-9 16:04:59", "2004-12-9 16:05:00");
            CheckCorrect(spec, "2004-12-9 16:05:00", "2004-12-9 17:05:00");
            CheckCorrect(spec, "2004-12-9 16:05:01", "2004-12-9 17:05:00");
            CheckCorrect(spec, "2004-12-9 16:05:01", "2004-12-9 17:05:00");
            CheckCorrect(spec, "2004-12-9 23:58:01", "2004-12-10 00:05:00");

            // Try next "5, 10 and 15 minutes past the hour"
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.MINUTES, 5);
            spec.AddValue(ScheduleUnit.MINUTES, 10);
            spec.AddValue(ScheduleUnit.MINUTES, 15);

            CheckCorrect(spec, "2004-12-9 15:45:01", "2004-12-9 16:05:00");
            CheckCorrect(spec, "2004-12-9 16:04:59", "2004-12-9 16:05:00");
            CheckCorrect(spec, "2004-12-9 16:05:00", "2004-12-9 16:10:00");
            CheckCorrect(spec, "2004-12-9 16:10:00", "2004-12-9 16:15:00");
            CheckCorrect(spec, "2004-12-9 16:14:59", "2004-12-9 16:15:00");
            CheckCorrect(spec, "2004-12-9 16:15:00", "2004-12-9 17:05:00");

            // Try next "0 and 30 and 59 minutes past the hour"
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.MINUTES, 0);
            spec.AddValue(ScheduleUnit.MINUTES, 30);
            spec.AddValue(ScheduleUnit.MINUTES, 59);

            CheckCorrect(spec, "2004-12-9 15:45:01", "2004-12-9 15:59:00");
            CheckCorrect(spec, "2004-12-9 15:59:01", "2004-12-9 16:00:00");
            CheckCorrect(spec, "2004-12-9 16:04:59", "2004-12-9 16:30:00");
            CheckCorrect(spec, "2004-12-9 16:30:00", "2004-12-9 16:59:00");
            CheckCorrect(spec, "2004-12-9 16:59:30", "2004-12-9 17:00:00");

            // Try minutes combined with seconds
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.MINUTES, 0);
            spec.AddValue(ScheduleUnit.MINUTES, 30);
            spec.AddValue(ScheduleUnit.SECONDS, 0);
            spec.AddValue(ScheduleUnit.SECONDS, 30);

            CheckCorrect(spec, "2004-12-9 15:59:59", "2004-12-9 16:00:00");
            CheckCorrect(spec, "2004-12-9 16:00:00", "2004-12-9 16:00:30");
            CheckCorrect(spec, "2004-12-9 16:00:29", "2004-12-9 16:00:30");
            CheckCorrect(spec, "2004-12-9 16:00:30", "2004-12-9 16:30:00");
            CheckCorrect(spec, "2004-12-9 16:29:59", "2004-12-9 16:30:00");
            CheckCorrect(spec, "2004-12-9 16:30:00", "2004-12-9 16:30:30");
            CheckCorrect(spec, "2004-12-9 17:00:00", "2004-12-9 17:00:30");

            // Try hours combined with seconds
            spec = new ScheduleSpec();
            for (var i = 10; i <= 14; i++)
            {
                spec.AddValue(ScheduleUnit.HOURS, i);
            }
            spec.AddValue(ScheduleUnit.SECONDS, 15);

            CheckCorrect(spec, "2004-12-9 15:59:59", "2004-12-10 10:00:15");
            CheckCorrect(spec, "2004-12-10 10:00:15", "2004-12-10 10:01:15");
            CheckCorrect(spec, "2004-12-10 10:01:15", "2004-12-10 10:02:15");
            CheckCorrect(spec, "2004-12-10 14:01:15", "2004-12-10 14:02:15");
            CheckCorrect(spec, "2004-12-10 14:59:15", "2004-12-11 10:00:15");

            // Try hours combined with minutes
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.HOURS, 9);
            spec.AddValue(ScheduleUnit.MINUTES, 5);

            CheckCorrect(spec, "2004-12-9 15:59:59", "2004-12-10 9:05:00");
            CheckCorrect(spec, "2004-11-30 15:59:59", "2004-12-1 9:05:00");
            CheckCorrect(spec, "2004-11-30 9:04:59", "2004-11-30 9:05:00");
            CheckCorrect(spec, "2004-12-31 9:05:01", "2005-01-01 9:05:00");

            // Try day of month as the 31st
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.DAYS_OF_MONTH, 31);

            CheckCorrect(spec, "2004-11-30 15:59:59", "2004-12-31 0:00:00");
            CheckCorrect(spec, "2004-12-30 15:59:59", "2004-12-31 0:00:00");
            CheckCorrect(spec, "2004-12-31 00:00:00", "2004-12-31 0:01:00");
            CheckCorrect(spec, "2005-01-01 00:00:00", "2005-01-31 0:00:00");
            CheckCorrect(spec, "2005-02-01 00:00:00", "2005-03-31 0:00:00");
            CheckCorrect(spec, "2005-04-01 00:00:00", "2005-05-31 0:00:00");

            // Try day of month as the 29st, for february testing
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.DAYS_OF_MONTH, 29);

            CheckCorrect(spec, "2004-11-30 15:59:59", "2004-12-29 0:00:00");
            CheckCorrect(spec, "2004-12-29 00:00:00", "2004-12-29 0:01:00");
            CheckCorrect(spec, "2004-12-29 00:01:00", "2004-12-29 0:02:00");
            CheckCorrect(spec, "2004-02-28 15:59:59", "2004-02-29 0:00:00");
            CheckCorrect(spec, "2003-02-28 15:59:59", "2003-03-29 0:00:00");
            CheckCorrect(spec, "2005-02-27 15:59:59", "2005-03-29 0:00:00");

            // Try 4:00 every day
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.HOURS, 16);
            spec.AddValue(ScheduleUnit.MINUTES, 0);

            CheckCorrect(spec, "2004-10-01 15:59:59", "2004-10-01 16:00:00");
            CheckCorrect(spec, "2004-10-01 00:00:00", "2004-10-01 16:00:00");
            CheckCorrect(spec, "2004-09-30 16:00:00", "2004-10-01 16:00:00");
            CheckCorrect(spec, "2004-12-30 16:00:00", "2004-12-31 16:00:00");
            CheckCorrect(spec, "2004-12-31 16:00:00", "2005-01-01 16:00:00");

            // Try every weekday at 10 am - scrum time!
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.HOURS, 10);
            spec.AddValue(ScheduleUnit.MINUTES, 0);
            for (var i = 1; i <= 5; i++)
            {
                spec.AddValue(ScheduleUnit.DAYS_OF_WEEK, i);
            }

            CheckCorrect(spec, "2004-12-05 09:50:59", "2004-12-06 10:00:00");
            CheckCorrect(spec, "2004-12-06 09:59:59", "2004-12-06 10:00:00");
            CheckCorrect(spec, "2004-12-07 09:50:00", "2004-12-07 10:00:00");
            CheckCorrect(spec, "2004-12-08 09:00:00", "2004-12-08 10:00:00");
            CheckCorrect(spec, "2004-12-09 08:00:00", "2004-12-09 10:00:00");
            CheckCorrect(spec, "2004-12-10 09:50:50", "2004-12-10 10:00:00");
            CheckCorrect(spec, "2004-12-11 00:00:00", "2004-12-13 10:00:00");
            CheckCorrect(spec, "2004-12-12 09:00:50", "2004-12-13 10:00:00");
            CheckCorrect(spec, "2004-12-13 09:50:50", "2004-12-13 10:00:00");
            CheckCorrect(spec, "2004-12-13 10:00:00", "2004-12-14 10:00:00");
            CheckCorrect(spec, "2004-12-13 10:00:01", "2004-12-14 10:00:00");

            // Every Monday and also on the 1st and 15th of each month, at midnight
            // (tests the or between DAYS_OF_MONTH and DAYS_OF_WEEK)
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.DAYS_OF_MONTH, 1);
            spec.AddValue(ScheduleUnit.DAYS_OF_MONTH, 15);
            spec.AddValue(ScheduleUnit.HOURS, 0);
            spec.AddValue(ScheduleUnit.MINUTES, 0);
            spec.AddValue(ScheduleUnit.SECONDS, 0);
            spec.AddValue(ScheduleUnit.DAYS_OF_WEEK, 1);

            CheckCorrect(spec, "2004-12-05 09:50:59", "2004-12-06 00:00:00");
            CheckCorrect(spec, "2004-12-06 00:00:00", "2004-12-13 00:00:00");
            //CheckCorrect(spec, "2004-12-07 00:80:00", "2004-12-13 00:00:00");
            CheckCorrect(spec, "2004-12-12 23:00:00", "2004-12-13 00:00:00");
            CheckCorrect(spec, "2004-12-13 23:00:00", "2004-12-15 00:00:00");
            CheckCorrect(spec, "2004-12-14 23:00:00", "2004-12-15 00:00:00");
            CheckCorrect(spec, "2004-12-15 23:00:00", "2004-12-20 00:00:00");
            CheckCorrect(spec, "2004-12-18 23:00:00", "2004-12-20 00:00:00");
            CheckCorrect(spec, "2004-12-20 00:01:00", "2004-12-27 00:00:00");
            CheckCorrect(spec, "2004-12-27 00:01:00", "2005-01-01 00:00:00");
            CheckCorrect(spec, "2005-01-01 00:01:00", "2005-01-03 00:00:00");
            CheckCorrect(spec, "2005-01-03 00:01:00", "2005-01-10 00:00:00");
            CheckCorrect(spec, "2005-01-10 00:01:00", "2005-01-15 00:00:00");
            CheckCorrect(spec, "2005-01-15 00:01:00", "2005-01-17 00:00:00");
            CheckCorrect(spec, "2005-01-17 00:01:00", "2005-01-24 00:00:00");
            CheckCorrect(spec, "2005-01-24 00:01:00", "2005-01-31 00:00:00");
            CheckCorrect(spec, "2005-01-31 00:01:00", "2005-02-01 00:00:00");

            // Every second month on every second weekday
            spec = new ScheduleSpec();
            for (var i = 1; i <= 12; i += 2)
            {
                spec.AddValue(ScheduleUnit.MONTHS, i);
            }
            for (var i = 0; i <= 6; i += 2) // Adds Sunday, Tuesday, Thursday, Saturday
            {
                spec.AddValue(ScheduleUnit.DAYS_OF_WEEK, i);
            }

            CheckCorrect(spec, "2004-09-01 00:00:00", "2004-09-02 00:00:00");   // Sept 1 2004 is a Wednesday
            CheckCorrect(spec, "2004-09-02 00:00:00", "2004-09-02 00:01:00");
            CheckCorrect(spec, "2004-09-02 23:59:00", "2004-09-04 00:00:00");
            CheckCorrect(spec, "2004-09-04 23:59:00", "2004-09-05 00:00:00");   // Sept 5 2004 is a Sunday
            CheckCorrect(spec, "2004-09-05 23:57:00", "2004-09-05 23:58:00");
            CheckCorrect(spec, "2004-09-05 23:58:00", "2004-09-05 23:59:00");
            CheckCorrect(spec, "2004-09-05 23:59:00", "2004-09-07 00:00:00");
            CheckCorrect(spec, "2004-09-30 23:58:00", "2004-09-30 23:59:00");   // Sept 30 in a Thursday
            CheckCorrect(spec, "2004-09-30 23:59:00", "2004-11-02 00:00:00");

            // Every second month on every second weekday
            spec = new ScheduleSpec();
            for (var i = 1; i <= 12; i += 2)
            {
                spec.AddValue(ScheduleUnit.MONTHS, i);
            }
            for (var i = 0; i <= 6; i += 2) // Adds Sunday, Tuesday, Thursday, Saturday
            {
                spec.AddValue(ScheduleUnit.DAYS_OF_WEEK, i);
            }

            CheckCorrect(spec, "2004-09-01 00:00:00", "2004-09-02 00:00:00");   // Sept 1 2004 is a Wednesday
            CheckCorrect(spec, "2004-09-02 00:00:00", "2004-09-02 00:01:00");
            CheckCorrect(spec, "2004-09-02 23:59:00", "2004-09-04 00:00:00");
            CheckCorrect(spec, "2004-09-04 23:59:00", "2004-09-05 00:00:00");   // Sept 5 2004 is a Sunday
            CheckCorrect(spec, "2004-09-05 23:57:00", "2004-09-05 23:58:00");
            CheckCorrect(spec, "2004-09-05 23:58:00", "2004-09-05 23:59:00");
            CheckCorrect(spec, "2004-09-05 23:59:00", "2004-09-07 00:00:00");

            // Every 5 seconds, between 9am and until 4pm, all weekdays except Saturday and Sunday
            spec = new ScheduleSpec();
            for (var i = 0; i <= 59; i += 5)
            {
                spec.AddValue(ScheduleUnit.SECONDS, i);
            }
            for (var i = 1; i <= 5; i++)
            {
                spec.AddValue(ScheduleUnit.DAYS_OF_WEEK, i);
            }
            for (var i = 9; i <= 15; i++)
            {
                spec.AddValue(ScheduleUnit.HOURS, i);
            }

            CheckCorrect(spec, "2004-12-12 20:00:00", "2004-12-13 09:00:00");  // Dec 12 2004 is a Sunday
            CheckCorrect(spec, "2004-12-13 09:00:01", "2004-12-13 09:00:05");
            CheckCorrect(spec, "2004-12-13 09:00:05", "2004-12-13 09:00:10");
            CheckCorrect(spec, "2004-12-13 09:00:11", "2004-12-13 09:00:15");
            CheckCorrect(spec, "2004-12-13 09:00:15", "2004-12-13 09:00:20");
            CheckCorrect(spec, "2004-12-13 09:00:24", "2004-12-13 09:00:25");
            CheckCorrect(spec, "2004-12-13 15:59:50", "2004-12-13 15:59:55");
            CheckCorrect(spec, "2004-12-13 15:59:55", "2004-12-14 09:00:00");
            CheckCorrect(spec, "2004-12-14 12:27:35", "2004-12-14 12:27:40");
            CheckCorrect(spec, "2004-12-14 12:29:55", "2004-12-14 12:30:00");
            CheckCorrect(spec, "2004-12-17 00:03:00", "2004-12-17 09:00:00");
            CheckCorrect(spec, "2004-12-17 15:59:50", "2004-12-17 15:59:55");
            CheckCorrect(spec, "2004-12-17 15:59:55", "2004-12-20 09:00:00");

            // Feb 14, 12pm
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.MONTHS, 2);
            spec.AddValue(ScheduleUnit.DAYS_OF_MONTH, 14);
            spec.AddValue(ScheduleUnit.HOURS, 12);
            spec.AddValue(ScheduleUnit.MINUTES, 0);

            CheckCorrect(spec, "2004-12-12 20:00:00", "2005-02-14 12:00:00");
            CheckCorrect(spec, "2003-12-12 20:00:00", "2004-02-14 12:00:00");
            CheckCorrect(spec, "2004-02-01 20:00:00", "2004-02-14 12:00:00");

            // Dec 31, 23pm and 50 seconds (countdown)
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.MONTHS, 12);
            spec.AddValue(ScheduleUnit.DAYS_OF_MONTH, 31);
            spec.AddValue(ScheduleUnit.HOURS, 23);
            spec.AddValue(ScheduleUnit.MINUTES, 59);
            spec.AddValue(ScheduleUnit.SECONDS, 50);

            CheckCorrect(spec, "2004-12-12 20:00:00", "2004-12-31 23:59:50");
            CheckCorrect(spec, "2004-12-31 23:59:55", "2005-12-31 23:59:50");

            // CST timezone 7:00:00am
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.HOURS, 7);
            spec.AddValue(ScheduleUnit.MINUTES, 0);
            spec.AddValue(ScheduleUnit.SECONDS, 0);
            spec.OptionalTimeZone = "Central Standard Time";

            CheckCorrectWZone(spec, "2008-02-01 06:00:00.000GMT-10:00", "2008-02-02 03:00:00.000GMT-10:00");
            CheckCorrectWZone(spec, "2008-02-01 06:00:00.000GMT-9:00", "2008-02-02 04:00:00.000GMT-9:00");
            CheckCorrectWZone(spec, "2008-02-01 06:00:00.000GMT-8:00", "2008-02-02 05:00:00.000GMT-8:00");
            CheckCorrectWZone(spec, "2008-02-01 06:00:00.000GMT-7:00", "2008-02-02 06:00:00.000GMT-7:00");
            CheckCorrectWZone(spec, "2008-02-01 06:00:00.000GMT-6:00", "2008-02-01 07:00:00.000GMT-6:00");
            CheckCorrectWZone(spec, "2008-02-01 06:00:00.000GMT-5:00", "2008-02-01 08:00:00.000GMT-5:00");
            CheckCorrectWZone(spec, "2008-02-01 06:00:00.000GMT-4:00", "2008-02-01 09:00:00.000GMT-4:00");

            // EST timezone 7am, any minute
            spec = new ScheduleSpec();
            spec.AddValue(ScheduleUnit.HOURS, 7);
            spec.AddValue(ScheduleUnit.SECONDS, 0);
            spec.OptionalTimeZone = "Eastern Standard Time";

            CheckCorrectWZone(spec, "2008-02-01 06:00:00.000GMT-7:00", "2008-02-02 05:00:00.000GMT-7:00");
            CheckCorrectWZone(spec, "2008-02-01 06:00:00.000GMT-6:00", "2008-02-01 06:01:00.000GMT-6:00");
            CheckCorrectWZone(spec, "2008-02-01 06:00:00.000GMT-5:00", "2008-02-01 07:00:00.000GMT-5:00");
            CheckCorrectWZone(spec, "2008-02-01 06:00:00.000GMT-4:00", "2008-02-01 08:00:00.000GMT-4:00");
        }
Пример #8
0
        private static long Compute(
            ScheduleSpec spec,
            long afterTimeInMillis,
            TimeZoneInfo timeZone,
            TimeAbacus timeAbacus)
        {
            long remainderMicros = -1;

            while (true)
            {
                DateTimeEx after;

                if (spec.OptionalTimeZone != null)
                {
                    try
                    {
                        timeZone = TimeZoneHelper.GetTimeZoneInfo(spec.OptionalTimeZone);
                        after    = DateTimeEx.GetInstance(timeZone);
                    }
                    catch (TimeZoneNotFoundException)
                    {
                        // this behavior ensures we are consistent with Java, but IMO, it's bad behavior...
                        // basically, if the timezone is not found, we default to UTC.
                        timeZone = TimeZoneInfo.Utc;
                        after    = DateTimeEx.GetInstance(timeZone);
                    }
                }
                else
                {
                    after = DateTimeEx.GetInstance(timeZone);
                }

                var remainder = timeAbacus.CalendarSet(afterTimeInMillis, after);
                if (remainderMicros == -1)
                {
                    remainderMicros = remainder;
                }

                var result = new ScheduleCalendar {
                    Milliseconds = after.Millisecond
                };

                ICollection <int> minutesSet = spec.UnitValues.Get(ScheduleUnit.MINUTES);
                ICollection <int> hoursSet   = spec.UnitValues.Get(ScheduleUnit.HOURS);
                ICollection <int> monthsSet  = spec.UnitValues.Get(ScheduleUnit.MONTHS);
                ICollection <int> secondsSet = null;

                bool isSecondsSpecified = false;

                if (spec.UnitValues.ContainsKey(ScheduleUnit.SECONDS))
                {
                    isSecondsSpecified = true;
                    secondsSet         = spec.UnitValues.Get(ScheduleUnit.SECONDS);
                }

                if (isSecondsSpecified)
                {
                    result.Second = NextValue(secondsSet, after.Second);
                    if (result.Second == -1)
                    {
                        result.Second = NextValue(secondsSet, 0);
                        after.AddMinutes(1);
                    }
                }

                result.Minute = NextValue(minutesSet, after.Minute);
                if (result.Minute != after.Minute)
                {
                    result.Second = NextValue(secondsSet, 0);
                }
                if (result.Minute == -1)
                {
                    result.Minute = NextValue(minutesSet, 0);
                    after.AddHours(1);
                }

                result.Hour = NextValue(hoursSet, after.Hour);
                if (result.Hour != after.Hour)
                {
                    result.Second = NextValue(secondsSet, 0);
                    result.Minute = NextValue(minutesSet, 0);
                }
                if (result.Hour == -1)
                {
                    result.Hour = NextValue(hoursSet, 0);
                    after.AddDays(1, DateTimeMathStyle.Java);
                }

                // This call may change second, minute and/or hour parameters
                // They may be reset to minimum values if the day rolled
                result.DayOfMonth = DetermineDayOfMonth(spec, after, result);

                bool dayMatchRealDate = false;
                while (!dayMatchRealDate)
                {
                    if (CheckDayValidInMonth(timeZone, result.DayOfMonth, after.Month, after.Year))
                    {
                        dayMatchRealDate = true;
                    }
                    else
                    {
                        after.AddMonths(1, DateTimeMathStyle.Java);
                    }
                }

                int currentMonth = after.Month;
                result.Month = NextValue(monthsSet, currentMonth);
                if (result.Month != currentMonth)
                {
                    result.Second     = NextValue(secondsSet, 0);
                    result.Minute     = NextValue(minutesSet, 0);
                    result.Hour       = NextValue(hoursSet, 0);
                    result.DayOfMonth = DetermineDayOfMonth(spec, after, result);
                }
                if (result.Month == -1)
                {
                    result.Month = NextValue(monthsSet, 0);
                    after.AddYears(1);
                }

                // Perform a last valid date check, if failing, try to compute a new date based on this altered after date
                int year = after.Year;
                if (!CheckDayValidInMonth(timeZone, result.DayOfMonth, result.Month, year))
                {
                    afterTimeInMillis = timeAbacus.CalendarGet(after, remainder);
                    continue;
                }

                return(GetTime(result, after.Year, spec.OptionalTimeZone, timeZone, timeAbacus, remainder));
            }
        }
Пример #9
0
        /// <summary>
        /// Determine the next valid day of month based on the given specification of valid days in month and
        /// valid days in week. If both days in week and days in month are supplied, the days are OR-ed.
        /// </summary>
        /// <param name="spec"></param>
        /// <param name="after"></param>
        /// <param name="result"></param>
        /// <returns></returns>

        private static int DetermineDayOfMonth(ScheduleSpec spec, DateTimeEx after, ScheduleCalendar result)
        {
            ICollection <Int32> daysOfMonthSet = spec.UnitValues.Get(ScheduleUnit.DAYS_OF_MONTH);
            ICollection <Int32> daysOfWeekSet  = spec.UnitValues.Get(ScheduleUnit.DAYS_OF_WEEK);
            ICollection <Int32> secondsSet     = spec.UnitValues.Get(ScheduleUnit.SECONDS);
            ICollection <Int32> minutesSet     = spec.UnitValues.Get(ScheduleUnit.MINUTES);
            ICollection <Int32> hoursSet       = spec.UnitValues.Get(ScheduleUnit.HOURS);

            int dayOfMonth;

            // If days of week is a wildcard, just go by days of month
            if (spec.OptionalDayOfMonthOperator != null || spec.OptionalDayOfWeekOperator != null)
            {
                var isWeek = false;
                var op     = spec.OptionalDayOfMonthOperator;
                if (spec.OptionalDayOfMonthOperator == null)
                {
                    op     = spec.OptionalDayOfWeekOperator;
                    isWeek = true;
                }

                // may return the current day or a future day in the same month,
                // and may advance the "after" date to the next month
                int currentYYMMDD = GetTimeYYYYMMDD(after);
                IncreaseAfterDayOfMonthSpecialOp(op.Operator, op.Day, op.Month, isWeek, after);
                int rolledYYMMDD = GetTimeYYYYMMDD(after);

                // if rolled then reset time portion
                if (rolledYYMMDD > currentYYMMDD)
                {
                    result.Second = (NextValue(secondsSet, 0));
                    result.Minute = (NextValue(minutesSet, 0));
                    result.Hour   = (NextValue(hoursSet, 0));
                    return(after.GetFieldValue(DateTimeFieldEnum.DAY_OF_MONTH));
                }
                // rolling backwards is not allowed
                else if (rolledYYMMDD < currentYYMMDD)
                {
                    throw new IllegalStateException("Failed to evaluate special date op, rolled date less then current date");
                }
                else
                {
                    var work = new DateTimeEx(after);
                    work.SetFieldValue(DateTimeFieldEnum.SECOND, result.Second);
                    work.SetFieldValue(DateTimeFieldEnum.MINUTE, result.Minute);
                    work.SetFieldValue(DateTimeFieldEnum.HOUR_OF_DAY, result.Hour);
                    if (work <= after)
                    {    // new date is not after current date, so bump
                        after.AddUsingField(DateTimeFieldEnum.DAY_OF_MONTH, 1);
                        result.Second = NextValue(secondsSet, 0);
                        result.Minute = NextValue(minutesSet, 0);
                        result.Hour   = NextValue(hoursSet, 0);
                        IncreaseAfterDayOfMonthSpecialOp(op.Operator, op.Day, op.Month, isWeek, after);
                    }
                    return(after.GetFieldValue(DateTimeFieldEnum.DAY_OF_MONTH));
                }
            }
            else if (daysOfWeekSet == null)
            {
                dayOfMonth = NextValue(daysOfMonthSet, after.Day);
                if (dayOfMonth != after.Day)
                {
                    result.Second = NextValue(secondsSet, 0);
                    result.Minute = NextValue(minutesSet, 0);
                    result.Hour   = NextValue(hoursSet, 0);
                }
                if (dayOfMonth == -1)
                {
                    dayOfMonth = NextValue(daysOfMonthSet, 0);
                    after.AddMonths(1, DateTimeMathStyle.Java);
                }
            }
            // If days of weeks is not a wildcard and days of month is a wildcard, go by days of week only
            else if (daysOfMonthSet == null)
            {
                // Loop to find the next day of month that works for the specified day of week values
                while (true)
                {
                    dayOfMonth = after.Day;
                    int dayOfWeek = (int)after.DayOfWeek;

                    // TODO
                    //
                    // Check the DayOfWeek logic in this section.  The former code reads something
                    // like the following:
                    //
                    // Calendar.Get(after, SupportClass.CalendarManager.DAY_OF_WEEK) - 1;
                    //
                    // Java calendars are one based which means that subtracting one makes them
                    // zero-based.  CLR DateTimes are zero-based so there should be no need to
                    // tweak the dates to make this work.

                    // If the day matches neither the day of month nor the day of week
                    if (!daysOfWeekSet.Contains(dayOfWeek))
                    {
                        result.Second = NextValue(secondsSet, 0);
                        result.Minute = NextValue(minutesSet, 0);
                        result.Hour   = NextValue(hoursSet, 0);
                        after.AddDays(1, DateTimeMathStyle.Java);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            // Both days of weeks and days of month are not a wildcard
            else
            {
                // Loop to find the next day of month that works for either day of month  OR   day of week
                while (true)
                {
                    dayOfMonth = after.Day;
                    int dayOfWeek = (int)after.DayOfWeek;

                    // TODO
                    //
                    // See my discussion above about day of week conversion

                    // If the day matches neither the day of month nor the day of week
                    if ((!daysOfWeekSet.Contains(dayOfWeek)) && (!daysOfMonthSet.Contains(dayOfMonth)))
                    {
                        result.Second = NextValue(secondsSet, 0);
                        result.Minute = NextValue(minutesSet, 0);
                        result.Hour   = NextValue(hoursSet, 0);
                        after.AddDays(1, DateTimeMathStyle.Java);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return(dayOfMonth);
        }
Пример #10
0
        public void TestWaitAndSpecTogether()
        {
            var startDate = new DateTime(2004, 12, 9, 15, 27, 10, 500, DateTimeKind.Local);
            var startTime = startDate.UtcMillis();

            _service.Time = startTime;

            // Add a specification
            var spec = new ScheduleSpec();

            spec.AddValue(ScheduleUnit.MONTHS, 12);
            spec.AddValue(ScheduleUnit.DAYS_OF_MONTH, 9);
            spec.AddValue(ScheduleUnit.HOURS, 15);
            spec.AddValue(ScheduleUnit.MINUTES, 27);
            spec.AddValue(ScheduleUnit.SECONDS, 20);

            _service.Add(ScheduleComputeHelper.ComputeDeltaNextOccurance(spec, _service.Time, TimeZoneInfo.Local, TimeAbacusMilliseconds.INSTANCE), _callbacks[3], _slots[1][1]);

            spec.AddValue(ScheduleUnit.SECONDS, 15);
            _service.Add(ScheduleComputeHelper.ComputeDeltaNextOccurance(spec, _service.Time, TimeZoneInfo.Local, TimeAbacusMilliseconds.INSTANCE), _callbacks[4], _slots[2][0]);

            // Add some more callbacks
            _service.Add(5000, _callbacks[0], _slots[0][0]);
            _service.Add(10000, _callbacks[1], _slots[0][1]);
            _service.Add(15000, _callbacks[2], _slots[1][0]);

            // GetInstance send a times reflecting various seconds later and check who got a callback
            _service.Time = startTime + 1000;
            SupportScheduleCallback.SetCallbackOrderNum(0);
            EvaluateSchedule();
            CheckCallbacks(_callbacks, new[] { 0, 0, 0, 0, 0 });

            _service.Time = startTime + 2000;
            EvaluateSchedule();
            CheckCallbacks(_callbacks, new[] { 0, 0, 0, 0, 0 });

            _service.Time = startTime + 4000;
            EvaluateSchedule();
            CheckCallbacks(_callbacks, new[] { 0, 0, 0, 0, 0 });

            _service.Time = startTime + 5000;
            EvaluateSchedule();
            CheckCallbacks(_callbacks, new[] { 1, 0, 0, 0, 2 });

            _service.Time = startTime + 9000;
            EvaluateSchedule();
            CheckCallbacks(_callbacks, new[] { 0, 0, 0, 0, 0 });

            _service.Time = startTime + 10000;
            EvaluateSchedule();
            CheckCallbacks(_callbacks, new[] { 0, 3, 0, 4, 0 });

            _service.Time = startTime + 11000;
            EvaluateSchedule();
            CheckCallbacks(_callbacks, new[] { 0, 0, 0, 0, 0 });

            _service.Time = startTime + 15000;
            EvaluateSchedule();
            CheckCallbacks(_callbacks, new[] { 0, 0, 5, 0, 0 });

            _service.Time = startTime + int.MaxValue;
            EvaluateSchedule();
            CheckCallbacks(_callbacks, new[] { 0, 0, 0, 0, 0 });
        }