Swift:将 ISO8601 转换为日期

Posted

技术标签:

【中文标题】Swift:将 ISO8601 转换为日期【英文标题】:Swift: Converting ISO8601 to Date 【发布时间】:2020-07-08 14:19:05 【问题描述】:

尝试将ISO8601 格式的String 转换为Date 并获得nil

let dateString = "2020-06-27T16:09:00+00:00" // ISO8601

我尝试了两种不同的方法:

import Foundation
let df = DateFormatter()
df.timeZone = TimeZone.current
df.locale = Locale(identifier: "en_US_POSIX")
df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let toDate = df.date(from: dateString)

print("toDate \(String(describing: toDate))") // output: toDate nil

我也试过了:

import Foundation
let isoDateFormatter = ISO8601DateFormatter()
isoDateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
isoDateFormatter.formatOptions = [
    .withFullDate,
    .withFullTime,
    .withDashSeparatorInDate,
    .withFractionalSeconds]
let isoDate = isoDateFormatter.date(from: dateString)
print("isoDate \(isoDate)") // output: isoDate nil

String 中的日期格式为 ISO8601。我在这里验证了它:http://jsfiddle.net/wq7tjec7/14/

不知道我做错了什么。

【问题讨论】:

您以日期格式指定 SSS,或为 ISO 格式化程序指定 withFractionalSeconds,但您的日期字符串没有有小数秒... 提示:let dateStr = isoDateFormatter.string(from: Date()) 并检查它是否是预期的输出,将其与当前字符串输入进行比较。 【参考方案1】:

正如@Martin 在 cmets 中提到的,您的日期在字符串末尾没有小数秒。 这是正确的格式:

df.dateFormat = "yyyy-MM-dd'T'HH:mm:SSxxxxx"

或从isoDateFormatterformatOptions 数组中删除withFractionalSeconds,如下所示:

isoDateFormatter.formatOptions = [
    .withFullDate,
    .withFullTime,
    .withDashSeparatorInDate]

更新:正如@Leo 在 cmets 中提到的,这里使用Z 表示时区格式是错误的,它需要改为xxxxx

【讨论】:

这是因为您指定输入有小数秒 @user1107173 您不应该将 DateFormatter 的时区设置为当前。日期字符串中的Z 表示日期时区为UTC。您应该将其设置为 TimeZone(secondsFromGMT: 0) 并在设置其他属性之前设置语言环境 另请注意,时区表示为 +00:00,而如果您使用 Z,则表示为 +0000。您需要使用xxxxx 而不是Z。所以首先将语言环境设置为"en_US_POSIX",然后将时区设置为TimeZone(secondsFromGMT: 0),并将日期格式设置为"yyyy-MM-dd'T'HH:mm:ss.SSSxxxxx"。这样,如果您从要解析的日期创建一个字符串,它将与您的输入完全相同。 @Frankenstein 在此处使用Z 表示时区是错误的。它将使用Z 而不是+00:00 来表示UTC 时区,而原始日期字符串则没有。所以这将创建一个类似2020-07-08T16:33:37.228Z而不是2020-07-08T16:33:37.228+00:00的字符串 有关 dateFormat 时区设置的更多信息,您可以查看i.stack.imgur.com/lkYVY.png。 OP 需要的时区是“没有 Z 为 0”的时区

以上是关于Swift:将 ISO8601 转换为日期的主要内容,如果未能解决你的问题,请参考以下文章

一种将当前日期时间转换为 ISO 8601 格式的优雅方法 [重复]

将 ISO 8601 日期时间字符串转换为 **Date** 对象时,如何将日期时间重新定位到当前时区?

Python - 将日期的字符串表示形式转换为 ISO 8601

如何配置 web api 的 json 序列化器将日期时间转换为 ISO 8601 格式?

如何在 PHP 中将日期时间转换为 ISO 8601

将日期对象转换为ISO 8601格式的字符串