I have a table that stores dates (birthdays, anniversaries etc.)
I have a dateformatter set on the table cell to show the month and day. All is well until you move to another time zone. If the date is set in EST and you move to PST then the dates all show a day early. I use strings to calculate age and dates for reminders so they are static but the NSDates move around. Perhaps this is the nature of date objects and they indeed should change with time zone.
I have tried setting the time zone of the formatter to the locale with
theFormatter,s setTimeZone_(current application's class "NSTimeZone"'s systemTimeZone())
but that only seems to do what the dateformatter does itself. It still shifts.
I am reading that you can set a default time zone for the application…
So how do you store a date event that doesn’t shift with the wind? I guess I should have stored all dates as strings but then they don’t display in the current locales language and format.
Any help appreciated. I’m a bit muddled.
NSDates don’t shift – it’s time zones that shift. It can get complicated, because sometimes you want to account for time zones, and sometimes you don’t – hence the option in iCal, for instance.
I’m not clear on what you are after, or how you’re turning your strings into dates. But I suspect that using setDefaultTimeZone_ and timeZoneForSecondsFromGMT_(0) will effectively remove the issue of time zones from the equation.
Coming from old applescript I never thought much about date objects but have been reading up on NSDate and NSCalendarDate and the rest of the family and now understand that NSDate is a point in time since 1 January, 2001, at 00:00 and indeed the formatter reads that point with the local time zone, thus my changing dates.
My application displays upcoming birthdays ( and other repeating events) in a list-like string so that is not a problem because I store in the tableView, in addition to the NSDate object, a static string of the date which reads “January 9” anywhere any time.
The table display however, adjusts itself for location. I set the table cell time zone to
and that seemed to do the trick but then people who entered their dates in Eastern Europe (east of GMT = 0)had the table showing their dates a day earlier.
I will experiment more. Perhaps setDefaultTimeZone_ will help going forward though everyone out there has a lot of events entered already. On top of that I have another table listing birthdays of famous people which I created here in EST so they are showing a day earlier in California! I can set that time zone on the table cell to EST but then users can add their own famous names etc…
Ideally time zones would not be involved at all. Will report back with my findings.
So iCal has timezone support which would be a neat option to have. I wonder if that just uses setDefaultTimeZone_ which sets the default for the whole application? It’s global in iCal and effects everything when you change the zone.
You can also enable time zone support but then set a particular date’s time zone to “floating.” I have googled around but can’t find any explanation of what that “floating” date is. I set some up in ical and retrieved the records with CalCalendarStore but the floating date appears in console exactly as the non floating date does and no other specifier for the type or zone information.
2012-02-04 07:30:00 âˆ’0800 ( for the float which stays at 7:30 regardless of zone)
2012-02-04 07:30:00 âˆ’0800 ( for theEST timezone date which changes with zone)
You can also just modify your data. Find the difference to GMT when you launch, then adjust all the dates by that amount; reverse the process when you save.
I was thinking of how I could adjust the table data on the fly and you hit the nail on the head. If my dateFormatters are set to GMT then of course why not just set the data to GMT. Slowly I am getting the idea that a point in time never changes and when created has the offset to GMT built in. I found an adjustment routine in OBJ-c and put it in a separate class. After studying OBJ-c to learn ASOC I am finding it quicker now to to think in OBJ-c! I may leave it and not translate to ASOC:
run through the input list and adjust dates:
NSDate *localDate = [[array objectAtIndex:i]valueForKey:@"tabledate"];
NSTimeInterval timeZoneOffset = [[NSTimeZone defaultTimeZone] secondsFromGMT];
if (timeZoneOffset > 0.0)
gmtTimeInterval = [localDate timeIntervalSinceReferenceDate] + timeZoneOffset;
gmtTimeInterval = [localDate timeIntervalSinceReferenceDate] - timeZoneOffset;
NSDate *gmtDate = [NSDate dateWithTimeIntervalSinceReferenceDate:gmtTimeInterval];
[[array objectAtIndex:i]setValue:gmtDate forKey:@"tabledate"];
I found that I had to adjust + or - depending on east or west of GMT and reverse that for writing out the list to storage at the end. Not sure if this is the best way but it seems to be working in my tests.
Thanks as always Shane, Rob