Issue Details (XML | Word | Printable)

Key: QRTZNET-149
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Blocker Blocker
Assignee: Marko Lahma
Reporter: Hippy
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Quartz.NET

CronExpression.GetTimeAfter(DateTime afterTimeUtc) does not account for day increment over days in month

Created: 30/Jan/09 08:21 PM   Updated: 02/Feb/09 12:44 PM
Component/s: Core
Affects Version/s: 1.0
Fix Version/s: 1.0.1, 1.2

Environment: .Net 3.5

Flags: Important


 Description  « Hide
To duplicate:

 - set the date to Jan.29-31
 - create a CronTrigger and simple job that fires s short time in the future and uses the *day of the month* field in particular
    - e.g. "0 0 0 29 1 ?"
 
The following code in the method is where it breaks (how about breaking that method up a bit, too? umpteen pages long!?):

                    if (day != t || mon != tmon)
                    {
                        if (mon > 12)
                        {
                            d = new DateTime(d.Year, 12, day, 0, 0, 0).AddMonths(mon - 12);
                        }
                        else
                        {
                            // THIS WILL BREAK EVENTUALLY WHEN THE TRIGGER FIRES!!!
                            // month will be February (i.e. 2) and day will be > 28
                            d = new DateTime(d.Year, mon, day, 0, 0, 0);
                        }
                        continue;
                    }

 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Ben Simon added a comment - 02/Feb/09 01:16 AM
This bug brought down a production system late last week. Stayed in the office until 5am to track down the issue.
I added a workaround piece of code and got the system running again.
This is not an optimal solution, but should work for most if not all of the cases where this occurs.
And I concur with the observation of the original poster that this method should be cleaned up...400 lines!!

if (day != t || mon != tmon)
                    {
                        if (mon > 12)
                        {
                            d = new DateTime(d.Year, 12, day, 0, 0, 0).AddMonths(mon - 12);
                        }
                        else
                        {
                            // This is to avoid a bug when moving from a month
                            //with 30 or 31 days to a month with less. Causes an invalid datetime to be instantiated.
                            // ex. 0 29 0 30 1 ? 2009 with clock set to 1/30/2009
                            int maxDays = DateTime.DaysInMonth( d.Year, mon );
                            if( day <= maxDays )
                                d = new DateTime(d.Year, mon, day, 0, 0, 0);
                            else
                                return null;
                        }
                        continue;
                    }

Marko Lahma added a comment - 02/Feb/09 01:38 AM
Thanks for reporting this, I'll check this ASAP and try to get 1.0.1 release out very soon.

Marko Lahma added a comment - 02/Feb/09 02:21 AM
Now fixed in maintenance branch and trunk. The proposed solution wasn't complete as it couldn't handle subsequent months that are valid. Thanks for the report and pinpointing the problem.

Ben Simon added a comment - 02/Feb/09 12:44 PM
Wow. Great response time. Thanks!