Maison >Java >javaDidacticiel >Cas Edge dans le développement d'applications et de backend - Dates et heures

Cas Edge dans le développement d'applications et de backend - Dates et heures

WBOY
WBOYoriginal
2024-08-09 09:23:32915parcourir

Introduction

Vous pensez peut-être qu'il est facile de gérer les dates et l'heure. Nous avons une minute qui dure 60 secondes, une heure de 60 minutes, une journée de 24 heures, une semaine de 7 jours, un mois de 28 à 31 jours, et ainsi de suite.

Il n'est sûrement pas nécessaire d'être sorcier ici…

Eh bien, rien ne pourrait être plus éloigné de la vérité !

Nous montrerons les pièges et les écueils liés à la date et à l'heure que vous pouvez rencontrer lors du développement d'applications et du backend.

Unités de mesure

Commençons par les unités de mesure, des plus petites aux plus grandes.

Secondes et millisecondes

La plus petite unité utilisée quotidiennement est une seconde. C'est aussi la base du temps Unix.

Cependant, dans certains langages de programmation, comme Java, l'unité la plus courante est la milliseconde (1/1000 de seconde), comme par exemple par la méthode System.currentTimeMillis().

Cette divergence peut conduire à de nombreuses erreurs.

Si vous recevez la valeur numérique de l'extérieur de votre système, il se peut que l'unité de mesure utilisée ne soit pas claire au premier coup d'œil, même après avoir lu la documentation !

Regardez le champ DATE dans les colonnes du fournisseur de contenu SMS et MMS (base de données). Les deux documents disent seulement :

  • La date à laquelle le message a été reçu.

  • Type : ENTIER (long)

Cependant, le SMS utilise des millisecondes tandis que le MMS utilise des secondes. Surpris? Eh bien, cela peut arriver, surtout si ces API sont conçues par des personnes différentes.

Comment gérer des cas comme ceux-ci ? Et comment pouvez-vous les éviter ?

