diff --git a/Source/NSCalendarDate.m b/Source/NSCalendarDate.m index e9259ed83..525f91ea8 100644 --- a/Source/NSCalendarDate.m +++ b/Source/NSCalendarDate.m @@ -982,11 +982,48 @@ static inline int getDigits(const char *from, char *to, int limit) * The year includes the century (ie you can't just say '02' when you * mean '2002').
* The month is in the range 1 to 12,
- * The day is in th range 1 to 31,
+ * The day is in the range 1 to 31,
* The hour is in the range 0 to 23,
* The minute is in the range 0 to 59,
* The second is in the range 0 to 59.
* If aTimeZone is nil, the [NSTimeZone+localTimeZone] value is used. + *

+ * GNUstep checks the validity of the method arguments, and unless + * the base library was built with 'warn=no' it generates a warning + * for bad values. It tries to use those bad values to generate a + * date anyway though, rather than failing (this also appears to be + * the behavior of MacOS-X). + *

+ * The algorithm GNUstep uses to create the date is this ...
+ * + * + * Convert the broken out date values into a time interval since + * the reference date, as if those values represent a GMT date/time. + * + * + * Ask the time zone for the offset from GMT at the resulting date, + * and apply that offset to the time interval ... so get the value + * for the specified timezone. + * + * + * Ask the time zone for the offset from GMT at the new date ... + * in case the new date is in a different daylight savings time + * band from the original date. If this offset differs from the + * previous one, apply the difference so that the result is + * corrected for daylight savings. This is the final result used. + * + * + * After establishing the time interval we will use and completing + * initialisation, we ask the time zone for the offset from GMT again. + * If it is not the same as the last time, then the time specified by + * the broken out date does not really exist ... since it's in the + * period lost by the transition to daylight savings. The resulting + * date is therefore not the date that was actually asked for, but is + * the best approximation we can do. If the base library was not + * built with 'warn=no' then a warning message is logged for this + * condition. + * + * */ - (id) initWithYear: (int)year month: (unsigned int)month diff --git a/Testing/nsdate.m b/Testing/nsdate.m index f64c335e2..25eb6aa3e 100644 --- a/Testing/nsdate.m +++ b/Testing/nsdate.m @@ -216,7 +216,7 @@ if ([(NSDate*) [NSCalendarDate date] compare: c = [NSCalendarDate dateWithString: @"2002-03-31 00:30:00 GB" calendarFormat: @"%Y-%m-%d %H:%M:%S %Z"]; - printf("\nSavings time checks at %s\n", [DESCRIP_FORMAT(c) cString]); + printf("\nSavings time begins at %s\n", [DESCRIP_FORMAT(c) cString]); c = [c addYear:0 month:0 day:0 hour:1 minute:0 second:0]; printf("Add an hour - %s\n", [DESCRIP_FORMAT(c) cString]); c = [c addYear:0 month:0 day:0 hour:-1 minute:0 second:0]; @@ -238,6 +238,33 @@ if ([(NSDate*) [NSCalendarDate date] compare: c = [c addYear:0 month:0 day:0 hour:-24 minute:0 second:0]; printf("Subtract twentyfour hours - %s\n", [DESCRIP_FORMAT(c) cString]); + c = [NSCalendarDate dateWithString: @"2002-10-27 00:30:00 GB" + calendarFormat: @"%Y-%m-%d %H:%M:%S %Z"]; + printf("\nSavings time ends at %s\n", [DESCRIP_FORMAT(c) cString]); + c = [c addYear:0 month:0 day:0 hour:1 minute:0 second:0]; + printf("Add an hour - %s\n", [DESCRIP_FORMAT(c) cString]); + c = [c addYear:0 month:0 day:0 hour:-1 minute:0 second:0]; + printf("Subtract an hour - %s\n", [DESCRIP_FORMAT(c) cString]); + c = [c addYear:0 month:0 day:0 hour:2 minute:0 second:0]; + printf("Add two hours - %s\n", [DESCRIP_FORMAT(c) cString]); + c = [c addYear:0 month:0 day:0 hour:-2 minute:0 second:0]; + printf("Subtract two hours - %s\n", [DESCRIP_FORMAT(c) cString]); + c = [c addYear:0 month:0 day:0 hour:3 minute:0 second:0]; + printf("Add three hours - %s\n", [DESCRIP_FORMAT(c) cString]); + c = [c addYear:0 month:0 day:0 hour:-4 minute:0 second:0]; + printf("Subtract four hours - %s\n", [DESCRIP_FORMAT(c) cString]); + c = [c addYear:0 month:0 day:0 hour:3 minute:0 second:0]; + printf("Add three hours - %s\n", [DESCRIP_FORMAT(c) cString]); + c = [c addYear:0 month:0 day:0 hour:-4 minute:0 second:0]; + printf("Subtract four hours - %s\n", [DESCRIP_FORMAT(c) cString]); + c = [c addYear:0 month:0 day:0 hour:4 minute:0 second:0]; + printf("Add four hours - %s\n", [DESCRIP_FORMAT(c) cString]); + c = [c addYear:0 month:0 day:0 hour:-24 minute:0 second:0]; + printf("Subtract twentyfour hours - %s\n", [DESCRIP_FORMAT(c) cString]); + + c = [NSCalendarDate dateWithYear: 2002 month: 3 day: 31 hour: 1 minute: 30 second: 0 timeZone: [NSTimeZone timeZoneWithName: @"GB"]]; + printf("Build at %s\n", [[c description] cString]); + c = [NSCalendarDate dateWithString: @"2002-09-27 01:59:00" calendarFormat: @"%Y-%m-%d %H:%M:%S"]; printf("Start at %s\n", [DESCRIP_FORMAT(c) cString]);