首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >iOS在未来创建日期,忽略夏令时

iOS在未来创建日期,忽略夏令时
EN

Stack Overflow用户
提问于 2013-01-29 04:05:13
回答 4查看 3.1K关注 0票数 10

我正在尝试处理日期,并在未来创建日期,但夏令时总是阻碍我的工作,打乱我的时间。

下面是我的代码,用来移动到下个月第一天的午夜进行约会:

代码语言:javascript
运行
复制
+ (NSDate *)firstDayOfNextMonthForDate:(NSDate*)date
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    calendar.timeZone = [NSTimeZone systemTimeZone];
    calendar.locale = [NSLocale currentLocale];

    NSDate *currentDate = [NSDate dateByAddingMonths:1 toDate:date];
    NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
                                                    fromDate:currentDate];

    [components setDay:1];
    [components setHour:0];
    [components setMinute:0];
    [components setSecond:0];

    return [calendar dateFromComponents:components];
}

+ (NSDate *) dateByAddingMonths: (NSInteger) monthsToAdd toDate:(NSDate*)date
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    calendar.timeZone = [NSTimeZone systemTimeZone];
    calendar.locale = [NSLocale currentLocale];

    NSDateComponents * months = [[NSDateComponents alloc] init];
    [months setMonth: monthsToAdd];

    return [calendar dateByAddingComponents: months toDate: date options: 0];
}

它给出了我在日期上迭代运行该方法时的日期:

代码语言:javascript
运行
复制
2013-02-01 00:00:00 +0000
2013-03-01 00:00:00 +0000
2013-03-31 23:00:00 +0000 should be 2013-04-01 00:00:00 +0000
2013-04-30 23:00:00 +0000 should be 2013-05-01 00:00:00 +0000

我最初的想法是不使用systemTimeZone,但这似乎没有什么不同。对于如何使时间恒定,而不考虑夏令时的变化,您有什么建议吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-01-29 05:15:40

对于给定的日历日期/时间,一般不可能预测表示的实际时间(从纪元开始的秒数)。时区更改,DST规则更改。这是生活中的一个事实。DST在澳大利亚有一段痛苦的历史。在以色列,DST规则一直是非常不可预测的。DST规则最近在美国发生了变化,这给微软带来了巨大的麻烦,因为它存储的是秒而不是日历日期。

当你指的是NSDateComponents时,永远不要保存NSDate。如果您的意思是“2013年5月1日在伦敦”,那么在数据库中保存“2013年5月1日在伦敦”。然后计算出尽可能接近实际事件的NSDate。如果你关心日历的事情(比如月份),那么可以使用NSDateComponents完成所有的日历数学运算。如果你真的只关心秒,那就只做NSDate数学。

编辑:有关很多非常有用的背景知识,请参阅Date and Time Programming Guide

还有一个关于日历组件的附注:当我说“2013年5月1日在伦敦”时,这并不意味着“5月1日午夜”。不要去添加你并不是真正想要的日历组件。

票数 8
EN

Stack Overflow用户

发布于 2013-01-29 04:54:19

请记住,您的程序打印到日志的是GMT时间,而不是本地时间。因此,在切换到您当地时区的DST之后,GMT将偏移一个小时是正确的。

票数 4
EN

Stack Overflow用户

发布于 2016-03-03 19:42:41

我也有同样的问题,人们说这实际上不是问题(就像我在一些相关的帖子上看到的那样)对这种情况没有帮助。每当你不得不处理时区和DST时,这类问题就会让人痛苦,我总是觉得每次都必须重新学习它。

我尽可能多地处理纪元时间(这是一个图表应用程序),但有时我需要使用NSDate和NSCalendar (即,用于格式化轴标签,以及用于标记日历月、季度和年)。我为此挣扎了一天左右,试图在日历上设置不同的时区之类的。

最后,我发现下面这行代码在我的应用委托中有很大的帮助:

代码语言:javascript
运行
复制
// prevent DST bugs by setting default timezone for app
    if let utcZone = NSTimeZone(abbreviation: "UTC") {
        NSTimeZone.setDefaultTimeZone(utcZone)
    }

最重要的是,源数据必须经过清理,所以每当我对传入数据使用NSDateFormatter时,我都会确保将其时区设置为数据源的正确时区(在我的示例中,它是格林尼治标准时间)。这消除了数据源中令人讨厌的DST问题,并确保所有生成的NSDates都可以很好地转换为纪元时间,而不用担心DST。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14570251

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档