I have a date that's stored as a number of days since January 1, 1600 that I need to deal with. This is a legacy date format that I need to read many, many times in my application.
Previously, I'd been creating a calendar, empty date components and root date like this:
self.gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar
] autorelease];
id rootComponents = [[[NSDateComponents alloc] init] autorelease];
[rootComponents setYear: 1600];
[rootComponents setMonth: 1];
[rootComponents setDay: 1];
self.rootDate = [gregorian dateFromComponents: rootComponents];
self.offset = [[[NSDateComponents alloc] init] autorelease];
Then, to convert the integer later to a date, I use this:
[offset setDay: theLegacyDate];
id eventDate = [gregorian dateByAddingComponents: offset
toDate: rootDate
options: 0];
(I never change any values in offset anywhere else.)
The problem is I'm getting a different time for rootDate
on iOS vs. Mac OS X. On Mac OS X, I'm getting midnight. On iOS, I'm getting 8:12:28. (So far, it seems to be consistent about this.) When I add my number of days later, the weird time stays.
OS | legacyDate | rootDate | eventDate ======== | ========== | ==========================|========================== Mac OS X | 143671 | 1600-01-01 00:00:00 -0800 | 1993-05-11 00:00:00 -0700 iOS | 143671 | 1600-01-01 08:12:28 +0000 | 1993-05-11 07:12:28 +0000
In the previous release of my product, I didn't care about the time; now I do. Why the weird time on iOS, and what should I do about it? (I'm assuming the hour difference is DST.)
I've tried setting the hour, minute and second of rootComponents to 0. This has no impact. If I set them to something other than 0, it adds them to 8:12:28. I've been wondering if this has something to do with leap seconds or other cumulative clock changes.
Or is this entirely the wrong approach to use on iOS?
It looks like the right answer is to make things simpler. Instead of making a rootDate, I just build the date from components every time. This should be no slower, and is still keeps the code really close to the idea.
Initial setup:
self.gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar
] autorelease];
self.components = [[[NSDateComponents alloc] init] autorelease];
[components setYear: 1600];
[components setMonth: 1];
(Obviously, properties and ivars are adjusted.)
Later, to actually convert a legacy date to a NSDate
:
[components setDay: 1 + theLegacyDate];
id eventDate = [gregorian dateFromComponents: components];
This has these advantages for me: