Это, кажется, повторяющаяся проблема для много ( меня включили ) и после того, как вытащилмои волосы слишком длинные, я наконец решил проблему.
Предположения, на которые опирается этот код, таковы:
- вас интересуют даты, а не время
- вы хотите, чтобы ваши вычисления даты не обращали внимания на любое летнее время
- вам нужно достаточно простое строковое представление даты, чтобы вы могли сохранить ее.
Для достижения1. Я использую уникальный экземпляр NSCalendar, который инициализируется в григорианском, GMT Это также служит 2.
для 3. NSDateFormatter инициализируется как уникальным календарем , так и его часовым поясом.Установка часового пояса для модуля форматирования на часовой пояс календаря, который в противном случае использовался для расчета, была ключом ко всем возникшим у меня проблемам!
Это всегда должно быть верно (предположим, что приведенный ниже код является частью класса DateModel
):
NSDate * today = [DateModel normalize: [NSDate date]] ;
NSString*todayS= [DateModel dateToString: today] ;
BOOL alwaysTrue=[[DateModel normalize: [NSDate date]] isEqual: [DateModel stringToDate: todayS]] ;
Вот код:
+ (NSDate *) normalize: (NSDate *) date {
NSDateComponents * comps = [[DateModel calendar] components:NSYearCalendarUnit
| NSMonthCalendarUnit
| NSDayCalendarUnit
| NSHourCalendarUnit
| NSMinuteCalendarUnit
| NSSecondCalendarUnit
fromDate:date] ;
[comps setHour:0] ;
[comps setMinute:0] ;
[comps setSecond:0] ;
NSDate * dateOnly = [[DateModel calendar] dateFromComponents:comps] ;
return dateOnly ;
}
+ (NSCalendar *) calendar {
static NSCalendar * calendar = nil ;
if (calendar == nil) {
calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] ;
calendar.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"GMT"] ;
}
return calendar ;
}
+ (NSDateFormatter *) dateFormatter {
static NSDateFormatter * formatter = nil ;
if (formatter == nil) {
formatter = [[NSDateFormatter alloc] init] ;
[formatter setCalendar:[self calendar]] ; // <- This is
[formatter setTimeZone:[self calendar].timeZone] ; // <- critical
[formatter setDateFormat:@"yyyyMMdd"] ;
}
return formatter ;
}
+ (NSDate *) dateFromString: (NSString *) stringDate {
return [DateModel normalize: [[DateModel dateFormatter] dateFromString:stringDate]] ;
}
+ (NSString *) stringFromDate: (NSDate *) date {
return [[DateModel dateFormatter] stringFromDate:[DateModel normalize: date]] ;
}
Надеюсь, это кому-нибудь поможет!