一尘不染

NSDate()或Date()显示错误的时间

swift

当我尝试记录当前日期时:

print(NSDate())

要么

print(Date())

(在Swift 3中)

或任何日期对象,它显示错误的时间。例如,现在大约是16:12,但上面显示的是

2016-10-08 20:11:40 +0000

我的日期在错误的时区吗?如何确定我的日期具有正确的时区?

为什么会这样,我该如何解决?如何在打印语句或调试器中轻松地在本地时区显示任意日期?

(请注意,这个问题是一个“铃声”,因此我可以提供一个简单的Swift 3 / Swift 2 Date /
NSDate扩展名,使您可以轻松地显示本地时区中的任何日期对象。


阅读 244

收藏
2020-07-07

共1个答案

一尘不染

NSDate(或Swift≥V3中的Date)没有时区。它记录了世界各地的即时时间。

在内部,日期对象在格林威治标准时间(又称为UTC)中记录自“纪元日期”(即2001年1月1日午夜)以来的秒数。

我们通常会想到本地时区中的日期。

如果您使用

print(NSDate())

系统显示当前日期,但以UTC /格林威治标准时间表示。因此,唯一看起来正确的地方就是那个时区。

如果发出debugger命令,则在调试器中也会出现相同的问题

e NSDate()

真痛苦 我个人希望iOS / Mac OS使用用户的当前时区显示日期,但不显示。

编辑2:

我以前使用本地化字符串的一项改进(使它更易于使用)是创建Date该类的扩展:

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)

编辑:

我刚刚发现NSDateFormatterDateFormatter在Swift
3中)有一个类方法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类的类别(swift 3中的Date),该类别具有一个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版本。

然后,您可以使用

斯威夫特2:

print(NSDate().localDateString())

斯威夫特3:

print(Date().localDateString())
2020-07-07