Preservation of absolute NSDate, not relative to the time zone

I am creating an iOS application for tracking attendance. Each attendance record is stored in an object that has a status attribute (for example, present, absent) and an NSDate attribute called date , which indicates the day on which this attendance record was made. When I select a specific date (using a UIDatePickerView or similar), I want all attendance records (objects) for that date to be displayed in a table.

Although it sounds simple in principle, I ran into a problem with time zones. I know that NSDate is stored independently of time zones (i.e. they are stored relative to UTC / GMT +0000). This means that if I am in Sydney and visit, for example, Sunday, November 4, 2012, because the date is stored as independent of the time zone, if I take my iPhone / iPad to a different time zone (for example, in San Francisco) the records will move one day ago, in this case, Saturday, November 3, 2012, because it was the time when the attendance was held in San Francisco local time (which was actually the next day in Sydney local time).

I do not want this to happen - I want the date to be absolute. In other words, if the visit takes place on Sunday November 4, 2012, then it must remain on that date, no matter where in the world (and depending on what time zone) I can go. As you can see, this completely contrasts, say, with the calendar application, when it is desirable that the appointment dates change depending on the time zone.

Any suggestions on a better way to approach this issue would be appreciated. Please keep in mind that I select a date to display using a UIDatePickerView that returns the current NSDate in a time-independent format, so I also need a way to make an easy comparison (preferably in NSPredicate , since attendance objects are stored in Core Data) so that Get all attendance objects for that particular day.

+6
source share
3 answers

Have you tried converting time to NSDateComponents? you can recreate an NSDate from it regardless of time zone.

Edited to add

 // This is just so I can create a date from a string. NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss z"]; // Create a date as recorded in a timezone that isn't mine. NSDate *localDate = [formatter dateFromString:@"2012-10-30 10:30:00 +0200"]; NSLog(@"Initial Date: %@", localDate); // this logs 2012-10-30 08:30:00 +0000 // Which is what you would expect, as the original time was 2 hours ahead NSDateComponents *components = [[NSDateComponents alloc] init]; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; components = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit fromDate:localDate]; NSLog(@"Components: %@", components); // Create a date from these time components in some other time zone [gregorian setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"EST"]]; NSDate *newDate = [gregorian dateFromComponents:components]; NSLog(@"New Date: %@", newDate); // This logs 2012-10-30 12:30:00 +0000 // Which is the local EST of 8:30 am expressed in UTC 

Which demonstrates how I can turn make 8:30 in the morning into a +2 time zone, just like for a -4 time zone.

+6
source

I believe that the best way for you is to use a timestamp, since it does not depend on any time zone. You can use various methods to convert timestamps to date and back. And implement any logic you want.

You can also easily compare them.

+1
source

Save the date in yyyyMMdd format. Then it is easy to convert to and from NSDate.

0
source

All Articles