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

Dun*_*n C 5 date nsdate swift

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

print(NSDate())
Run Code Online (Sandbox Code Playgroud)

要么

print(Date()) 
Run Code Online (Sandbox Code Playgroud)

(在Swift 3中)

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

2016-10-08 20:11:40 +0000
Run Code Online (Sandbox Code Playgroud)

我的日期是在错误的时区吗?如何修复日期以获得正确的时区?

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

(请注意,这个问题是一个"振铃",因此我可以提供一个简单的Swift 3/Swift 2 Date/NSDate扩展,让您可以轻松地在本地时区显示任何日期对象.

Dun*_*n C 17

NSDate(或Swift中的日期≥V3)没有时区.它记录了世界各地的瞬间.

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

我们通常会在当地时区考虑日期.

如果您使用日志记录日期

print(NSDate()) 
Run Code Online (Sandbox Code Playgroud)

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

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

e NSDate()
Run Code Online (Sandbox Code Playgroud)

这是一种痛苦.我个人希望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)
    }
}
Run Code Online (Sandbox Code Playgroud)

这样你就可以使用像这样的表达式Date().localString(),或者如果你只想打印时间,你可以使用Date().localString(dateStyle:.none)

编辑:

我刚刚发现NSDateFormatter(DateFormatter在Swift 3中)有一个类方法localizedString.这就是我的扩展程序所做的,但更简单,更干净.这是宣言:

class func localizedString(from date: Date, dateStyle dstyle: DateFormatter.Style, timeStyle tstyle: DateFormatter.Style) -> String
Run Code Online (Sandbox Code Playgroud)

所以你只需使用

let now = Date()
print (DateFormatter.localizedString(
  from: now, 
  dateStyle: .short, 
  timeStyle: .short))
Run Code Online (Sandbox Code Playgroud)

你几乎可以忽略下面的一切.


我创建了一个NSDate类(swift 3中的Date)的类,它有一个方法localDateString,用于在用户的本地时区显示日期.

以下是Swift 3表单中的类别:(filename 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)
  }
}
Run Code Online (Sandbox Code Playgroud)

并以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)
  }
}
Run Code Online (Sandbox Code Playgroud)

(如果您更喜欢不同的日期格式,则可以很容易地修改日期格式化程序使用的格式.在您需要的任何时区显示日期和时间也很简单.)

我建议在你的所有项目中放入适当的Swift 2/Swift 3版本的这个文件.

然后你可以使用

斯威夫特2:

print(NSDate().localDateString())
Run Code Online (Sandbox Code Playgroud)

斯威夫特3:

print(Date().localDateString())
Run Code Online (Sandbox Code Playgroud)