NSDate 转换 NSDateComponents 问题

Posted

技术标签:

【中文标题】NSDate 转换 NSDateComponents 问题【英文标题】:NSDate convert NSDateComponents issue 【发布时间】:2013-04-17 20:46:42 【问题描述】:

destinationDate 和组件的结果不同。 我该如何解决这个问题?

NSTimeZone* sourceTimeZone      = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];

NSDate* sourceDate              = [NSDate date];
NSInteger sourceGMTOffset       = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger destinationGMTOffset  = [destinationTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval         = destinationGMTOffset - sourceGMTOffset;

NSDate* destinationDate         = [[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate];

NSCalendar *calendar            = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *components    = [calendar components:(NSYearCalendarUnit  |
                                                        NSMonthCalendarUnit |
                                                        NSDayCalendarUnit   |
                                                        NSHourCalendarUnit  |
                                                        NSMinuteCalendarUnit|
                                                        NSSecondCalendarUnit) fromDate:destinationDate];

NSLog(@"%@", destinationDate); 
NSLog(@"%@", components);

2013-04-24 19:27:09 +0000

历年:2013 月:4 闰月:无 天数:25 小时:4 分钟:27 第二:9

【问题讨论】:

您的问题是什么,日期描述将始终以 GMT 表示。您的 localTimeZone 似乎比格林威治标准时间晚 5 小时。第一个日志可以解释为下午 4:27,它与组件中显示的相同 你有答案吗? 我正在努力解决一个很接近的问题,但我无法从您的代码中理解您最初想要实现的目标 - 您能否用几句话来说明这一点? 【参考方案1】:

日期 (destinationDate) 以 GMT 打印。但是,日期组件并不是因为日历是使用本地时区创建的。

如果您尝试使用calendar.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0],您将得到相同的结果。否则,您将获得两次添加的差异(第一次由您的代码,第二次由日历)

实际上,您的代码没有多大意义。 NSDate 不应该被时区修改,因为它不包含任何时区信息。 NSDate 始终代表特定的时刻,与时区无关。仅当您想将日期转换为字符串时才转换日期 - 当您这样做时,请使用 NSCalendarNSDateFormatter 并设置正确的时区。

以下代码足以打印出带有系统(默认)时区的日期,

NSDate* sourceDate              = [NSDate date];
NSCalendar *calendar            = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *components = [calendar components:(NSYearCalendarUnit  |
                                                     NSMonthCalendarUnit |
                                                     NSDayCalendarUnit   |
                                                     NSHourCalendarUnit  |
                                                     NSMinuteCalendarUnit|
                                                     NSSecondCalendarUnit) fromDate:destinationDate];

NSLog(@"%@", sourceDate); 
NSLog(@"%@", components);

【讨论】:

您能否在解释中添加(隐式)应用系统时区的位置?它在日历上吗?在向组件的转变中?你只说你想要一个公历,你什么都不说时区...... @MottiShneor 这是一个非常古老的答案,并稍微改进了措辞。系统时区存储在日历中。当您想将Date(某个时刻)转换为特定的时间分量(相对于给定时区)时使用它。【参考方案2】:

NSDateComponents 总是以格林威治标准时间的形式给出日期,所以只需像下面这样简单地放置你就会得到当前日期。

NSDateComponents *components    = [calendar components:(NSYearCalendarUnit  |
                                                            NSMonthCalendarUnit |
                                                            NSDayCalendarUnit   |
                                                            NSHourCalendarUnit  |
                                                            NSMinuteCalendarUnit|
                                                            NSSecondCalendarUnit) fromDate:[NSDate date]];

destinationDate 替换为[NSDate date]

输出:

 2013-04-24 16:05:08 +0000

<NSDateComponents: 0x7e3e5b0>
    Calendar Year: 2013
    Month: 4
    Day: 24
    Hour: 16
    Minute: 5
    Second: 8

【讨论】:

你是如何得出 OP 想要什么的结论的? 他提到destinationDate 和组件不同,这就是我在他的代码中发现问题的原因。 在他的代码中,他将 sourceDate 创建为 currentDate 并使用间隔创建destinationDate,这取决于 timeZone 将被提前或延迟。这个问题本身很模糊,为什么你说用 currentDate 替换destinationDate。非常混乱。

以上是关于NSDate 转换 NSDateComponents 问题的主要内容,如果未能解决你的问题,请参考以下文章

NSDate - 将日期转换为 GMT

如何在iphone中找出当前年份是不是闰年[重复]

将NSDate转换为NSString

将 NSDate 转换为 NSString

将 Adob​​e PDF 日期字符串转换为 NSDate

NSDate 转换 NSDateComponents 问题