La gestion des dates lors du traitement des fuseaux horaires est une tâche difficile.
Heureusement pour nous, il existe de nombreuses bibliothèques comme moment.js qui nous aident à gérer des problèmes courants comme les fuseaux horaires, l’heure d’été, la manipulation et le formatage de la date.

J’ai récemment rencontré plusieurs problèmes dans l’affichage des dates dans le bon format et le fuseau horaire tout en travaillant sur un projet d’application mobile.

Nous avons un serveur externe qui nous envoie l’heure locale sous forme de chaîne et de fuseau horaire comme ceci:

{
  localDateTime: 'YYYY-MM-DD HH:mm', // Not in UTC
  timezone: 'Indian/Reunion', // Or 'Europe/Paris''
}

Je devais afficher et manipuler ces dates. Mais avant cela, j’avais besoin de les analyser et de les stocker.

Dans cet article, je vais vous montrer comment gérer les difficultés courantes dans la gestion des dates avec l’une des bibliothèques les plus courantes: moment.js.

Qu’est ce que « Moment Js »

Moment est une bibliothèque très complète et populaire pour gérer les dates. Elle peut être considéré comme la norme en javascript. Elle fournit des fonctions pour analyser, manipuler et afficher les dates et les heures. Moment-timezone.js ajoute des fonctions pour gérer les dates et les heures des différents pays.

D’un autre côté, il faut savoir que les dates des moments sont mutables. Je vais traiter ce problème dans la partie manipulation de cet article.

Je vais me concentrer sur l’explication du déroulement du traitement de la date dans une application JS complète. Je vais également faire la lumière sur certains points critiques de moments.

Time zone : les fuseaux horaire

Alors, qu’est-ce qu’un fuseau horaire?

Le fuseau horaire est une région du globe qui observe un temps standard uniforme décalé par rapport aux coordonnées universelles (UTC). Un fuseau horaire règle l’heure en fonction de la distance du méridien principal. Certains fuseaux horaires changent leur décalage au cours de l’année. C’est ce qu’on appelle l’heure d’été (DST).

Dans la carte ci-dessus, vous pouvez voir l’heure dans chaque partie du monde correspondant au fuseau horaire sans heure d’été.

fuseaux horaires mondiaux
Remarque: Il n’y a pas de différence de temps entre l’heure UTC et l’heure GMT (Greenwich Mean Time). Mais UTC est une heure standard alors que GMT est un fuseau horaire.

Comment stocker une date

Analyser la chaîne de date

Lorsque vous recevez une chaîne de date, vous devez d’abord l’analyser pour obtenir le Datetime correct avant de pouvoir le stocker dans votre base de données.

Selon le format

Moment fournit une fonction moment(date: string, format: string) pour convertir une chaîne en un objet moment en fonction du format.

const moment = require('moment')
 
const dateToStore = '2018-02-06 13:35'
const momentDate = moment(dateToStore,'YYYY-MM-DD HH:mm')
// momentObject(2018-02-06T13:35:00+01:00)

Selon le fuseau horaire

Nous avons créé un objet moment qui correspond à la chaîne. Mais voyons le résultat dans notre exemple avec un serveur A à la Réunion (UTC +04:00) et un serveur B en France (UTC +01:00). Si A envoie une chaîne 2018-02-06 13:35 à B, A veut partager 2018-02-06 9:35+00:00, mais B comprend 2018-02-06 12:35 +00:00.

Par défaut, moment analyse la date avec l’heure locale de la machine (l’utilisateur ou le serveur). Vous pouvez obtenir l’utcOffset local en minutes avec moment.utcOffset(). Donc, si vous ne spécifiez pas le fuseau horaire, la date ne sera pas correctement analysée. Vous auriez dû le spécifier en utilisant moment-timezone au lieu de moment.

const moment = require('moment')
const momentTz = require('moment-timezone')
 
const dateToStore = '2018-02-06 13:35'
moment().utcOffset(); // 60 minutes
const timeZone = 'Indian/Reunion' // 'UTC+04:00'
 
const momentDate = moment(dateToStore,'YYYY-MM-DD HH:mm')
//momentObject(2018-02-06T13:35:00+01:00)
 
const momentDateTz = momentTz.tz(dateToStore,'YYYY-MM-DD HH:mm',timeZone)
//momentObject(2018-02-06T13:35:00+04:00)

Meilleurs exemple

Dans ce cas, l’API externe envoie la date sans aucun fuseau horaire et pas en UTC. La meilleure pratique consiste à envoyer la date en UTC ou au moins avec le décalage d’UTC afin que le récepteur n’ait pas à gérer le fuseau horaire. Dans ces meilleurs cas, vous pouvez analyser la chaîne de date en utilisant moment.utc() ou moment.parseZone() ou aussi moment(date,'YYYY-MM-DD HH:mm:ssZZ').

const moment = require('moment')
 
