ios - 无论语言环境/isDaylightSavingTime/时区如何,DateFormatter 都会为某些用户返回 nil 日期
问题描述
我们将 Disqus 用于我们的评论功能。其注释时间戳采用 ISO8601 日期格式,例如"2019-12-11T01:45:23"
. 我们尝试使用 DateFormatter 解析该字符串,设置如下:
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
return dateFormatter
它适用于大多数用户。但是,我们会收到格式化程序返回的少量用户的报告nil
。我们对原因的初步假设如下。
- 日期格式“yyyy-MM-dd'T'HH:mm:ss”错误
- 语言环境
- 时区
- 夏令时使得理论上不存在一些时间
- 日历
- 或者是其他东西...
它们都是我们用来设置 DateFormatter 的参数。我们尝试了许多组合,包括我们从用户报告中获得的组合。我们尝试了与用户报告中相同的日期、区域设置、时区、日历和时间本身。
语言环境:
en_GB
, 时区:Europe/London
, 日历: gregorian, isDaylightSavingTime: 1语言环境:
en_TR
, 时区:Etc/GMT-3
, 日历: gregorian, isDaylightSavingTime: 0语言环境:
es_MX
, 时区:America/Mexico_City
, 日历: gregorian, isDaylightSavingTime: 1语言环境:
en_ID
, 时区:Asia/Jakarta
, 日历: gregorian, isDaylightSavingTime: 0
但我们无法重现。
此外,我们还进行了另一项测试,其中包含全年分布的大量日期。并对每个用户进行隐藏解析测试。似乎在返回 nil 日期的设备上,它在每个日期都返回 nil。日期字符串列表如下所示...
[
"2019-01-11T01:45:23",
"2019-02-11T01:45:23",
"2019-03-11T01:45:23",
"2019-04-10T01:45:23",
"2019-04-11T01:45:23",
"2019-04-12T01:45:23",
"2019-05-11T01:45:23",
"2019-06-11T01:45:23",
"2019-07-11T01:45:23",
"2019-08-11T01:45:23",
"2019-09-11T01:45:23",
"2019-10-11T01:45:23",
"2019-11-11T01:45:23",
"2019-12-11T01:45:23",
])
我们后来发现还有另一个日期格式化程序,叫做ISO8601DateFormatter
. 似乎更适合这种解析。这是我们如何设置它。
let dateFormatter = ISO8601DateFormatter()
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
dateFormatter.formatOptions = [.withFullDate, .withTime, .withDashSeparatorInDate, .withColonSeparatorInTime]
return dateFormatter
有了这个ISO8601DateFormatter
,问题就解决了。
但我仍然想知道什么会导致DateFormatter
某些设备失败?除了我不知道的语言环境/isDaylightSavingTime/时区之外,还有其他因素吗?
解决方案
是用户设置的 12 小时制还是 24 小时制?
iOS 可以更改日期格式化程序的格式字符串以匹配用户的设置。建议将语言环境en_US_POSIX
用于固定格式,以防止由于用户设置而导致格式更改。
推荐阅读
- c# - 应跨越 4 列的 GridView 数据全部显示在第一列下
- java - 使用可变参数时是否创建了新数组?
- fullcalendar - FullCalendar - 从数据库数据中显示用户的工作日程
- python - Python:从值中获取对应的键
- numpy - fromfile 可以省略字段吗?
- jquery - 在jQuery中排除带有前缀的元素及其所有子元素
- r - 只能得到股票指数R的5天数据
- xml - 如何将非 RDF XML 文件加载到 Virtuoso 中?
- ember.js - 在 Ember 中将计算属性添加到 Route.Extend
- sockets - HTTP ChunkSize 是如何选择的?