DateFormatter对于某些用户返回零日期,而与语言环境/ isDaylightSavingTime /时区无关

时间:2019-05-02 07:10:27

标签: ios nsdateformatter

我们将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 /时区之外,我是否不知道其他因素?

3 个答案:

答案 0 :(得分:0)

请使用带时区的ISO8601日期格式

  "2019-12-11T01:45:23.000Z"

格式:

“ XXXX-XX-XX” =年,月,日, “ T” =分隔符 “ XX:XX:XX.XXX” =小时,分钟,秒,毫秒 “ Z” =零时差的时区指示符,又称UTC,GMT和Zulu时间

 let dateFormatter = DateFormatter()
 dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
 dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
 return dateFormatter

答案 1 :(得分:0)

对于仍然面临此问题的任何人,对我有用的是设置dateFormatter.isLenient = true,如下所述:DateFormatter returning nil for a valid Date string

答案 2 :(得分:0)

用户设置的是12小时还是24小时制吗?

iOS可以更改日期格式器的格式字符串以匹配用户的设置。区域设置en_US_POSIXrecommended for fixed formats,以防止由于用户设置而导致格式更改。