2016-04-01 6 views
0

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

Например:

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 не кажется, лучше.

+0

Ваш часовой пояс. Вы> +8: 00? – Larme

+0

@Larme yes (lldb) po [[NSCalendar currentCalendar] timeZone] Азия/Шанхай (GMT + 8) офсет 28800 – dopcn

ответ

3

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

Вы указали 16:00 по 31 декабря 2015 года по UTC. Это полночь 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 
0

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

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

и

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

оба тот же момент времени.

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

0

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

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