【发布时间】:2010-12-24 04:33:43
【问题描述】:
我需要能够将 NSDate 值转换为 GMT 日期。
如何将 NSDate 值转换为 GMT 格式的 NSDate 值,而与 iPhone 设备使用的日期区域设置无关?
【问题讨论】:
标签: ios objective-c swift nsdate gmt
我需要能够将 NSDate 值转换为 GMT 日期。
如何将 NSDate 值转换为 GMT 格式的 NSDate 值,而与 iPhone 设备使用的日期区域设置无关?
【问题讨论】:
标签: ios objective-c swift nsdate gmt
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm";
NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
[dateFormatter setTimeZone:gmt];
NSString *timeStamp = [dateFormatter stringFromDate:[NSDate date]];
[dateFormatter release];
【讨论】:
在 Cocoa 中处理时间可能很复杂。当您获得 NSDate 对象时,它位于本地时区。 [[NSTimeZone defaultTimeZone] secondsFromGMT] 为您提供当前时区与 GMT 的偏移量。然后你可以这样做:
NSDate *localDate = // get the date
NSTimeInterval timeZoneOffset = [[NSTimeZone defaultTimeZone] secondsFromGMT]; // You could also use the systemTimeZone method
NSTimeInterval gmtTimeInterval = [localDate timeIntervalSinceReferenceDate] - timeZoneOffset;
NSDate *gmtDate = [NSDate dateWithTimeIntervalSinceReferenceDate:gmtTimeInterval];
现在gmtDate 应该为您提供正确的 GMT 日期。为了显示它,查看NSDateFormatter,特别是setDateStyle 和setTimeStyle 方法。您创建一个NSDateFormatter,按照您想要的方式对其进行配置,然后调用stringFromDate: 以获得一个格式良好的字符串。
【讨论】:
Howard's Answer是正确的,请投票接受。
作为参考,我认为解释日期对象和本地化日期表示之间的区别是有用的。
在许多编程语言中,日期对象用于表示唯一的时间点。忽略Relativistic 参数,可以假设在任何情况下我们都可以定义一个时间点,该时间点对每个人来说都是普遍相等的,而不管我们如何测量时间。
如果我们可以为每个时间点构造一个唯一的标签,则该标签可以被传递并明确引用。 日期对象的目的是充当给定时间点的唯一通用标签。
人们可以想出任何数量的技术来构建这样的标签方案,而每个日期对象如何选择这样做对任何使用它们的人来说都无关紧要。
一个例子可能是使用一个通用事件的数字偏移量(太阳爆炸后 X 秒)。
只有当我们希望获取一个时间点并将其序列化为人类可读的字符串时,我们才必须处理时区、语言环境等的复杂性......
(本地日期字符串) + (日期格式化程序) => 时间点
时间点 + (日期格式化程序) => (本地日期字符串)
每个时间点都是通用的...没有纽约时间点或格林威治标准时间点之类的东西,只有将时间点转换为本地字符串(使用日期格式化程序)是否会出现与时区的任何关联。
注意:我确信有很多关于这个问题的博客/文章,但是我的 google foo 在这个时间点让我失望了。如果有人有热情就这个问题展开讨论,请随时这样做。
【讨论】:
Swift 4:
//UTC or GMT ⟺ Local
extension Date {
// Convert local time to UTC (or GMT)
func toGlobalTime() -> Date {
let timezone = TimeZone.current
let seconds = -TimeInterval(timezone.secondsFromGMT(for: self))
return Date(timeInterval: seconds, since: self)
}
// Convert UTC (or GMT) to local time
func toLocalTime() -> Date {
let timezone = TimeZone.current
let seconds = TimeInterval(timezone.secondsFromGMT(for: self))
return Date(timeInterval: seconds, since: self)
}
}
【讨论】:
虽然 Alex 的回答是一个好的开始,但它没有处理 DST(夏令时),并添加了与参考日期的不必要转换。以下对我有用:
要从 localDate 转换为 GMT,将 DST 考虑在内:
NSDate *localDate = <<your local date>>
NSTimeInterval timeZoneOffset = [[NSTimeZone systemTimeZone] secondsFromGMTForDate:localDate];
NSDate *gmtDate = [localDate dateByAddingTimeInterval:-timeZoneOffset]; // NOTE the "-" sign!
要从 GMT 日期转换为 localDate,将 DST 考虑在内:
NSDate *gmtDate = <<your gmt date>>
NSTimeInterval timeZoneOffset = [[NSTimeZone systemTimeZone] secondsFromGMTForDate:gmtDate];
NSDate *localDate = [gmtDate dateByAddingTimeInterval:timeZoneOffset];
一个小提示:我使用了 dateByAddingTimeInterval,它仅适用于 iOS 4。如果您使用的是 OS 3 或更早版本,请使用 addTimerInterval。
【讨论】:
您是否尝试过查看 NSDateFormatter 的文档?
NSDateFormatter 似乎有一些玩 TimeZones 的方法,特别是
-setTimeZone:
我自己没有测试过,但我想如果您将 GMT 设置为最初以另一个时区表示的日期的时区,它将显示正确调整以匹配新时区的日期。
【讨论】: