保存 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 回答):
- 子类化 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;
}
在 didFinishLaunchingWithOptions:
中添加 [NSTimeZone setDefaultTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]]
以便所有日期格式化程序默认在 GMT 中生成日期字符串(但从不在格式字符串中包含时区)。
当需要保存用户操作的 date/time 时,通过 [NSDate gmtDate]
获取日期并将该值保存在数据库中。
我的应用程序与时区无关:我希望以忽略用户时区变化的方式保存和显示日期和时间。一旦我在我的应用程序中记录了某些用户操作的本地 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 回答):
- 子类化 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; }
在
didFinishLaunchingWithOptions:
中添加[NSTimeZone setDefaultTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]]
以便所有日期格式化程序默认在 GMT 中生成日期字符串(但从不在格式字符串中包含时区)。当需要保存用户操作的 date/time 时,通过
[NSDate gmtDate]
获取日期并将该值保存在数据库中。