如何在任何情况下从NSDate获得正确的年份?

问题描述:

我知道的是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

正如@Larme在他的评论中指出的,你的本地时区正在影响你的结果;

您已于2015年12月31日下午4点指定UTC。这是2016年1月1日当地时区(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 

你的代码是完全正常的。 po命令显示依赖于UTC的时间说明,而NSCalendar/NSDateComponents考虑当前时区。

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

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

都在时间的同一时刻。

如果您必须始终处理基于UTC的日期,请将NSCalendar实例的时区设置为UTC

“年”组件将始终返回正确的年份 - 基于正在使用的日历! NSDate使用UTC登录,但是使用当地时区计算年份。你给的日期是2015年在伦敦使用GMT(接近UTC),但在2016年在世界其他地区。例如在澳大利亚,当时的新年焰火早已消失。

当你在看日历周时,这是一个完全不同的,完全不相关的主题。 12月31日可以在一年的最后一周,或下周的第一周。但这不是由“年份”返回。它由“yearForWeekOfYear”返回。