I have developed an app which works alot with dates and also stores these as strings in core data using this method:
- (NSDate*) stringToDate{
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yy-MM-dd HH:mm"];
NSDate *date = [dateFormat dateFromString:self];
return date;
}
Working with date/time is quite tricky - just alone the time difference between the system and the locale time - anyway the above method should take care of that. (So I hope, since formatting a NSDate to a NSString returns the correct local time instead of looking at the NSDate variable in debugger which shows a 2 hours difference in my case)
There are also many calculations like this:
NSCalendar *calendar = [NSCalendar currentCalendar]; <------
NSDateComponents *components = [calendar components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSYearCalendarUnit |NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:someDate];
NSInteger now_hour = [components hour];
NSInteger now_minute = [components minute];
NSInteger yearx = [components year];
NSInteger monthx = [components month];
NSInteger dayx = [components day];
where I need to set/change/create certain dates/times, do calculations and retrieve/store them in core data again as NSStrings.
My question is about using the appropriate calendar.
Should I always write:
NSCalendar *calendar = [NSCalendar currentCalendar]; ?
or
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
and
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSRepublicOfChinaCalendar];
esp. depending on whether the app is used in Europe/USA vs China?
Your method stringToDate
won't actually exactly work, see QA1480. Short version: the NSDateFormatter
unfortunately has two, slightly contradictory, roles — decoding and encoding specific text formats and converting dates for display. Because the latter is locale related, it's the default. To ensure you get the former behaviour, you should explicitly set the en_US_POSIX
locale, which is guaranteed exactly to honour your date string.
That being said, you seem to be a little confused about what an NSDate
is. It's not an NSString
or any other written representation of a date. It's an abstract record of an exact moment. It's therefore completely unrelated to the current calendar. The user's calendar and locale will affect how dates are printed, but it doesn't affect the dates themselves. Now is still now, however you write it. That's why when you apply a formatter to a date you get a correct local date, but if you just log a date to the console then you get something abstract and not necessarily in your local time zone. NSDate
has no concept of time zones or of different calendars.
Core Data can store dates directly (ie, there's no need whatsoever for you to convert to an from strings manually any more than there is for numeric values) so I'm not entirely sure what you're getting at. But normal behaviour is to use currentCalendar
when you want to display something for the user. That'll display according to their time zone and other settings.
As per the QA, for applying fixed date strings you should use a date formatter with an explicitly set locale and not think about the calendar at all.