保存 NSDate 后忽略时区更改

Ignoring time-zone changes after saving NSDate

我的应用程序与时区无关:我希望以忽略用户时区变化的方式保存和显示日期和时间。一旦我在我的应用程序中记录了某些用户操作的本地 date/time(通常通过在 sqlite 数据库中保存 timeIntervalSince1970),我想显示相同的 date/time 字符串,无论用户的时区是否已更改与否,也不管用户在其设备中的各种时区设置。

例如,如果用户的操作发生在旧金山当地时间 1:15 下午,然后他几天后在纽约打开我的应用程序,我希望之前的操作仍然显示为 1:15 pm(不是 4:15 pm),即使他在他的设备中手动设置了其他时区(例如芝加哥)。在纽约 9:00 pm 的第二个动作应该永远显示为 9:00 pm,即使回到加利福尼亚也是如此。

我可以通过将每个 date/time 保存为一个字符串(基于用户的本地时区)来实现我的目标,然后不再使用日期方法——但是我不能这样做 date/time算术(例如,排序)。

如何在保存和检索时与时区无关dates/times?

(Apple 的日历应用程序似乎在时区覆盖打开时以这种方式运行,但前提是我手动设置事件时间。)

记录时区和时间戳。稍后格式化时间戳时使用该时区。您需要向数据库添加另一列 table.

按照 Rob 的建议保存时区,或者将时间同时保存为 NSDate 字符串。使用 UI 的字符串和 NSDate 的字符串进行计算。

或者嘿,如果你需要的话,三个都做。

这是可行的解决方案(@Hot Licks 值得称赞,但他没有 post 回答):

  1. 子类化 NSDate 并添加一个 gmtDate 方法来完成从本地 TZ 到 GMT 的转换。 gmtDate 使用 @"yyyy-MM-dd HH:mm" 作为格式字符串,它也会从值中删除秒数。像这样:
+(NSDate *)gmtDate
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm"; // drops the seconds

    dateFormatter.timeZone = [NSTimeZone systemTimeZone]; // the local TZ
    NSString *localTimeStamp = [dateFormatter stringFromDate:[NSDate date]];
    // localTimeStamp is the current clock time in the current TZ

    // adjust date so it'll be the same clock time in GMT
    dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
    NSDate *gmtDate = [dateFormatter dateFromString:localTimeStamp];
    return gmtDate;
}
  1. didFinishLaunchingWithOptions: 中添加 [NSTimeZone setDefaultTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]] 以便所有日期格式化程序默认在 GMT 中生成日期字符串(但从不在格式字符串中包含时区)。

  2. 当需要保存用户操作的 date/time 时,通过 [NSDate gmtDate] 获取日期并将该值保存在数据库中。