Calcul des intervalles temporels avec Luxon Business Days

Tutoriels JavaScript

Il y a peu de temps, en mai 2021, j’ai écrit sur le statut de Luxon en tant qu’héritier apparent de Moment.js alors que ce dernier passait en mode maintenance. Depuis lors, les créateurs de plugins pour Moment.js se sont efforcés de migrer leurs bibliothèques vers Luxon, alors que de plus en plus d’organisations l’adoptent comme leur de facto Bibliothèque de dates JS.

L’un de ces plugins est Luxon Business Days. Comme son nom l’indique, il s’agit d’une bibliothèque de calcul et de manipulation des jours ouvrables basée sur son précurseur Moment Business Days.

Dans ce didacticiel, nous utiliserons Luxon Business Days pour accéder à un tableau de cours quotidiens des actions sans avoir à parcourir nous-mêmes chaque élément pour trouver un jour spécifique.

La tâche expliquée

Supposons que vous disposiez d’un objet stockant une série temporelle quotidienne et les cours boursiers associés :

const DAY_TIMESERIES = {
  close: [
    174.92, 
    172, 
    172.17, 
    172.19, 
    175.08, 
    175.53, 
    172.19, 
    173.07, 
    173.07, 
    169.8, 
    166.23, 
    164.51, 
    162.41, 
    161.62, 
    159.78, 
    159.69, 
    159.22, 
    170.33, 
    174.78, 
    174.61, 
    175.84, 
    172.9, 
    172.39, 
    171.66, 
    174.83, 
    176.28, 
    172.12, 
    168.64, 
    168.88, 
    172.79, 
    172.55, 
    168.88, 
    167.3, 
    167.3, 
    169.32, 
    170.07, 
    162.74
  ],
  timestamps: [
    "2022-01-05T00:00:00",
    "2022-01-06T00:00:00",
    "2022-01-07T00:00:00",
    "2022-01-10T00:00:00",
    "2022-01-11T00:00:00",
    "2022-01-12T00:00:00",
    "2022-01-13T00:00:00",
    "2022-01-14T00:00:00",
    "2022-01-17T00:00:00",
    "2022-01-18T00:00:00",
    "2022-01-19T00:00:00",
    "2022-01-20T00:00:00",
    "2022-01-21T00:00:00",
    "2022-01-24T00:00:00",
    "2022-01-25T00:00:00",
    "2022-01-26T00:00:00",
    "2022-01-27T00:00:00",
    "2022-01-28T00:00:00",
    "2022-01-31T00:00:00",
    "2022-02-01T00:00:00",
    "2022-02-02T00:00:00",
    "2022-02-03T00:00:00",
    "2022-02-04T00:00:00",
    "2022-02-07T00:00:00",
    "2022-02-08T00:00:00",
    "2022-02-09T00:00:00",
    "2022-02-10T00:00:00",
    "2022-02-11T00:00:00",
    "2022-02-14T00:00:00",
    "2022-02-15T00:00:00",
    "2022-02-16T00:00:00",
    "2022-02-17T00:00:00",
    "2022-02-18T00:00:00",
    "2022-02-21T00:00:00",
    "2022-02-22T00:00:00",
    "2022-02-23T00:00:00",
    "2022-02-24T00:00:00"
  ]
};

La beauté des réseaux parallèles à Luxon

Pour ce didacticiel, nous garderons la longueur des séries chronologiques brève et les plafonnerons à environ deux mois. Dans un scénario réel, les séries temporelles pourraient s’étendre sur des années, il serait donc bien d’éviter de parcourir à la fois le horodatages et proche tableaux. Heureusement, nous n’avons pas à le faire. Pour comprendre pourquoi, imaginons que nous recherchions le cours de l’action sur 21 février 2022. Pour ce faire, il faudrait d’abord trouver quel horodatages l’élément contenait la date que nous recherchons. De là, nous pourrions récupérer le prix de la proche tableau utilisant le même index d’élément, car à la fois le horodatages et proche sont Réseaux parallèles. Aussi connu sous le nom Structure des tableaux (SoA)il s’agit de plusieurs tableaux de même taille tels que nième élément de chaque tableau est lié de sorte que tous nième les éléments représentent ensemble un objet ou une entité. Vous les trouverez partout dans le code d’application, mais un exemple de tableau parallèle est constitué de deux tableaux qui représentent X et y coordonnées de n points.

Par conséquent, trouver l’index d’un élément nous dirige automatiquement vers les données associées dans l’autre tableau.

