DateFormatter возвращает нулевую дату для некоторых пользователей независимо от локали / isDaylightSavingTime / timezone - PullRequest
0 голосов
/ 02 мая 2019

Мы используем 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.Наша первоначальная гипотеза для причины заключается в следующем.

  • формат даты «гггг-ММ-дд'Т'ХЧ: мм: сс» был неправильным
  • языковой стандарт
  • часовой пояс
  • летнее время теоретически не существует
  • календарь
  • или что-то еще ...

Все ониПараметры, которые мы используем для настройки DateFormatter.Мы перепробовали много комбинаций, включая те, которые мы получили из пользовательских отчетов.Мы использовали ту же дату, локаль, часовой пояс, календарь и само время, что и в пользовательских отчетах.

  • языковой стандарт: en_GB, часовой пояс: Europe/London, календарь: григорианский, isDaylightSavingTime: 1

  • языковой стандарт: en_TR, часовой пояс: Etc/GMT-3, календарь: григорианский, isDaylightSavingTime: 0

  • языковой стандарт: es_MX, часовой пояс: America/Mexico_City, календарь: григорианский, isDaylightSavingTime: 1

  • языковой стандарт: en_ID, часовой пояс: Asia/Jakarta, календарь: gregorian, isDaylightSavingTime: 0

Но мы не смогли воспроизвести.

Кроме того,мы сделали еще один тест с кучей дат, распространяющихся в течение года.И выполнить скрытый анализ парсинга для каждого пользователя.Похоже, на устройстве, которое возвращает ноль даты, он возвращает ноль для КАЖДОЙ даты.Список строк даты выглядит следующим образом ...

    [
      "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потерпеть неудачу на каком-либо устройстве ?Есть ли другие факторы, кроме locale / isDaylightSavingTime / timezone, о которых я не знаю?

1 Ответ

0 голосов
/ 02 мая 2019

Пожалуйста, используйте формат даты ISO8601 с часовым поясом

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

Формат:

"XXXX-XX-XX" = год, месяц, день, "T" = разделитель "XX: XX: XX.XXX "= часы, минуты, секунды, миллисекунды" Z "= указатель часового пояса для смещения нуля, или UTC, GMT, время Зулу

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