1
votes

DateFormatter renvoie une date nulle pour certains utilisateurs indépendamment de la langue / isDaylightSavingTime / timezone

Nous utilisons Disqus pour nos fonctionnalités de commentaires. Son horodatage de commentaires est au format de date ISO8601, par exemple "2019-12-11T01: 45: 23" . Nous avons essayé d'analyser cette chaîne avec DateFormatter, configuré comme ceci:

let dateFormatter = ISO8601DateFormatter()
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
dateFormatter.formatOptions = [.withFullDate, .withTime, .withDashSeparatorInDate, .withColonSeparatorInTime]
return dateFormatter

Cela fonctionne bien pour la plupart des utilisateurs. Cependant, nous recevons des rapports pour un petit nombre d'utilisateurs indiquant que le formateur renvoie nil . Notre hypothèse initiale pour la cause est la suivante.

  • le format de date "aaaa-MM-jj'T'HH: mm: ss" était incorrect
  • paramètres régionaux
  • fuseau horaire
  • L'heure d'été rend le temps théoriquement inexistant
  • calendrier
  • ou autre chose ...

Tous sont des paramètres que nous utilisons pour configurer le DateFormatter. Nous avons essayé de nombreuses combinaisons, y compris celles obtenues à partir des rapports d'utilisateurs. Nous avons essayé la même date, les mêmes paramètres régionaux, le même fuseau horaire, le même calendrier et l'heure que dans les rapports d'utilisateurs.

  • paramètres régionaux: en_GB , fuseau horaire: Europe / Londres , calendrier: grégorien, isDaylightSavingTime: 1

  • paramètres régionaux: en_TR , fuseau horaire: Etc / GMT-3 , calendrier: grégorien, isDaylightSavingTime: 0

  • paramètres régionaux: es_MX , fuseau horaire: America / Mexico_City , calendrier: grégorien, isDaylightSavingTime: 1

  • paramètres régionaux: en_ID , fuseau horaire: Asie / Jakarta , calendrier: grégorien, isDaylightSavingTime: 0

Mais nous n'avons pas pu reproduire.

De plus, nous avons fait un autre test avec un tas de dates réparties tout au long de l'année. Et effectuez un test d'analyse masqué sur chaque utilisateur. Il semble que sur l'appareil qui renvoie une date nulle, il renvoie une valeur nulle pour CHAQUE date. La liste des chaînes de date ressemble à ceci ...

    [
      "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",
      ])

Nous avons découvert plus tard qu'il existe un autre formateur de date appelé ISO8601DateFormatter . Cela semble être plus approprié pour cette analyse. Voici comment nous l'avons configuré.

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

Avec ce ISO8601DateFormatter , le problème est résolu.

Mais je voulez savoir ce qui peut provoquer l'échec de DateFormatter sur certains appareils ? Y a-t-il d'autres facteurs que locale / isDaylightSavingTime / timezone dont je ne suis pas au courant?


1 commentaires

Avez-vous trouvé une solution? Je deviens nul indépendamment de quoi que ce soit aussi.


3 Réponses :


0
votes

Veuillez utiliser le format de date ISO8601 avec le fuseau horaire

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

Format:

"XXXX-XX-XX" = année, mois, jour, "T" = séparateur "XX: XX: XX.XXX" = heure, minute, secondes, millisecondes "Z" = indicateur de fuseau horaire pour le décalage zéro, alias UTC, GMT, heure zoulou

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


1 commentaires

C'est de Disqus, un service tiers, donc je n'ai aucun contrôle sur le format de la chaîne de date entrante.



0
votes

Pour toute personne confrontée à ce problème, ce qui a fonctionné pour moi était de définir dateFormatter.isLenient = true comme décrit ici: DateFormatter renvoyant nil pour une chaîne de date valide


0 commentaires

1
votes

S'agit-il du paramètre de l'utilisateur pour une horloge sur 12 heures ou sur 24 heures?

iOS peut modifier la chaîne de format d'un formateur de date pour qu'elle corresponde aux paramètres de l'utilisateur. La locale en_US_POSIX est recommandée pour les formats fixes < / a> pour empêcher les changements de format dus aux paramètres utilisateur.


0 commentaires