我已经尝试了一些类似的问题和答案,但仍然无法正常工作。我正在尝试转换2019-09-30T09:10:32.537244Z
func serverToLocal(date:String) -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-ddTHH:mm:ss.SSSSSSZ"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let localDate = dateFormatter.date(from: date)
return localDate
}
以上方法总是返回nil。我的日期格式有什么问题?
显然,关键问题是T
周围没有引号。
但是您可能不希望在每次调用此例程时都实例化一个新的日期格式程序(因为这在计算上非常昂贵)。因此,您应该将日期格式化程序另存为属性。这样,您无需为要转换为Date
的每个字符串实例化新的格式化程序。同样,此格式化程序可用于将日期转换回2019-09-30T09:10:32.537244Z
格式的字符串。
因此,与其他地方提供的建议相反,我将建议设置格式化程序的timeZone
。从字符串转换为日期时不需要此操作(因为日期字符串包含时区限定符),但是从日期转换为字符串时,确实需要日期格式化程序来指定时区,否则,日期将在设备的本地时区中。这样,格式化程序仍然可以将字符串转换为日期,也可以转换回字符串。
[同样,我建议将Z
替换为ZZZZZ
或仅替换X
。同样,仅当日期格式器也用于将日期转换回字符串时,这才是至关重要的(否则,结果字符串将在其中包含+0000
而不是Z
)。最重要的是,我发现使用X
/ ZZZZZ
意味着我永远不必担心它,当格式化程序将2019-09-30T09:10:32.537244Z
转换为Date
对象时,它就可以工作,反之亦然。
因此:
let iso8601DateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSX"
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.locale = Locale(identifier: "en_US_POSIX")
return formatter
}()
func serverToLocal(string: String) -> Date? {
return iso8601DateFormatter.date(from: string)
}
func localToServer(date: Date) -> String {
return iso8601DateFormatter.string(from: date)
}