时区日期格式问题

Posted

技术标签:

【中文标题】时区日期格式问题【英文标题】:TimeZone Date Formatting Issue 【发布时间】:2020-02-23 17:19:20 【问题描述】:

我正在尝试从具有多个时区的字符串中获取日期,如果 API 返回带有 CSTUTC 之类缩写的区域,则它可以正常工作,但如果返回 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 将日期字符串格式化为带时区的日期格式

带有特定格式时区的 db 日期时间

涉及日期 fns 格式()的时区问题

如何在java中使用日光将日期格式从一个时区转换为另一种时区[重复]

根据时区自定义格式的javascript日期时间[重复]