Lis: Conversion de fuseau horaire avec Luxon et JavaScript

Calcul du nombre de jours entre deux dates à l’aide de Luxon

L’une des choses pour lesquelles Luxon est extrêmement doué est le calcul de la durée entre les dates. En fait, il ne faudrait que trois lignes de code pour trouver le nombre de jours entre le premier horodatage et le 21 février 2022 date cible que nous recherchons :

const firstClosingPriceDate = DateTime.fromISO(DAY_TIMESERIES.timestamps[0]); //"2022-01-05T00:00:00"
const targetPriceCalcDate = DateTime.fromISO("2022-02-21T00:00:00");

let diffInDays = targetPriceCalcDate.diff(firstClosingPriceDate, 'days').days;  //47

Le différence() renvoie un objet Duration, nous devons donc accéder à la jours propriété si nous ne voulons que les jours et aucun autre intervalle, comme des semaines ou des mois.

Calcul du nombre de jours ouvrables entre deux dates

Alors que le résultat ci-dessus (47) est tout à fait exact, il y a un problème : les cours quotidiens des actions ne sont fournis que les jours ouvrables ! Si vous regardez attentivement les horodatages, vous remarquerez qu’il y a un intervalle de deux jours tous les cinq jours. Il se trouve que la bibliothèque Moment Business Days a le businessDiff() méthode, qui saute commodément les jours non ouvrables dans ses calculs. Bien sûr, puisque nous utilisons Luxon, il est logique de l’associer au plugin Luxon Business Days.

C’est probablement le bon moment pour mentionner que le plugin Luxon Business Days n’est pas un portage complet de son homologue Moment.js. Et, comme le veut le destin, la méthode businessDiff() est manifestement absente de la documentation, de l’objet d’espace de noms DateTime global et du code source. Cela signifie-t-il que notre plan est mort dans l’eau ? Loin de là. Nous pouvons porter sur le Moment.js businessDiff() méthode à notre propre projet. Bien sûr, cela ne fonctionnera pas immédiatement avec Luxon, mais, grâce à la page For Moment Users de Luxon, nous pouvons facilement remplacer les équivalents Luxon par les invocations de la méthode Moment. Voici le tout nouveau compatible Luxon businessDiff() méthode:

DateTime.prototype.businessDiff = function(d2, relative) {
  var d1 = this;
  var positive = d1 >= d2;
  var start = d1 < d2 ? d1 : d2;
  var end = d2 > d1 ? d2 : d1;
  var daysBetween = 0;

  if (start.hasSame(end, 'day')) {
    return daysBetween;
  }

  while (start.startOf('day') < end.startOf('day')) {
    if (start.isBusinessDay()) {
      daysBetween += 1;
    }
    start = start.plus({ days: 1 })
  }

  if (!end.isBusinessDay()) {
    daysBetween -= 1;
  }

  if (relative) {
    return (positive ? daysBetween : -daysBetween);
  }

  return daysBetween;
};

Le businessDiff() la méthode renvoie 33qui équivaut à l'index pour récupérer les données de prix :

let diffInDays = targetPriceCalcDate.businessDiff(firstClosingPriceDate); // 33

document.write(pricesFromTargetPriceCalcDate[diffInDays]); //172.79
document.write(
  DateTime.fromISO(daysFromTargetPriceCalcDate[diffInDays]).toLocaleString(DateTime.DATE_MED)
); //Feb 15, 2022

Lis: Analyse des dates et des heures à l'aide de Luxon

La démo

Dans la démo codepen.io, le businessDiff() méthode est utilisée pour trancher proche et horodatages tableaux au lendemain de la targetPriceCalcDateafin que nous puissions rechercher le premier jour où le cours de clôture de l'action correspond ou dépasse le cours cible, en utilisant le natif Tableau.findIndex() méthode:

const targetPriceAchievedIndex 
  = pricesFromTargetPriceCalcDate.findIndex(price => price >= targetPrice) + 1;

Conclusion

Pas fan du looping ? Pourquoi ne pas laisser quelqu'un d'autre gérer le fardeau de l'itération de tableau pour vous ? Grâce à des méthodes comme différence(), businessDiff(), trouver()et trouverIndex()vous pouvez tout oublier sur les boucles et le code d'une manière plus orientée méthode, plus proche de la programmation fonctionnelle que votre JavaScript typique.

En savoir plus sur la programmation JavaScript et les didacticiels de développement Web.

Leave a Comment