时区日期格式问题
Posted
技术标签:
【中文标题】时区日期格式问题【英文标题】:TimeZone Date Formatting Issue 【发布时间】:2020-02-23 17:19:20 【问题描述】:我正在尝试从具有多个时区的字符串中获取日期,如果 API 返回带有 CST
或 UTC
之类缩写的区域,则它可以正常工作,但如果返回 EET
则会失败
let timeString = "17:32 (EET)"
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm (zzz)"
let time = formatter.date(from: timeString) // return nil
知道可能是什么问题吗?!
【问题讨论】:
【参考方案1】:可能是因为有多个时区与时区缩写匹配,或者日期格式化程序的默认日期(1 月 1 日)与使用的时区缩写的夏令时不匹配。并非所有国家/地区都使用夏令时,它可能随时更改。检查此link。这可能也会发生在所有非美国时区缩写上。例如CST
它也用于"China Standard Time"
和"Chicago Standard Time"
。您可以将日期格式化程序属性 isLenient
设置为 true 以解决该问题。请注意,这将导致日期为 2000 年 1 月 1 日,并且时区偏移可能不正确。如果您可以控制字符串输入,则应使用时区标识符而不是其缩写以避免歧义。在解析固定日期格式时,您还应该将日期格式化程序的区域设置为 "en_US_POSIX"
,以避免日期格式化程序反映用户设备区域设置和设置:
let timeString = "17:32 (EET)"
let formatter = DateFormatter()
formatter.locale = .init(identifier: "en_US_POSIX")
formatter.dateFormat = "HH:mm (zzz)"
formatter.isLenient = true
let date = formatter.date(from: timeString) // "Jan 1, 2000 at 1:32 PM" "BRT Brazilian Standard Time"
所以你应该使用"GMT+2"
或"GMT-3"
以避免歧义,或者我已经建议使用其标识符"HH:mm (VV)"
即"Europe/Athens"
或"America/Sao_Paulo"
【讨论】:
谢谢Leo,你的回答很清楚。我认为我遇到的问题与 API 更相关,因为响应因用户的时区而异。因此,我试图找到一种适用于任何时区的解决方案,而无需修复用户时区的本地。如果这可能有帮助,或者您对此有任何建议,我将检查是否可以在响应中发送用户的时区。再次感谢! @AhmedM.Hassan 欢迎您。正如您在我发布的链接中看到的那样,日期格式化程序没有足够的信息来推断正确的时区,因为它取决于国家/地区的夏令时。有多种情况,因此结果将是不可预测的。这就是它返回 nil 的原因。您还可以设置日期格式化程序的 defaultDate 和日历来帮助它解析您的日期。 完美..再次感谢?以上是关于时区日期格式问题的主要内容,如果未能解决你的问题,请参考以下文章
C# DateTime 将日期字符串格式化为带时区的日期格式