代码如下:
NSDate *dateLocalNow = [self getLocalDate:[NSDate date]];
NSLog(@"%@",dateLocalNow);
NSDateComponents *dateToCheckAgainst = [[NSCalendar currentCalendar] components:NSMinuteCalendarUnit | NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSMinuteCalendarUnit fromDate: dateLocalNow];
NSLog(@"%@", dateToCheckAgainst);
getLocalDate
给我本地时区的日期。如果 dateLocalNow
的 NSLog
输出:
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
for dateToCheck
against 给我以下信息?:
Calendar Year: 2014
Month: 10
Leap month: no
Day: 28
Minute: 1
最佳答案
NSDate
与时区无关。在内部,它存储自引用时间点以来经过的秒数。该引用点有许多人类可读的标签。以下是 Cocoa 标准引用日期的一些人类可读标签:
- 1/1/01,格林威治标准时间上午 12:00:00
- 12/31/00,下午 6:00:00 CST
- 1/1/01,格林威治标准时间+4 上午 4:00:00
这些标签都代表同一时刻,但可以用许多不同的方式来标记该时刻。只有一种方法可以将该瞬间表示为 NSDate
。
您已经创建了一个新的 NSDate
,它是原始的 NSDate
,调整了一些时区偏移量,但 iOS SDK 不知道也不关心。它认为您的新 NSDate
是基于其标准引用日期的偏移量的即时时间。该新时刻与您的原始时刻不同(除非您的系统时区恰好是 GMT)。你不应该期望它在转换为人类可读的字符串或 NSDateComponents
时产生相同的结果,除非你在 NSDateFormatter
或 上设置时区NSCalendar
恰到好处——您在发布的代码中没有这样做。
那你怎么办呢?您不要尝试创建一个 NSDate
,该 NSDate
与另一个基于时区偏移的 NSDate
存在偏移。相反,当您将 NSDate
转换为人类可读的字符串时,您可以通过设置 NSDateFormatter
的 timeZone
属性来指定时区。或者,当您询问日期的组成部分时,您可以设置 NSCalendar
的 timeZone
属性。如果您从组件构建日期,您还可以在使用日历将组件转换为 NSDate
之前设置 NSDateComponents
的 timeZone
>.
因此:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSDate *now = [NSDate date];
NSDateFormatter *f = [[NSDateFormatter alloc] init];
f.dateStyle = NSDateFormatterShortStyle;
f.timeStyle = NSDateFormatterLongStyle;
f.timeZone = [NSTimeZone systemTimeZone];
NSLog(@"from formatter = %@", [f stringFromDate:now]);
NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.timeZone = [NSTimeZone systemTimeZone];
NSDateComponents *components = [calendar components:NSMinuteCalendarUnit | NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:now];
NSLog(@"components = %@", components);
}
return 0;
}
输出:
2014-10-29 00:24:19.762 commandline[28543:303] from formatter = 10/29/14, 12:24:19 AM CDT
2014-10-29 00:24:19.763 commandline[28543:303] components = <NSDateComponents: 0x1001027a0>
Calendar Year: 2014
Month: 10
Leap month: no
Day: 29
Minute: 24
关于ios - 为什么 NSDateComponents 给我一个不同的日期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26623118/