NSDate真的算错了吗

起因

作者在最近工作中需要向后台上传手机当前日期,我很自然的就想到我们可以用NSDate来获取当前系统时间,于是就用下面的方法获得了系统时间并转换成了日期

NSDate *sourceDate = [NSDate date]
NSDateFormatter  *dateformatter = [[NSDateFormatter alloc] init];
[dateformatter setDateFormat:@"YYYY-MM-dd"];
[dateformatter stringFromDate:sourceDate]

但是,当我在检验上传数据是否正确的时候,把[NSDate date]在控制台中输出后,发现居然和正确时间有了8小时的时差。这显然是项目不能接受的误差,所以我尝试将这8小时的误差进行调整

尝试

于是经过一番Google,我发现网上好多人都遇到了这个问题,于是找到了下面的这种解决办法

NSDate *sourceDate = [NSDate date];
NSTimeZone *sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
NSTimeZone *mytimeZone = [NSTimeZone systemTimeZone];

NSInteger sourceOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger myTimeOffset = [mytimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval = myTimeOffset - sourceOffset;

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

这时候我的destinationDate就是我认为“正确”的时间,但是当我调用stringFromDate:时,然而发现坑爹的日期居然变成了明天的日期(发现问题时在下午)

正确的做法

在查看了苹果关于NSDate和NSDateFormatter的文档后,终于发现,第二步的转换完全是多此一举。
文档中明确的说明了

NSDate objects encapsulate a single point in time, independent of any particular calendrical system or time zone. Date objects are immutable, representing an invariant time interval relative to an absolute reference date (00:00:00 UTC on 1 January 2001).

也就是说,NSDate是没有时区这个概念的,他只提供了一个UTC时间,与时区无关,我们前面对NSDate的操作是强行给他加了8小时,并没有改变时区。
而时区的概念是存在于NSDateFormatter中,在我们调用stringFromDate:时就已经默认将UTC时间转换成了我们所在的时区,并不需要我们对[NSDate date]进行修改。

总结

我遇到这个蛋疼的问题后,我问了以前取过当前日期的同事,发现他的代码也存在同样的问题,只是当时测试并没有发现。
沉痛的教训就是,遇到问题,还是首先认真看苹果官方的文档,然后再到网上去搜,网上的答案确实不一定是对的,有的时候只是把你从一个坑领到了另一个坑里。

你可能感兴趣的:(NSDate真的算错了吗)