为什么NSDateComponents给我一个不同的约会?

时间:2014-10-29 05:06:11

标签: ios objective-c

以下是代码:

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

3 个答案:

答案 0 :(得分:2)

NSDate与时区无关。在内部,它存储自参考时间点以来经过的秒数。该参考点有许多人类可读的标签。以下是Cocoa标准参考日期的一些人类可读标签:

  • 1/1/01,格林尼治标准时间上午12:00:00
  • 12/31/00,CST 6:00:00
  • 1/1 / 01,4:00 AM GMT + 4

这些标签都代表同一时刻,但该瞬间可以通过多种不同的方式进行标记。只有一种方法可以将该瞬间表示为NSDate

您已经制作了一个新的NSDate原始版NSDate,并根据某些时区偏移进行了调整,但iOS SDK并不知道或不关心。它会根据与标准参考日期的偏移量将您的新NSDate视为即时。新瞬间与原始瞬间不同(除非您的系统时区恰好是GMT)。转换为人类可读的字符串或NSDateComponents时,您不应期望它产生相同的结果,除非您在NSDateFormatterNSCalendar上设置恰好的时区 - 你在发布的代码中没做过。

那你怎么办呢?您不会尝试根据时区偏移创建偏离其他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记录显示日期,它将显示组件