【问题标题】:Swift NSDate ISO 8601 formatSwift NSDate ISO 8601 格式
【发布时间】:2017-02-01 22:02:44
【问题描述】:

我正在研究 Swift 中的日期格式,并尝试将字符串日期转换为 NSDate 并将 NSSate 转换为字符串日期(ISO 8601 格式)。

这是我的代码

let stringDate = "2016-05-14T09:30:00.000Z" // ISO 8601 format

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" // ISO 8601

let date = dateFormatter.dateFromString(stringDate)
print("Date = \(date)") // Output is 2016-05-14 16:30:00 +0000

// Again converting it date to string using stringFromDate
print("\(dateFormatter.stringFromDate(date!))") // 2016-05-14T09:30:00.000Z

我试图了解为什么我会收到 GMT 格式的 NSDate(从 09:30 到 16:30 时间增加 7 小时)?

如果我将该 NSDate date 变量转换为字符串,那么我将得到原始字符串日期。这里发生了什么?

【问题讨论】:

  • 您的目标是 macOS 10.12 或更高版本吗?有一个新课程 ISO8601DateFormatter 可能会有所帮助。
  • 没有。我正在使用 macOS 10.11.6 和 iOS 9。我将检查这个类 ISO8601DateFormatter。谢谢。

标签: ios swift nsdate nsdateformatter iso8601


【解决方案1】:

如果您的目标是 iOS 11.0+ / macOS v10.13+ (High Sierra),您可以简单地将 ISO8601DateFormatterwithInternetDateTimewithFractionalSeconds 选项一起使用,如下所示:

let stringDate = "2016-05-14T09:30:00.000Z" // ISO 8601 format

let iso8601DateFormatter = ISO8601DateFormatter()
iso8601DateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let date = iso8601DateFormatter.date(from: stringDate)

print("Date = \(date)") // Output is 2016-05-14 09:30:00 +0000

要在旧系统上使用 DateFormatter,请参阅 Apple Tech Note QA1480

如果您使用的是固定格式的日期,则应首先设置 日期格式化程序的区域设置为适合您的固定 格式。在大多数情况下,选择的最佳语言环境是“en_US_POSIX”,一个 专门为产生美国英语结果而设计的语言环境 无论用户和系统偏好如何。 “en_US_POSIX”也是 时间不变(如果美国在未来的某个时间点改变 它格式化日期的方式,“en_US”将改变以反映新的 行为,但“en_US_POSIX”不会),以及机器之间 (“en_US_POSIX”在 iOS 上的工作方式与在 OS X 上的工作方式相同,并且因为它 在其他平台上也可以)。

这里是 Swift 5 的 sn-p,基于提供的示例代码:

let stringDate = "2016-05-14T09:30:00.000Z" // ISO 8601 format

let rfc3339DateFormatter = DateFormatter()
rfc3339DateFormatter.locale = Locale(identifier: "en_US_POSIX")
rfc3339DateFormatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSS'Z'"
rfc3339DateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
let date = rfc3339DateFormatter.date(from: stringDate)

print("Date = \(date)") // Output is 2016-05-14 09:30:00 +0000

【讨论】:

    【解决方案2】:

    您的格式字符串错误。您指示文字 Z 而不是“Z 作为祖鲁时间”。去掉单引号:

    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
    dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
    

    您应该始终将语言环境指定为en_US_POSIXwhen parsing Internet time。这一点很容易被忽视,以至于 Apple 在 OS X v10.12 (Sierra) 中创建了 ISO8601DateFormatter 类。

    【讨论】:

      【解决方案3】:

      对于 Swift 3.0+,您可以使用 NSISO8601DateFormatterISO8601DateFormatter

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-01
        • 2013-07-07
        • 2016-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多