const receveidDateInUTC= '2018-02-06 9:35:00+00:00'
const receveidDateWithTimeZone = '2018-02-06 13:35:00+04:00'
 
moment(receveidDateInUTC,'YYYY-MM-DD HH:mm:ssZZ')
// momentObject(2018-02-06T10:35:00+01:00)
 
moment.utc(receveidDateInUTC,'YYYY-MM-DD HH:mm:ssZZ')
// momentObject(2018-02-06T9:35:00+00:00)
 
moment(receveidDateWithTimeZone,'YYYY-MM-DD HH:mm:ssZZ')
// momentObject(2018-02-06T10:35:00+01:00)
 
moment.parseZone(receveidDateWithTimeZone,'YYYY-MM-DD HH:mm:ssZZ')
// momentObject(2018-02-06T13:35:00+04:00)

Comme vous pouvez le voir, il existe plusieurs façons d’analyser la même date.
C’est pourquoi il est recommandé de stocker et d’envoyer votre date en UTC.

Utiliser les coordonnées de temps universel (UTC)

Pour rendre les données portables, je recommande de stocker le datetime en UTC. C’est la norme de temps internationale qui exprime des dates sans décalage et ne s’ajuste pas à l’heure d’été. Pour ce faire, j’utilise la fonction moment.utc() qui convertit un objet moment en UTC.

const momentTz = require('moment-timezone')
 
const dateToStore = '2018-02-06 13:35'
const timeZone = 'Indian/Reunion' // 'UTC+04:00'
 
const momentDateTz = momentTz.tz(dateToStore,'YYYY-MM-DD HH:mm',timeZone)
// momentObject(2018-02-06T13:35:00+04:00)
 
const momentDateTzUTC = momentTz.tz(dateToStore,'YYYY-MM-DD HH:mm',timeZone).utc()
// momentObject(2018-02-06T9:35:00+00:00)

Finalement, vous pouvez stocker la date en tant qu’attribut TIMESTAMP_WITH_TIMEZONE dans votre base de données.

Afficher une date

Réglez l’heure locale

J’ai créé un service dans mon application qui fournit une fonction pour formater les dates. Nous avons reçu la date de notre back-end en UTC. Mais selon où la personne est, les locales ne sont pas les mêmes. Les locales contiennent des informations sur les conventions et normes linguistiques, culturelles et technologiques. C’est pourquoi la première chose à faire est de régler l’heure locale.

Mettre en forme la date

 

Pour finir, je crée une fonction pour chaque format que j’ai.

const plainTextDateTime = dateTime => {
return moment(dateTime).format('DD MMMM HH:mm') // 06 Février 13:35
}
const getDate = dateTime => {
return moment(dateTime).format('DD MMMM') // 06 Février
}
const getTime = dateTime => {
return moment(dateTime).format('HH:mm') // 13:35
}

Manipulation de date

Moment fournit un noyau de fonctions de manipulation comme fonctions de comparaison, d’addition et de soustraction. C’est vraiment facile à utiliser. Le problème principal est que les objets moment sont mutables.

Par exemple, si vous voulez savoir si une date est moins d’une heure, vous avez deux options:

//option 1
const myDate = moment('2018-02-06 13:35:00+00:00','YYYY-MM-DD HH:mm:ssZZ');
if (myDate.isBefore(moment().add(1,'hour'))) {
// myDate is less than one hour
}
 
//option 2
const now = moment();
const myDate = moment('2018-02-06 9:35:00+00:00','YYYY-MM-DD HH:mm:ssZZ');
if (myDate.subtract(1,'hour').isBefore(now)) {
// myDate is less than one hour
}
console.log(myDate.format())
// myDate has been muted => 2018-02-06T08:35:00+00:00

Avec la première option, vous ajoutez une heure à moment() ce qui n’est pas un problème car vous ne gardez pas cette valeur en mémoire. Mais avec la deuxième option, la valeur de myDate a changé ce qui n’est pas ce que vous attendiez. Vous devez cloner la valeur de myDate avant de manipuler cette valeur.

//option 2
const myDate = moment('2018-02-06 9:35:00+00:00','YYYY-MM-DD HH:mm:ssZZ');
if (myDate.clone().subtract(1,'hour').isBefore(moment())) {
// myDate is less than one hour
}
console.log(myDate.format())
// myDate has NOT been muted => 2018-02-06T09:30:00+00:00

Conclusion

Pour conclure, une date a quatre états pour les mêmes données:

  • L’état reçu sous forme de chaîne: analyser la date pour avoir l’objet moment correct
  • L’état de stockage: stocker vos données en UTC ou au moins avec le fuseau horaire
  • L’état de manipulation: manipulez vos dates avec l’objet date. Si vous utilisez un moment, clonez l’objet avant de le manipuler.
  • L’état d’affichage: définissez l’heure locale et créez un service pour gérer la représentation différente dans votre application.

Vous avez aimé cet article? N’hésitez pas à me faire un retour en commentaire


Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *