我正在尝试处理日期,并在未来创建日期,但夏令时总是阻碍我的工作,打乱我的时间。
下面是我的代码,用来移动到下个月第一天的午夜进行约会:
+ (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];
}它给出了我在日期上迭代运行该方法时的日期:
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,但这似乎没有什么不同。对于如何使时间恒定,而不考虑夏令时的变化,您有什么建议吗?
发布于 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日午夜”。不要去添加你并不是真正想要的日历组件。
发布于 2013-01-29 04:54:19
请记住,您的程序打印到日志的是GMT时间,而不是本地时间。因此,在切换到您当地时区的DST之后,GMT将偏移一个小时是正确的。
发布于 2016-03-03 19:42:41
我也有同样的问题,人们说这实际上不是问题(就像我在一些相关的帖子上看到的那样)对这种情况没有帮助。每当你不得不处理时区和DST时,这类问题就会让人痛苦,我总是觉得每次都必须重新学习它。
我尽可能多地处理纪元时间(这是一个图表应用程序),但有时我需要使用NSDate和NSCalendar (即,用于格式化轴标签,以及用于标记日历月、季度和年)。我为此挣扎了一天左右,试图在日历上设置不同的时区之类的。
最后,我发现下面这行代码在我的应用委托中有很大的帮助:
// prevent DST bugs by setting default timezone for app
if let utcZone = NSTimeZone(abbreviation: "UTC") {
NSTimeZone.setDefaultTimeZone(utcZone)
}最重要的是,源数据必须经过清理,所以每当我对传入数据使用NSDateFormatter时,我都会确保将其时区设置为数据源的正确时区(在我的示例中,它是格林尼治标准时间)。这消除了数据源中令人讨厌的DST问题,并确保所有生成的NSDates都可以很好地转换为纪元时间,而不用担心DST。
https://stackoverflow.com/questions/14570251
复制相似问题