NSDate() 或 Date() 显示错误的时间
NSDate() or Date() shows the wrong time
当我尝试记录当前日期时:
print(NSDate())
或
print(Date())
(在Swift 3)
或任何日期对象,它显示错误的时间。比如现在是16:12左右,但是上面显示的是
2016-10-08 20:11:40 +0000
我约会的时区不对吗?如何确定我的日期以使用正确的时区?
为什么会这样,我该如何解决?如何在打印语句或调试器中轻松显示本地时区的任意日期?
(注意这个问题是 "ringer" 这样我就可以提供一个简单的 Swift 3/Swift 2 Date/NSDate 扩展,让你轻松显示任何日期在您当地时区的对象。
NSDate(或 Swift ≥ V3 中的日期)没有时区。它记录了全世界的一瞬间。
在内部,日期对象记录自“纪元日期”或 2001 年 1 月 1 日午夜以来的秒数 Greenwich Mean Time、a.k.a UTC。
我们通常会想到本地时区的日期。
如果您使用
记录日期
print(NSDate())
系统显示当前日期,但它以UTC/Greenwich 标准时间表示。所以时间唯一正确的地方就是那个时区。
如果您发出调试器命令,您会在调试器中遇到同样的问题
e NSDate()
这很痛苦。我个人希望 iOS/Mac OS 会使用用户的当前时区显示日期,但他们不会。
编辑#2:
我以前使用本地化字符串的一个改进是创建 Date
class:
的扩展,使其更易于使用
extension Date {
func localString(dateStyle: DateFormatter.Style = .medium, timeStyle: DateFormatter.Style = .medium) -> String {
return DateFormatter.localizedString(from: self, dateStyle: dateStyle, timeStyle: timeStyle)
}
}
这样你可以只使用像 Date().localString()
这样的表达式,或者如果你只想打印时间,你可以使用 Date().localString(dateStyle:.none)
编辑:
我刚刚发现 NSDateFormatter
(Swift 3 中的 DateFormatter
)有一个 class 方法 localizedString。这就是我下面的扩展所做的,但更简单、更干净。这是声明:
class func localizedString(from date: Date, dateStyle dstyle: DateFormatter.Style, timeStyle tstyle: DateFormatter.Style) -> String
所以你只需使用
let now = Date()
print (DateFormatter.localizedString(
from: now,
dateStyle: .short,
timeStyle: .short))
您几乎可以忽略下面的所有内容。
我已经创建了一个 NSDate class(swift 3 中的日期)的类别,它有一个方法 localDateString 显示用户本地时区的日期。
这里是 Swift 3 格式的类别:(文件名 Date_displayString.swift)
extension Date {
@nonobjc static var localFormatter: DateFormatter = {
let dateStringFormatter = DateFormatter()
dateStringFormatter.dateStyle = .medium
dateStringFormatter.timeStyle = .medium
return dateStringFormatter
}()
func localDateString() -> String
{
return Date.localFormatter.string(from: self)
}
}
并且在 Swift 2 形式中:
extension NSDate {
@nonobjc static var localFormatter: NSDateFormatter = {
let dateStringFormatter = NSDateFormatter()
dateStringFormatter.dateStyle = .MediumStyle
dateStringFormatter.timeStyle = .MediumStyle
return dateStringFormatter
}()
public func localDateString() -> String
{
return NSDate.localFormatter.stringFromDate(self)
}
}
(如果您喜欢不同的日期格式,可以很容易地修改日期格式化程序使用的格式。在您需要的任何时区显示日期和时间也很简单。)
我建议将此文件的适当 Swift 2/Swift 3 版本放入您的所有项目中。
然后您可以使用
Swift 2:
print(NSDate().localDateString())
Swift 3:
print(Date().localDateString())
一种更正时区日期的简单方法是使用 TimeZone.current.secondsFromGMT()
对于本地时间戳值,例如:
let currentLocalTimestamp = (Int(Date().timeIntervalSince1970) + TimeZone.current.secondsFromGMT())
当我尝试记录当前日期时:
print(NSDate())
或
print(Date())
(在Swift 3)
或任何日期对象,它显示错误的时间。比如现在是16:12左右,但是上面显示的是
2016-10-08 20:11:40 +0000
我约会的时区不对吗?如何确定我的日期以使用正确的时区?
为什么会这样,我该如何解决?如何在打印语句或调试器中轻松显示本地时区的任意日期?
(注意这个问题是 "ringer" 这样我就可以提供一个简单的 Swift 3/Swift 2 Date/NSDate 扩展,让你轻松显示任何日期在您当地时区的对象。
NSDate(或 Swift ≥ V3 中的日期)没有时区。它记录了全世界的一瞬间。
在内部,日期对象记录自“纪元日期”或 2001 年 1 月 1 日午夜以来的秒数 Greenwich Mean Time、a.k.a UTC。
我们通常会想到本地时区的日期。
如果您使用
记录日期print(NSDate())
系统显示当前日期,但它以UTC/Greenwich 标准时间表示。所以时间唯一正确的地方就是那个时区。
如果您发出调试器命令,您会在调试器中遇到同样的问题
e NSDate()
这很痛苦。我个人希望 iOS/Mac OS 会使用用户的当前时区显示日期,但他们不会。
编辑#2:
我以前使用本地化字符串的一个改进是创建 Date
class:
extension Date {
func localString(dateStyle: DateFormatter.Style = .medium, timeStyle: DateFormatter.Style = .medium) -> String {
return DateFormatter.localizedString(from: self, dateStyle: dateStyle, timeStyle: timeStyle)
}
}
这样你可以只使用像 Date().localString()
这样的表达式,或者如果你只想打印时间,你可以使用 Date().localString(dateStyle:.none)
编辑:
我刚刚发现 NSDateFormatter
(Swift 3 中的 DateFormatter
)有一个 class 方法 localizedString。这就是我下面的扩展所做的,但更简单、更干净。这是声明:
class func localizedString(from date: Date, dateStyle dstyle: DateFormatter.Style, timeStyle tstyle: DateFormatter.Style) -> String
所以你只需使用
let now = Date()
print (DateFormatter.localizedString(
from: now,
dateStyle: .short,
timeStyle: .short))
您几乎可以忽略下面的所有内容。
我已经创建了一个 NSDate class(swift 3 中的日期)的类别,它有一个方法 localDateString 显示用户本地时区的日期。
这里是 Swift 3 格式的类别:(文件名 Date_displayString.swift)
extension Date {
@nonobjc static var localFormatter: DateFormatter = {
let dateStringFormatter = DateFormatter()
dateStringFormatter.dateStyle = .medium
dateStringFormatter.timeStyle = .medium
return dateStringFormatter
}()
func localDateString() -> String
{
return Date.localFormatter.string(from: self)
}
}
并且在 Swift 2 形式中:
extension NSDate {
@nonobjc static var localFormatter: NSDateFormatter = {
let dateStringFormatter = NSDateFormatter()
dateStringFormatter.dateStyle = .MediumStyle
dateStringFormatter.timeStyle = .MediumStyle
return dateStringFormatter
}()
public func localDateString() -> String
{
return NSDate.localFormatter.stringFromDate(self)
}
}
(如果您喜欢不同的日期格式,可以很容易地修改日期格式化程序使用的格式。在您需要的任何时区显示日期和时间也很简单。)
我建议将此文件的适当 Swift 2/Swift 3 版本放入您的所有项目中。
然后您可以使用
Swift 2:
print(NSDate().localDateString())
Swift 3:
print(Date().localDateString())
一种更正时区日期的简单方法是使用 TimeZone.current.secondsFromGMT()
对于本地时间戳值,例如:
let currentLocalTimestamp = (Int(Date().timeIntervalSince1970) + TimeZone.current.secondsFromGMT())