Как получить правильный год от NSDate при любых обстоятельствах?

Я знаю о NSDateComponents, но дело в том, что какой-то недельный механизм испортит результат, когда дата стоит в начале или в конце года.

Например:

NSCalendar *calendar = [NSCalendar currentCalendar];
NSCalendarUnit calendarUnit = NSYearCalendarUnit;
NSDateComponents *dateComponents = [calendar components:calendarUnit fromDate:self.date];

(lldb) po self.date
2015-12-31 16:00:00 +0000

(lldb) po dateComponents
<NSDateComponents: 0x12f4c83f0>
    Calendar Year: 2016

Изменение minimumDaysInFirstWeek также не имеет большого значения, и NSDateFormatter не кажется лучшим способом.


person dopcn    schedule 01.04.2016    source источник
comment
Какой у вас часовой пояс. Вы ›+8:00?   -  person Larme    schedule 01.04.2016
comment
@Larme yes (lldb) po [[NSCalendar currentCalendar] timeZone] Азия/Шанхай (GMT+8) смещение 28800   -  person dopcn    schedule 01.04.2016


Ответы (3)


Как указал @Larme в своем комментарии, ваш местный часовой пояс влияет на ваш результат;

Вы указали 16:00 31 декабря 2015 года по всемирному координированному времени. Сейчас полночь 1 января 2016 года по вашему местному часовому поясу (UTC+8).

Вы можете использовать метод NSCalendar componentsInTimeZone для получения года в определенном часовом поясе:

NSCalendar *calendar = [NSCalendar currentCalendar];
NSTimeZone *tz=[NSTimeZone timeZoneForSecondsFromGMT:0];
NSDateComponents *dateComponents = [calendar componentsInTimeZone:tz fromDate:self.date];
int year=dateComponents.year;  // This will be 2015 
person Paulw11    schedule 01.04.2016

Ваш код в полном порядке. Команда po отображает описание времени, зависящее от UTC, а NSCalendar/NSDateComponents учитывает текущий часовой пояс.

2015-12-31 16:00:00 +0000

а также

2016-01-01 00:00:00 +0800

оба являются одним и тем же моментом времени.

Если вам всегда приходится иметь дело с датами на основе UTC, установите часовой пояс экземпляра NSCalendar на UTC.

person vadian    schedule 01.04.2016

Компонент «год» всегда будет возвращать правильный год — в зависимости от используемого календаря! NSDate регистрируется в формате UTC, но год рассчитывается с использованием вашего местного часового пояса. Дата, которую вы указали, была в 2015 году в Лондоне, где используется GMT (близко к UTC), но в 2016 году в других регионах мира. Например, в Австралии, где к тому времени уже давно отгремели новогодние фейерверки.

Когда вы смотрите на календарные недели, это совершенно другая и совершенно не связанная тема. 31 декабря может приходиться на последнюю неделю года или на первую неделю следующей недели. Но это не возвращается «годом». Он возвращается "yearForWeekOfYear".

person gnasher729    schedule 01.04.2016