来自字符串 swift 的日期格式化程序

Date formatter from string swift

我需要像这样 2020.03.18 00:00 在日期中转换此字符串 2020-03-18T00:00:00 当我尝试像这样转换时,我的应用程序崩溃了。

public extension String {

    var dateValue: Date {
        let formatter = DateFormatter()
        formatter.timeZone = .none
        formatter.dateFormat = "yyyy-MM-dd HH:mm"
        return formatter.date(from: self)!
    }

}

有什么想法吗?

您的日期格式化程序需要包含 "T"

dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'"

问题在于此代码使用的 dateFormat 字符串 yyyy-MM-dd HH:mm,但这不是实际输入的字符串。是yyyy-MM-dd'T'HH:mm:ss。因此向 Date 对象的转换失败,强制解包将导致它崩溃。

相反,我建议使用一种格式化程序将 2020-03-18T00:00:00 的 ISO8601 格式转换为 Date 对象。如果您随后想要 2020.03.18 00:00 格式的字符串,您将有一个单独的格式化程序。

在 ISO8601 日期字符串中没有明确时区的情况下,假定为本地时区。所以根本不要指定 timeZone 属性。 (通常唯一指定它的情况是 Zulu/GMT/UTC,即 TimeZone(secondsFromGMT: 0)。)

例如

let iso8601Formatter = DateFormatter()
iso8601Formatter.locale = Locale(identifier: "en_US_POSIX")
iso8601Formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"

let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy.MM.dd HH:mm"

func convert(input: String) -> String? {
    guard let date = iso8601Formatter.date(from: input) else { return nil }
    return formatter.string(from: date)
}

let result = convert(input: "2020-03-18T00:00:00") // "2020.03.18 00:00"

请注意,格式化程序的实例化(以及 dateFormat 字符串的更改)是众所周知的计算密集型过程,这就是我创建这些格式化程序属性而不是局部变量的原因。很明显,你可以随意命名它们并将它们放在任何你想要的地方,但要确保避免重复实例化这些格式化程序或更改 dateFormat 字符串。