NSDate 和 TimeZone 问题
Posted
技术标签:
【中文标题】NSDate 和 TimeZone 问题【英文标题】:NSDate and TimeZone Issues 【发布时间】:2014-02-11 04:34:45 【问题描述】:我正在尝试让我的应用根据预定事件触发通知。给出的日期来自将在 EST 进行的时间表。给出的时间是 2014 年 2 月 21 日星期五 12:00:00 -0500(美国东部标准时间中午)。
当按下安排通知的按钮时,它会运行以下代码:
NSString *message = [@"15 minutes until " stringByAppendingString:self.thetitle];
NSLog(@"original%@", self.thedate);
NSDate *newDate = [self.thedate dateByAddingTimeInterval:-60*15];
NSDateFormatter *formatter3 = [[NSDateFormatter alloc] init];
// [formatter3 setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
[formatter3 setTimeStyle:NSDateFormatterShortStyle];
[formatter3 setDateStyle:NSDateFormatterShortStyle];
NSString *detailstext = [formatter3 stringFromDate:newDate];
NSDate *othernewdate = [formatter3 dateFromString:detailstext];
NSLog(@"other%@", othernewdate);
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.timeZone = [NSTimeZone systemTimeZone];
notification.fireDate = othernewdate;
notification.alertBody = message;
notification.soundName = UILocalNotificationDefaultSoundName;
notification.hasAction = YES;
notification.alertAction = NSLocalizedString(@"View", @"View notification button");
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
由于通知 fireDate 上设置的时间是 othernewdate,因此我在控制台中运行了一个 NSLog 以查看它显示的内容。它回来了:
2014-02-21 16:45:00 +0000
这似乎很完美,因为美国东部标准时间的那个时间是上午 11:45,或者中午前 15 分钟,这正是我想要的。
问题是这样的: 我正在 CST 中对此进行测试。我运行该应用程序,告诉它为此事件安排通知,然后将我的手机时钟更改为 EST,它最终在 10:45 触发通知。
会有人从不同的时区使用这个应用程序,然后在这个应用程序的会议开始时前往美国东部标准时间。我不希望他们在不同的时区安排大量通知并在错误的时间触发。有什么建议吗?
【问题讨论】:
在字符串和日期之间转换时使用NSDateFormatter
。还要在格式化程序中设置时区。 NSDate
的 NSLog
可能没有提供您想要/期望的字符串,请在 NSLog
中使用 NSDateFormatter
。 NSDate
内部基于 GMT,时区只影响字符串到日期、日期到字符串和日期组件的操作。
@Zaph 好的,我试过在一行中添加 ~[formatter3 setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"EST"]];~ 但它保持不变。
【参考方案1】:
如果您希望在独立于时区的绝对日期/时间触发通知,则必须设置notification.timezone = nil
。
来自文档:
"fireDate中指定的日期根据该属性的值进行解释。如果指定nil(默认),则触发日期解释为绝对GMT时间,适用于倒数计时器等情况。如果如果您为此属性分配一个有效的 NSTimeZone 对象,则触发日期被解释为挂钟时间,当时区发生变化时会自动调整;适合这种情况的示例是闹钟。"
【讨论】:
仍然没有区别。 您能在更改设备时区前后显示NSLog(@"timezone=%@, notification=%@", [NSTimeZone localTimeZone], notification)
的输出吗?以上是关于NSDate 和 TimeZone 问题的主要内容,如果未能解决你的问题,请参考以下文章
Symfony2 和 date_default_timezone_get() - 依赖系统的时区设置是不安全的