美文网首页iOS开发总结
NSDate真的算错了吗

NSDate真的算错了吗

作者: Randall_Steven | 来源:发表于2016-04-12 22:55 被阅读53次

    起因

    作者在最近工作中需要向后台上传手机当前日期,我很自然的就想到我们可以用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]进行修改。

    总结

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

    相关文章

      网友评论

      • 李盛民:切身之痛:沉痛的教训就是,遇到问题,还是首先认真看苹果官方的文档,然后再到网上去搜,网上的答案确实不一定是对的,有的时候只是把你从一个坑领到了另一个坑里。
        必须要自己做一遍,现在谁的都不信了~
        Randall_Steven:实践出真知,这话还是很对的

      本文标题: NSDate真的算错了吗

      本文链接:https://www.haomeiwen.com/subject/odswlttx.html