以下是代码:
NSDate *dateLocalNow = [self getLocalDate:[NSDate date]];
NSLog(@"%@",dateLocalNow);
NSDateComponents *dateToCheckAgainst = [[NSCalendar currentCalendar] components:NSMinuteCalendarUnit | NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSMinuteCalendarUnit fromDate: dateLocalNow];
NSLog(@"%@", dateToCheckAgainst);
getLocalDate
告诉我当地时区的日期。如果NSLog
输出dateLocalNow
:
2014-10-29 01:01:55 +0000
这是getLocalDate
来源:
-(NSDate *)getLocalDate:(NSDate *)date {
NSDate* sourceDate = date;
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
NSDate* destinationDate = [[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate];
return destinationDate;
}
为什么NSLog
dateToCheck
反对给我以下内容?:
Calendar Year: 2014
Month: 10
Leap month: no
Day: 28
Minute: 1
答案 0 :(得分:2)
NSDate
与时区无关。在内部,它存储自参考时间点以来经过的秒数。该参考点有许多人类可读的标签。以下是Cocoa标准参考日期的一些人类可读标签:
这些标签都代表同一时刻,但该瞬间可以通过多种不同的方式进行标记。只有一种方法可以将该瞬间表示为NSDate
。
您已经制作了一个新的NSDate
原始版NSDate
,并根据某些时区偏移进行了调整,但iOS SDK并不知道或不关心。它会根据与标准参考日期的偏移量将您的新NSDate
视为即时。新瞬间与原始瞬间不同(除非您的系统时区恰好是GMT)。转换为人类可读的字符串或NSDateComponents
时,您不应期望它产生相同的结果,除非您在NSDateFormatter
或NSCalendar
上设置恰好的时区 - 你在发布的代码中没做过。
那你怎么办呢?您不会尝试根据时区偏移创建偏离其他NSDate
的{{1}}。相反,您可以通过设置NSDate
的{{1}}属性,在将NSDate
转换为人类可读的字符串时指定时区。或者,当您询问日期的组成部分时,可以设置timeZone
的{{1}}属性。如果您要从组件构建日期,则还可以在使用日历将组件转换为NSDateFormatter
之前设置timeZone
的{{1}}。
因此:
NSCalendar
输出:
timeZone
答案 1 :(得分:1)
你能退一步告诉我们你要做什么吗?这个例程感觉就像你正在尝试[NSDate date]
并将其“转换”为当地时间。但这不是日期在Cocoa中如何运作的。 NSDate
没有时区概念。只有日期格式化程序(和日历)才能。
所以,当你得到[NSDate date]
时,它会检索当前时间。是的,如果您NSLog
,它可能会在GMT中显示给您,但如果您使用带有默认时区的NSDateFormatter
或从NSCalendar
获取组件,它将始终位于本地时区(除非你将其覆盖为别的东西),不需要调整。
答案 2 :(得分:0)
+0000表示它是本地日期的GMT表示。使用NSDateFormatter记录显示日期,它将显示组件