Heureusement, nous pouvons formuler plusieurs règles générales :

  1. Assurez-vous toujours du format des données entrantes.
    Vérifiez-le dans la nature car la documentation peut être incorrecte et/ou obsolète. Il est généralement très facile de repérer une erreur, comme une date 50 000 ans trop éloignée dans le futur, lorsque vous la recherchez lors du développement. Ce résultat se produit lorsque les millisecondes sont traitées comme des secondes, par exemple.

  2. Si vous avez une influence du côté qui envoie les valeurs (par exemple, le système est en cours de conception et personne ne l'utilise encore), pensez aux formats textuels standardisés.
    Ici, je mets l'accent sur la normalisation (par exemple ISO 8601) et non sur certains formats personnalisés (nous élargirons ce sujet plus tard). Après quelques années, personne de l'équipe d'origine ne peut plus travailler sur ce projet, et le format textuel est simple à comprendre pour les nouveaux développeurs, car ils n'ont pas besoin de consulter la documentation.
    Les formats numériques peuvent toutefois être meilleurs dans les appareils dont les performances sont critiques.

  3. **Utilisez des classes dédiées pour traiter les valeurs de date/heure/durée plutôt que les entiers bruts.
    **Dans le monde Java, nous avons un package java.time avec de nombreuses classes utiles comme Instant ou Duration. S'il existe un entier appelé par exemple. eventDuration, on ne sait pas s'il stocke des secondes ou des millisecondes - ou peut-être même des jours ?

  4. Si vous devez gérer des valeurs brutes (entiers, longs, etc.) que vous ne pouvez pas simplement refactoriser entièrement, comme le code existant, incluez l'unité de mesure avec les noms de variables/champs .
    Par exemple, eventDurationSeconds est sans ambiguïté.

Secondes intercalaires

Vous avez probablement entendu parler des années bissextiles. Ils diffèrent des cours « normaux » en étant plus longs d’un jour. Nous avons aussi des secondes intercalaires !

Sont-elles plus longues que les secondes non intercalaires ?

Eh bien, ça dépend !

Tout d’abord, commençons par un peu de théorie. La Terre ralentit ; en réalité, ce n’est pas une déclaration philosophique mais un fait scientifiquement prouvé. C'est ce qu'on appelle le delta-T.

OK, alors qu'est-ce que cela signifie en pratique pour nous ? Eh bien, nos unités de mesure du temps ont une longueur standardisée. L'unité de base est la seconde, définie comme :

La durée de 9 192 631 770 périodes du rayonnement correspondant à la transition entre les deux niveaux hyperfins de l'état fondamental non perturbé fondamental de l'atome de césium 133. (source : bipm.org)

Cette durée est constante et informe toutes les autres unités dérivées des secondes, par exemple. une minute comprend 60 secondes, une heure dure 60 minutes (3 600 secondes) et ainsi de suite.

Cependant, si la Terre ralentit (et que la journée s'allonge), nous devons d'une manière ou d'une autre s'adapter à ce ralentissement pour garantir que le temps mesuré par nos unités soit cohérent avec la réalité. Cela se fait en insérant des secondes supplémentaires – les secondes intercalaires.

Il n'y a que 2 créneaux disponibles pour les secondes intercalaires dans l'année : toute fin juin et décembre. La toute fin signifie le dernier jour (respectivement le 30 ou le 31) juste après 23:59:59 UTC (donc l'heure locale varie).

Après ces dernières secondes normalement, la seconde intercalaire supplémentaire est insérée avant de passer au jour suivant. Ainsi, nous pouvons avoir 23:59:60 (61 secondes dans une minute — en comptant à partir de‌ 0).

Edge Cases in App and Backend Development — Dates & Times

En raison du fait que le ralentissement n'est pas constant, les secondes intercalaires sont insérées de manière irrégulière. La dernière (au moment de la rédaction de cet article, en avril 2021) a eu lieu en décembre 2016, soit il y a plus de 4 ans. Cependant, l'avant-dernière date de juin 2015, avec seulement un an et demi de différence entre les deux.

Dans certains endroits où nous pouvons régler l'heure, comme les horloges murales physiques ou certaines API de framework, il peut être impossible d'observer et/ou de régler l'heure avec la seconde intercalaire.

Par exemple, l'ancienne classe Java Date prend en charge même les secondes intercalaires doubles — la plage s'étend de 0 à 61, donc 62 secondes sont possibles !

Cependant, la classe Instant moderne du package java.time n'expose pas les secondes intercalaires aux programmeurs. La seconde intercalaire s'étend de manière égale sur les 1 000 dernières secondes de la journée (ces secondes sont plus longues).

Notez qu'en théorie, la seconde intercalaire peut être également négative. Mais cela ne s'est pas produit jusqu'à présent.

Cela signifie qu'une minute peut comprendre 59 secondes, ce qui peut entraîner d'énormes problèmes. Par exemple, si une action est programmée pour se produire à 23:59:59.001 et qu'il s'avère que l'heure souhaitée n'existe pas…

Heureusement, de manière analogue à la répartition des secondes visibles, il peut également être réduit pour être complètement transparent pour les programmeurs.

On sait que la 61ème seconde peut exister, mais qu'en est-il de la 62ème ? Eh bien, la documentation dit :

Il est extrêmement improbable que deux secondes intercalaires se produisent dans la même minute, mais cette spécification suit les conventions de date et d'heure pour ISO C.

En effet, dans la spécification C, nous avons une plage [0, 61]. Mais pourquoi ? La même question dérangeait Paul Eggert, l'auteur de tzdata (base de données de fuseaux horaires) en 1992. Comme on peut le lire dans l'archive :

*« Parce qu'il y avait en réalité deux secondes intercalaires dans une année (à des jours différents), et quelqu'un du comité ANSI C pensait qu'elles arrivaient le même jour. » *— source groups.google.com.

Cette légère erreur d'interprétation, survenue il y a plusieurs décennies, est encore visible aujourd'hui car la nouvelle implémentation doit être rétrocompatible avec ces normes.

Passons à d'autres cas extrêmes dans le développement d'applications et de backend.

Les jours

Les minutes et les heures n’impliquent aucun cas inattendu donc passons aux jours.

Qu'est-ce qu'un jour ? Ça dépend! On peut dire que cela dure 24 heures de 00:00:00 à 23:59:60 (y compris la seconde intercalaire ? ). Eh bien, que ce soit généralement le cas, la journée ne dure pas toujours 24 heures, puisqu'elle peut être 23, 25 ou même 21 et 27 ! Pourquoi ces valeurs ? La réponse est…

Heure d'été

Ce qu'on appelle l'heure d'été ou « heure d'été » avance les horloges pendant les mois les plus chauds dans le but de réduire la consommation d'énergie. L’obscurité commence plus tard qu’à l’heure « normale » (hors heure d’été). De nos jours, la nécessité de l’heure d’été est discutable car elle présente de nombreux inconvénients. Certains pays ont même récemment cessé d'observer l'heure d'été (par exemple la Russie en 2014) à cause d'eux.

Quels sont les problèmes avec l'heure d'été ? Voyons !

Je n'aborderai pas des choses comme les réglages manuels oubliés des horloges murales ou le retard des transports publics, mais je me concentrerai plutôt sur les aspects liés au backend et au développement d'applications.

Vous pensez peut-être qu'à l'heure d'été, on avance les horloges d'une heure. Ce n'est pas toujours le cas ! Il y a des endroits dans le monde où la différence est de 3 heures (comme Casey) ou de 30 minutes (comme l'île Lord Howe).

L'heure d'été, pas exactement comme son nom l'indique, peut également couvrir une partie du printemps ou de l'automne mais, en général, elle est liée aux mois les plus chauds. À son tour, cela dépend de l'hémisphère.

Alors qu'en Europe il y a un été, en Australie il y a un hiver et vice versa. Donc, pour mettre cela en perspective, l’heure d’été australienne tombe pendant l’hiver européen !

De plus, la définition de l’été en termes de temps dépend des juridictions. Dans tous les pays de l'Union européenne, le changement d'heure se fait au même moment donc le décalage horaire entre Berlin et Londres, par exemple, est toujours de 1 heure, que l'on soit en été ou en hiver.

Mais considérons le décalage horaire entre Sydney et Londres. Dans ce cas, cela dépend du jour de l’année ! C'est parce que Sydney commence et arrête d'observer l'heure d'été à des dates différentes de celles de Londres.

Edge Cases in App and Backend Development — Dates & Times
Inspiration : timeanddate.com

Par exemple, à partir de janvier, nous avons 10 heures de différence. Sydney observe l'heure d'été à ce moment-là, mais pas Londres. Fin mars, Londres commence à observer l'heure d'été, tandis que l'état de Sydney reste inchangé, la différence se réduit donc à 9 heures. Puis en avril, Sydney cesse d’observer l’heure d’été, nous disposons donc de 8 heures. Nous avons 3 compensations différentes. La question sur le décalage horaire entre Sydney et Londres a donc 3 réponses !

Des pays comme les États-Unis, les membres de l’UE ou l’Australie ont, disons, des juridictions stables en ce qui concerne l’heure d’été. On sait à l’avance quand la transition aura lieu. Cependant, ce n’est pas toujours le cas, car certains pays peuvent modifier leurs lois de manière inattendue. Par exemple en 2020 aux Fidji, les règles ont changé avec l'annonce arrivée seulement quelques mois avant.

Des situations encore plus compliquées se produisent dans certains pays islamiques qui observent officiellement le Ramadan. S'ils observent également l'heure d'été, cette dernière pourra être… suspendue (pour la période du Ramadan).

Cela signifie que la transition vers l'heure d'été peut se produire plus d'une fois (aller-retour) et même plusieurs fois par an. De plus, le Ramadan est calculé selon le calendrier islamique (lunaire). La prédiction est utilisée pour calculer les dates limites du Ramadan et elle peut ne pas être toujours exacte. Par exemple, en Palestine en 2020, la prévision s’avère courte d’environ une semaine. Les modifications n'ont été appliquées que quelques jours à l'avance.

La plupart des systèmes utilisent la base de données IANA Time Zone comme source des moments de transition DST. Il y a généralement quelques mises à jour chaque année dans cette base de données.

Notez que la gestion de l'heure d'été peut avoir un impact sur les algorithmes. Considérons quelques scénarios typiques.

Si nous avons une alarme programmée à une heure murale particulière (par exemple 02h30), il peut s'avérer qu'un tel moment n'existe pas (lorsque l'heure passe de 02h00 à 03h00 pendant la transition DST) ou il existe deux fois lorsque l'heure est modifiée à l'envers. Si, par exemple, la sauvegarde n’est pas effectuée ou si les médicaments ne sont pas administrés ou sont administrés deux fois, les conséquences peuvent être terribles.

Un autre effet courant consiste à déclencher des changements d'heure cycliques si l'utilisateur se trouve dans le fuseau horaire observant l'heure d'été. Par exemple, si vous planifiez le lancement d'un build sur bitrise.io à 10h00, il peut soudainement commencer à se déclencher à 11h00.

Cela se produit parce que la logique sous le capot ne connaît pas l'heure d'été et que l'heure visible par l'utilisateur n'est calculée que lors du rendu de l'interface utilisateur. L'instant absolu est toujours le même mais l'heure visible par l'utilisateur change en fonction de l'heure d'été. Habituellement, ce n'est pas ce à quoi les clients s'attendent.

Les semaines

Quel est le premier jour de la semaine ? Si vous vivez en Europe, vous diriez probablement lundi. Aux États-Unis, ce sera dimanche et dans les pays arabes, samedi. Ces faits peuvent avoir un impact sur la construction d’algorithmes et/ou le rendu des calendriers.

Qu'en est-il du numéro de semaine dans l'année ? Vous pensez peut-être que tout commence le 1er janvier.

Comme vous l'avez peut-être deviné, ce n'est pas toujours le cas !

Selon la norme ISO, la 1ère semaine de l'année doit contenir le jeudi. Par exemple, en 2021, le 1er janvier est un vendredi et appartient donc à la dernière semaine de l'année précédente. La première semaine de 2021 a commencé le 4 janvier ! Cependant, toutes les régions n'utilisent pas la même règle que la norme ISO en la matière.

Les mois

Le calendrier grégorien utilisé par la plupart des pays du monde compte 12 mois, de janvier à décembre. Cependant, d’autres types de calendrier peuvent comporter davantage de mois. Par exemple, le calendrier hébreu peut comporter 13 mois. Le 13ème (dans le monde informatique) s'appelle Undecimber.

Les années

Habituellement, l'année dure 365 jours. Cependant, chacune divisible par 4 (ex. 2020, 2024 etc.) est une année bissextile qui compte 366 jours (avec 29 jours en février au lieu des 28 normaux). Mais si elle est divisible par 100 (2100, 2200 etc.), ce n'est PAS une année bissextile. Mais ? s'il est divisible par 400 (2000, 2400 etc.) c'est une année bissextile.

Heureusement, vous n’êtes pas obligé (et ne devriez pas !) essayer de mettre en œuvre de telles distinctions vous-même. Vous devez utiliser des classes/fonctions de date, des bibliothèques bien connues du langage de programmation donné.

Il y avait de nombreux bugs spectaculaires dans des services bien connus liés à des calculs incorrects des années bissextiles. Il existe même un terme : problème des années bissextiles.

Les fuseaux horaires

L'heure locale dépend de la longitude. Alors qu’il est midi dans un endroit particulier, il est aussi minuit à l’autre bout du globe.

Il n'est pas pratique de régler les horloges en continu lorsque l'on voyage, c'est pourquoi le globe a été divisé en zones qui couvrent les zones ayant la même heure officielle locale.

Les limites des zones sont généralement égales aux frontières des pays dans le cas des petits pays ou de certaines régions géographiques dans les plus grands (comme l'Australie, les États-Unis ou la Russie).

Edge Cases in App and Backend Development — Dates & Times
Source : timeanddate.com

Pour des raisons politiques et économiques dans certains endroits, l'heure officielle diffère considérablement de l'heure « légitime » (en tenant uniquement compte de la longitude/heure du soleil). Par exemple, en Espagne, la zone est la même que dans la plupart des pays d'Europe centrale continentale plutôt qu'au Royaume-Uni, qui est plus proche selon la longitude.

La plupart des fuseaux horaires ont des décalages intégraux (la différence par rapport à UTC — une heure standard), par exemple. à Berlin +1 heure (+2 en heure d'été) ou -3 h à Buenos Aires (Argentine, pas d'heure d'été). Cependant, le décalage peut inclure des moitiés d'heures, par exemple. à Mumbai (Inde), nous avons +5h30 (pas d'heure d'été).

Si cela ne suffisait pas, les quarts sont également possibles, comme à Katmandou (Népal) nous avons +5h45 !

Heureusement, il n’existe plus de compensations plus fines au moment de la rédaction. Cependant, ils existaient dans le passé, comme +0:20 aux Pays-Bas.

Du fait que nous avons 24 heures sur les horloges, on peut penser qu'il s'agit aussi d'une gamme de décalages possibles. +12h00 et -12h00 combinés donnent 24.

Cependant, la distance temporelle la plus éloignée entre les fuseaux horaires est de 26 heures !

Cela est possible car nous avons un décalage de +14h00. Il a été adopté par plusieurs pays d'Océanie car ils sont plutôt liés à l'Australie, il est donc plus pratique d'avoir quelques heures de décalage que plus de 20, ce qui conduit à une autre date dans la plupart des cas.

Considérons un outil de recherche de correspondance aérienne. Dans le cas de vols aller-retour, les utilisateurs peuvent choisir les dates/heures de départ et de retour. Il peut être évident que l'heure de retour doit être postérieure au départ.

Bien sûr, cela ne pourrait pas être plus éloigné de la vérité !

Gardez à l'esprit que ces heures correspondent aux fuseaux horaires locaux.

Jetez un œil à cet exemple :

  1. Départ de Tokyo à 00h30 (offset +09h00) vers San Francisco (offset -07h00)

  2. Arrivée à San Francisco à 18h00, la veille en heure locale !

  3. Retour de San Francisco à 19h50 (encore précédent par rapport au départ initial)

Donc, vous pouvez aller quelque part et revenir hier. Voir cet exemple :

Edge Cases in App and Backend Development — Dates & Times

Dénomination du fuseau horaire

Un autre cas limite potentiel dans le développement d'applications/backend auquel vous pourriez être confronté est lié à la dénomination du fuseau horaire.

Vous remarquerez peut-être que nous pouvons appeler un fuseau horaire par son décalage, par exemple. +01:00 ou par son identifiant par exemple. Europe/Berlin. Notez que cette dernière notation offre de multiples avantages : elle contient des informations sur les transitions d'heure d'été (Berlin a un décalage de +02h00 en été) et elle contient également des données historiques.

Par exemple, les zones Europe/Varsovie et Europe/Berlin semblent aujourd'hui identiques. Ils ont tous deux des décalages égaux toute l'année, les transitions d'heure d'été se produisant également toujours aux mêmes moments.

Cependant, cela n’a pas toujours été le cas dans le passé ! Par exemple, en 1977, il n'y avait pas d'heure d'heure du tout à Berlin, mais Varsovie l'a observée du 3 avril au 25 septembre (complètement différent de ce que nous avons aujourd'hui).

Notez que les identifiants de fuseau horaire sont basés sur les noms de villes. Ceci est intentionnel car les frontières des pays sont susceptibles de changer beaucoup plus souvent que les noms de villes.

Par exemple, la Crimée est en fait passée de l'Ukraine à la Russie, mais les noms des villes restent inchangés. La zone Europe/Simferopol peut être utilisée peu importe si nous avons besoin de données actuelles ou historiques.

Jour vs nychthémère, période vs durée

Disons que quelque chose dure un jour. Ainsi, si cela commence à 09:15:00 alors nous pouvons ajouter 24 heures et obtenir l'heure de fin (09:15:00 le lendemain exclusivement, dans ce cas).

Eh bien, ce n'est pas toujours aussi simple ! Gardez à l’esprit que nous pouvons avoir une transition vers l’heure d’été lorsque l’horloge est artificiellement ajustée vers l’avant ou vers l’arrière. Cela signifie que la journée dure généralement 24 heures mais, parfois, elle peut atteindre 23, 25 ou même des valeurs plus étranges comme 27 ou 23 heures et demie (vous souvenez-vous de Casey et Lord Howe ?).

Il est important de ne pas traiter aveuglément les jours comme 24 heures lors de la mise en œuvre de la logique métier. Vous devez utiliser les API de date/heure appropriées pour cela. Par exemple, en Java, nous avons des classes distinctes :

  • Période, qui représente les jours calendaires — parfait pour des choses comme la validité de l'abonnement qui est mesurée en jours, mois ou années

  • Durée, qui représente le temps continu par exemple. 24 heures, quelle que soit la date indiquée sur le calendrier. Il est parfait pour mesurer la durée d'actions, telles que les déplacements ou le temps écoulé depuis le démarrage de l'appareil/du programme.

Certaines langues ont des mots distincts pour les états ensoleillés (en anglais — jour) et 24 heures consécutives (en anglais — nychthemeron, mais ce n'est pas couramment utilisé).

Représentation date/heure :

Edge Cases in App and Backend Development — Dates & Times
Source : xkcd.com

Lors de la communication avec d'autres systèmes, comme via l'API REST, il est important de se mettre d'accord sur les formats de données. Si la date affichée est le 12/10/2021, elle peut être au format américain (12 octobre) ou au format britannique (10 décembre).

Il est préférable d'utiliser une représentation sans ambiguïté !

Pour la date et l'heure, nous avons la norme ISO 8601. Notez que non seulement les dates et heures absolues sont standardisées, mais également les périodes. Il est également important d'utiliser le type approprié : local (pour représenter des données telles que les heures de déclenchement d'un réveil ou les dates de naissance) ou zoné (pour représenter des moments dans le temps, comme le début d'un événement ou la prise de photos).

Les formats personnalisés et non standardisés entraînent généralement de la confusion et des bugs, alors évitez-les.

Lors de l'affichage de la date et de l'heure dans l'interface utilisateur, vous devez prendre en compte les paramètres régionaux de l'utilisateur. Le format affiché dépend de la langue et de la région. Regardez les exemples suivants qui font tous référence à la même date :

  • 18/04/21 — Anglais américain

  • 18/04/2021 — Anglais britannique

  • 18.04.2021 — Roumain

  • ١٨‏/٤‏/٢٠٢١ — Arabie Saoudite, arabe avec chiffres arabes orientaux

Il existe des types de format prédéfinis fournis par les bibliothèques de date/heure, telles que FormatStyle dans java.time. Utilisez-les si possible. Sinon, vous pouvez créer des formats plus personnalisés à l'aide de symboles de modèle standardisés. Consultez la documentation CLDR pour plus de détails.

Il convient de noter que, dans le cas des mois, des trimestres et des jours de semaines, il existe également des variantes autonomes. Ils n'ont de sens que dans certaines langues (pas en anglais). En polonais, par exemple, avril s'appelle kwiecień — il s'agit d'une version autonome. Cependant, s'il est lié à un jour (par exemple le 18 avril), le texte devient 18 kwietnia.

Conclure

Gérer les dates et l'heure n'est pas simple. Cependant, si vous suivez les normes décrites ci-dessus et utilisez les types appropriés, vous pouvez éviter d'énormes erreurs.

J'espère que mes idées sur les dates et les cas limites d'heure seront utiles dans vos projets. Bonne chance !

Publié à l'origine sur https://www.thedroidsonroids.com le 26 avril 2021.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn