Fermer

septembre 26, 2020

Learn date-fns: une bibliothèque de dates JavaScript légère


 Introduction à date-fns

Travailler avec des dates en JavaScript est pénible. Les méthodes de date natives sont souvent verbeuses et parfois incohérentes – ce qui les rend également sujettes aux erreurs. Mais de bonnes nouvelles sont à portée de main. Il existe plusieurs bibliothèques pour éliminer la douleur de la manipulation. Ces bibliothèques sont aux dates JavaScript, ce que jQuery est à l'API DOM native.

Permettez-moi de vous donner un exemple. C'est la réponse acceptée à une question Stack Overflow demandant comment obtenir le dernier jour du mois :

 var  t  =   new   Date  ( ) ; 
 alert  (  new   Date  ( t .  getFullYear  () [19659007] t .  getMonth  ()   +   1   0   23   59   59 )  ) ; 

Bien sûr que cela fonctionne, mais ce que représentent les chiffres après getMonth n'est pas immédiatement évident. Maintenant, comparez cela avec le beaucoup plus lisible:

 const  today  =   new   Date  () ; 
 console . [19659015] log  (  lastDayOfMonth  ( today )  ) ; 

That lastDayOfMonth method is one provided by date-fns un ensemble d'outils complet auto-proclamé pour manipuler les dates JavaScript dans le navigateur et Node.js.

Dans cet article, je vais vous montrer comment être opérationnel avec date-fns. Après l'avoir lu, vous pourrez l'inclure dans vos projets et profiter de ses nombreuses méthodes d'aide pour manipuler les dates avec facilité. Cela fera du code t.getMonth () + 1, 0, 23, 59, 59 une chose du passé.

Alors, pourquoi ne pas simplement utiliser Moment.js?

Moment. js est une bibliothèque fantastique pour travailler avec des dates en JavaScript – elle possède de nombreuses fonctionnalités et offre une multitude d'utilitaires utiles. Il n'est cependant pas sans critiques.

Beaucoup de gens citent le fait que les objets Moment sont mutables (c'est-à-dire que des opérations comme add ou soustract changent l'objet Moment original) comme étant déroutant pour les développeurs et source de bogues.

Il a également été critiqué pour sa grande taille. Moment ne fonctionne pas bien avec les algorithmes modernes de «tremblement d'arbre» ​​et si vous avez besoin d'une internationalisation ou d'une prise en charge des fuseaux horaires, vous pouvez rapidement vous retrouver avec un ensemble JavaScript assez volumineux. fait que l'utilisation de Moment peut conduire à de mauvaises performances.

Tout cela a conduit les responsables de Moment à mettre le projet en maintenance et pour décourager Moment d'être utilisé dans de nouveaux projets à venir.

Nous reconnaissons que de nombreux projets existants peuvent continuer à utiliser Moment, mais nous aimerions décourager Moment d'être utilisé dans de nouveaux projets à l'avenir. Au lieu de cela, nous aimerions recommander des alternatives qui sont d'excellents choix pour une utilisation dans les applications modernes d'aujourd'hui.

Cela fait de date-fns l'une des meilleures alternatives à Moment.js.

Installation [19659064] Depuis la version deux de la bibliothèque, le seul moyen d'installer date-fns est de créer un package npm.
 npm   install  date-fns

Ou via Yarn:

 yarn   add  date-fns

Vous pouvez utiliser date-fns avec le système de modules CommonJS et aussi avec les modules ES:


 const   { lastDayOfMonth }   =   require  ([19659076] 'date-fns' ) ; 

ou:


 import   { lastDayOfMonth }   from   'date-fns' [19659007]; 

Il n'y a malheureusement actuellement pas de version CDN de date-fns disponible. Sa suppression et sa possible réintégration sont en cours de discussion dans ce numéro de GitHub . Mais cela ne veut pas dire que vous ne pouvez pas l'utiliser dans un navigateur, mais simplement que vous devrez introduire une étape de regroupement dans votre flux de travail.

Voyons comment faire cela maintenant.

Comment regrouper date-fns pour Utilisation dans un navigateur

Je suppose que Node et npm sont installés sur votre machine. Sinon, veuillez consulter notre tutoriel sur l'installation de Node .

Ensuite, installez Parcel . Il s'agit d'un bundler (similaire à Webpack), qui vous permettra de regrouper votre JavaScript et de le diffuser dans un navigateur.

 npm   install  -g parcel-bundler

Ensuite, créez un nouveau projet avec un fichier package.json .

 mkdir  datefns
 cd  datefns
 npm  init -y

Installez la bibliothèque date-fns, comme ci-dessus:

 npm   install  date-fns

Créez maintenant deux fichiers, index.html et index.js .


 < html   lang  =  " en  " > 
   < head > 
     < meta   charset  = "  UTF- 8  "   /> 
     < title >  date-fns  </  title > 
   </  tête > 
   < corps > 
     < script   src  =  " index.js "  >    </  script > 
   </  body > 
 </  html > 
 import   { lastDayOfMonth }   from   'date-fns' ; 

 const  today  =   new [19659006] Date  () ; 
 console .  log  ( lastDayOfMonth  ( today ) ) ; 

Démarrez le serveur de développement intégré de colis:

 parcel index.html

Et accédez à http: // localhost: 1234 . Vous ne verrez rien affiché sur la page, mais si vous ouvrez la console du navigateur. vous devriez qu'il ait enregistré le dernier jour du mois en cours.

En ce qui concerne le déploiement, vous pouvez exécuter:

 parcel build index.js --experimental-scope-hoisting

pour que Parcel affiche un bundle minifié et arborescent dans le dossier dist .

Date-fns Basic Usage

Maintenant que nous sommes opérationnels, regardons à quelle date -fns peut le faire.

L'une des tâches les plus courantes lorsque vous travaillez avec des dates est la possibilité de les formater correctement. Nous pouvons le faire avec la fonction de format date-fns .

Modifiez le code HTML de notre page d'exemple ci-dessus pour qu'il ressemble à ceci:

   < body > 
   < h1 >  La date est aujourd'hui  < span > [19659112]  </  span >   </  h1 > 
   < script   src  =  " index.js "  >    </  script > 
 </  body >  

Dans index.js nous voulons importer la fonction format que nous pouvons ensuite passer la date du jour et une chaîne de format. Nous voulons ensuite afficher le résultat sur la page.

 import   { format }   from   'date-fns' ; 

 const  today  =   nouveau   Date  () ; 
 const  formattedDate  =   format  ( today   'jj.MM.aaaa' ) ; 

 document .  querySelector  ( 'h1> span' ) [19659007].  textContent   =  formattedDate ; 

Bien sûr, nous ne sommes pas limités à un format jj.MM.yyyy essayons quelque chose de différent: [19659004] const formattedDate = format ( today 'PPPP' ) ;

Cela formatera la sortie comme so: Mercredi 16 septembre 2020 . Vous pouvez trouver une liste complète des options de formatage dans la documentation .

Changer les paramètres régionaux

Si vous avez un site Web en plusieurs langues, alors date-fns simplifie l'internationalisation des heures et des dates. Salutons nos invités allemands:

   < h1 >  Heute ist  < span >   </  span  >   </  h1 >  

Et dans le fichier JavaScript, nous pouvons importer les paramètres régionaux allemands et les transmettre au format fonction : [19659180] import { format } from 'date-fns' ;
import { de } from 'date-fns / locale' ;

const today = new Date () ;
const formattedDate = format ( today 'PPPP' { locale : de } ) ;

document . querySelector ( 'h1> span' ) . textContent [19659022] = formattedDate ;

Cela affichera quelque chose du genre: Heute ist Mittwoch, 16. septembre 2020 .

Il peut sembler compliqué d'exiger et de passer des paramètres régionaux comme options, mais contrairement à Moment.js qui gonfle votre build avec tous les paramètres régionaux par défaut, date-fns oblige les développeurs à exiger manuellement les paramètres régionaux au fur et à mesure qu'ils sont nécessaires.

Vous pouvez afficher une liste des paramètres régionaux disponibles en consultant le node_modules / date-fns / locale dossier dans votre projet.

Immuabilité, pureté et simplicité

L'un des arguments de vente de date-fns est que ses fonctions sont pures et simples à expliquer. Cela conduit à un code facile à comprendre, qui est plus facile à déboguer lorsque les choses tournent mal.

Permettez-moi de vous montrer cela en utilisant Moment.js comme contre-exemple. Comme mentionné précédemment, les dates dans Moment sont modifiables, ce qui peut entraîner un comportement inattendu.

 const  moment  =   require  ( 'moment' )  ; 
 const  now  =   new   Date  () ; 
 const  mNow  =   moment [19659007] ( maintenant ) ; 

mNow .  add  ( 'day'   3 ) ; 
 console .  log  ( mNow .  àDate  () ) ; 
mNow .  add  ( 3   'day' ) ; 
 console .  log  ( mNow .  àDate  () ) ; 



Il y a quelques points à noter ici. La fonction add de Moment n’est pas difficile quant à l’ordre dans lequel elle accepte ses arguments (bien que la première méthode lancera désormais un avertissement de désapprobation). Mais le plus déroutant est que si vous appelez add plusieurs fois de suite, vous n'obtiendrez pas le même résultat car les objets Moment sont mutables:

 mNow .  add  ( 3   "jour" ) ; 
mNow .  add  ( 3   'day' ) ; 

Maintenant, comparez cela à date-fns qui garde les arguments dans un ordre et renvoie toujours le même résultat, renvoyant un nouvel objet Date pour chaque appel.

 import   { addDays }   de   'date-fns' ; 

 const  today  =   new   Date  ()) [19659007]; 
 const  threeDaysTime  =   addDays  ( 3  today ) ; 
 const  sixDaysTime  =   addDays  ( threeDaysTime   3 ) ; 

 console .  log  ( ] today ) ;  
 console .  log  ( threeDaysTime ) ;  
 console .  log  ( sixDaysTime ) ; 

Notez également à quel point le nom de la méthode est plus expressif ( addDays au lieu de seulement add ), en gardant les choses cohérentes et en ayant une méthode pour faire une chose et une seule chose. [19659369] Comparaison des dates

Si vous regardez la liste des articles sur le canal JavaScript de SitePoint, vous pouvez voir que certains sont répertoriés comme étant publiés à une certaine date, tandis que d'autres sont répertoriés comme étant publiés il y a X jours. Cela peut prendre un certain temps si vous essayez de l'implémenter en JavaScript vanille, mais avec date-fns c'est un jeu d'enfant – utilisez simplement la méthode formatDistance .

Comparons deux dates différentes.

 import   { formatDistance }   from   'date-fns' ; 

 const  startDate  =   new   Date  ] ( 2020   8   16 ) ;  
 const  endDate  =   new   Date  ( 2020   11   25 ) ;  
 const  distanceInWords  =   formatDistance  ] ( startDate  endDate ) ; 

 console .  log  ( ` It is  $ { distanceInWords }   jusqu'à Noël  ` [19659007]) ; 

Remarquez comment, lorsque vous travaillez avec JavaScript, les mois sont basés sur zéro (par exemple, mois 11 = décembre), mais les jours comptent à partir de un. Cela me trébuche encore et encore.

Travailler avec des collections de dates

Date-fns a quelques méthodes d'aide très pratiques que vous pouvez utiliser pour manipuler des collections de dates de toutes sortes de façons.

Commander une collection de Dates

L'exemple suivant utilise compareAsc pour trier les dates par ordre croissant. Pour ce faire, il renvoie 1 si la première date est postérieure à la seconde, -1 si la première date est antérieure à la seconde ou 0 si les dates sont égales.

 import   { compareAsc } [19659082] de   'date-fns' ; 

 const  date1  =   new   Date  ( '2005-01-01' [19659007]) ; 
 const  date2  =   new   Date  ( '2010-01-01' ) ; [19659191] const  date3  =   new   Date  ( '2015-01-01' ) ; 
 const  arr  =   [ date3  date1  date2 ] ; 
 const  sortedDates  =  arr .  sort  ( compareAsc ) ; 


Comme vous pouvez le voir, les dates sont maintenant dans l'ordre croissant.

La méthode équivalente à compareAsc est compareDesc .

 import   { compareDesc }   from   'date-fns' ; 
 ... 
 const  sortedDates  =  arr .  sort  ( compareDesc ) ; 

Génération des jours entre deux dates

Pour générer les jours entre deux dates, vous pouvez utiliser la méthode addDays que nous avons rencontrée précédemment, ainsi que le eachDayOfInterval helper qui renvoie un tableau de dates dans la plage spécifiée.

 import   { addDays  eachDayOfInterval } [19659082] de   'date-fns' ; 

 const  today  =   new   Date  () ; 
 const  aWeekFromNow  =   addDays  ( today   7 ) ; 
 const  thisWeek  =   eachDayOfInterval  (
   { start :  today  end :  aWeekFromNow } 
) ; [19659353] console .  log  ( thisWeek ) ; 


Recherche de la date la plus proche

Recherche de la date la plus proche d'une certaine date dans un tableau de dates peut être fait en utilisant la méthode plus procheTo . Cet extrait de code fait suite à l'exemple précédent:

 import   { addDays  eachDayOfInterval  nearTo }   from   ' date-fns '; 
 ... 
 const  noël  =   nouveau   Date  ( 2020   11   25 ) ; 
 const  nearToChristmasDate  =   nearTo  ( noël  thisWeek  ]) ; 

 console .  log  ( nearChristmasDate ) ; 

Il y a aussi la méthode plus procheIndexTo si vous voulez obtenir l'index du tableau à la place.

Validation d'une date

La dernière aide que je veux regarder est la méthode isValid qui, comme son nom l'indique, vérifie si une date donnée est valide.

Cependant, en raison de la façon dont JavaScript traite les dates, il y a quelques pièges à connaître:

 import   { isValid }   from   'date-fns' ; 

 const  invalidDate  =   new   Date  ([19659076] '2020, 02, 30' ) ; 
 console .  log  ( isValid  ( invalidDate ) [19659007]) ; 

On vous pardonnerait de penser que l'extrait ci-dessus devrait afficher false car le 30 février 2020 est évidemment une date invalide. Pour comprendre ce qui se passe, saisissez new Date ('2020, 02, 30') dans la console de votre navigateur. Vous verrez Sun Mar 01 2020 revenir vers vous – JavaScript a pris le jour supplémentaire de fin février et l'a transformé en 1er mars (qui est bien sûr une date valide).

Pour contourner ce problème, nous pouvons analyser la date avant de vérifier sa validité:

 import   { isValid  parse }   from [19659083] 'date-fns' ; 

 const  validDate  =   parse  ( '29 .02.2020 ' ' jj.MM .yyyy '  new   Date  () ) ; 
 const  invalidDate  =   parse  ( '30 .02.2020 ' ' dd.MM.yyyy '  new   Date  () )  ; 

 console .  log  ( validDate ) ; 


 console .  log  ( invalidDate ) ; 


 console .  log  ( isValid  ( validDate ) )  ; 


 console .  log  ( isValid  ( invalidDate ) ) ; 

Ceci peut facilement être extrait dans une petite méthode d'aide, utile, par exemple, pour valider l'entrée utilisateur dans les formulaires.

Fuseaux horaires

Un inconvénient de date-fns est qu'il n'en a actuellement aucun L'assistant de fuseau horaire fonctionne comme Moment.js, mais renvoie plutôt le fuseau horaire local sur lequel le code s'exécute.

Cette réponse Stack Overflow donne des informations sur le niveau natif Date les objets ne stockent pas réellement les données de «fuseau horaire réel». Dans ce fil de discussion, vous remarquerez qu'ils mentionnent une méthode de définition native des fuseaux horaires en JavaScript. Ce n'est pas une solution complète, mais cela fonctionne pour de nombreux scénarios qui ne nécessitent qu'une conversion de sortie (de l'heure UTC ou locale vers un fuseau horaire spécifique).

 new   Date  () [19659007].  toLocaleString  ( "en-US"   { timeZone :   "America / New_York" } ) ; 

Les fuseaux horaires sont en fait un problème compliqué à résoudre, c'est pourquoi MomentJS a une bibliothèque séparée pour cela. Il y a plans en cours pour ajouter la prise en charge du fuseau horaire à date-fns mais au moment de la rédaction de cet article, ce travail est toujours en cours.

Il existe cependant un package disponible sur npm (basé sur une demande d'extraction non fusionnée vers date-fns ) qui ajoute la prise en charge du fuseau horaire pour date-fns v2.0.0 à l'aide de l'API Intl . Avec 140k téléchargements hebdomadaires, il semble populaire, mais au moment de la rédaction de cet article, il n'a pas été mis à jour depuis plusieurs mois.

Cela dit, voici comment vous pourriez l'utiliser:

 npm  i date-fns- tz
 import   { format  utcToZonedTime }   from   'date-fns-tz' ; 

 const  today  =   nouvelle   Date  () ;  
 const  timeZone  =   'Australie / Brisbane' ; [19659388] const  timeInBrisbane  =   utcToZonedTime  ( today  timeZone ) ; 

 console .  log  ( "
  Heure à Munich:  $ { format  ( today   'yyyy-MM-dd HH: mm: ss' ) }  
  Heure à Brisbane:  $ { format  ( timeInBrisbane   'yyyy-MM-dd HH: mm: ss' ) }  
 ` ) ; 



Conclusion

Date-fns est une super petite bibliothèque qui met tout un tas de méthodes d'aide pour travailler avec les dates et les heures en JavaScript au bout de vos doigts . Il est en cours de développement actif et maintenant que Moment.js a été mis en mode maintenance, cela en fait un excellent remplacement pour Moment.js. commencez à l'utiliser dans vos propres projets.






Source link