Poco fa, nel maggio del 2021, ho scritto di Lo status di Luxon come erede apparente di Moment.js poiché il successivo è entrato in modalità di manutenzione. Da allora, i creatori di plugin per Moment.js si sono affrettati a migrare le loro librerie a Luxon, poiché sempre più organizzazioni lo adottano come loro di fatto Libreria di date JS.
Uno di questi plugin è Luxon giorni lavorativi. Come suggerisce il nome, è una libreria per il calcolo e la manipolazione dei giorni lavorativi che si basa su di essa Momento di giorni lavorativi precursore.
In questo tutorial, utilizzeremo Luxon Business Days per accedere a una serie di prezzi azionari giornalieri senza dover ripetere da soli ogni elemento per trovare un giorno specifico.
Il compito spiegato
Supponiamo di avere un oggetto che memorizza una serie temporale giornaliera e i relativi prezzi delle azioni:
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 bellezza degli array paralleli a Luxon
Per questo tutorial, manterremo breve la lunghezza delle serie temporali e le limiteremo a circa due mesi. In uno scenario reale, le serie temporali potrebbero estendersi indietro di anni, quindi è bene evitare di ripetere sia le timestamp e chiudere matrici. Fortunatamente, non dobbiamo. Per capire perché, immagina che stavamo cercando il prezzo delle azioni 21 febbraio 2022. Per farlo, dovremmo prima trovare quale timestamp l’elemento conteneva la data che stiamo cercando. Da lì, potremmo recuperare il prezzo dal chiudere array usando lo stesso indice di elemento, perché entrambi i timestamp e chiudere sono Array paralleli. Conosciuto anche come Struttura degli array (SoA)si tratta di più array della stessa dimensione in modo tale che il ennesimo l’elemento di ogni array è correlato in modo che all ennesimo gli elementi insieme rappresentano un oggetto o un’entità. Li troverai ovunque nel codice dell’applicazione, ma un esempio di array parallelo sono due array che rappresentano X e y coordinate di n punti.
Quindi, trovare l’indice di un elemento ci punta automaticamente ai dati correlati nell’altro array.
Leggere: Conversione TimeZone con Luxon e JavaScript
Calcolo del numero di giorni tra due date utilizzando Luxon
Una delle cose in cui Luxon è estremamente bravo è calcolare la durata tra le date. In effetti, sarebbero necessarie solo tre righe di codice per trovare il numero di giorni tra il primo timestamp e il 21 febbraio 2022 data obiettivo che stiamo cercando:
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
Il diff() il metodo restituisce un oggetto Duration, quindi è necessario accedere a giorni proprietà se vogliamo solo i giorni e nessun altro intervallo, come settimane o mesi.
Calcolo del numero di giorni lavorativi tra due date
Mentre il risultato di cui sopra (47) ha ragione, c’è un problema: i prezzi giornalieri delle azioni vengono forniti solo nei giorni lavorativi! Se osservi attentamente i timestamp, noterai che c’è un intervallo di due giorni ogni cinque giorni. A quanto pare, la libreria Moment Business Days ha il businessDiff() metodo, che salta convenientemente i giorni non lavorativi nei suoi calcoli. Ovviamente, dal momento che stiamo usando Luxon, ha senso solo accoppiarlo con il Luxon giorni lavorativi collegare.
Questo è probabilmente un buon momento per ricordare che il Luxon giorni lavorativi plugin non è un port completo della sua controparte Moment.js. E, come vuole il destino, il metodo businessDiff() è vistosamente assente dalla documentazione, dall’oggetto globale dello spazio dei nomi DateTime e dal codice sorgente. Questo significa che il nostro piano è morto nell’acqua? Lontano da esso. Possiamo trasferire Moment.js businessDiff() metodo al nostro progetto. Certo, non funzionerà subito con Luxon, ma grazie a Luxon’s Per gli utenti del momento pagina, possiamo facilmente sostituire gli equivalenti Luxon con le invocazioni del metodo Moment. Ecco la nuovissima compatibilità Luxon businessDiff() metodo:
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; };
Il businessDiff() metodo ritorna 33che equivale all’indice per recuperare i dati sui prezzi:
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
Leggere: Analisi di date e orari con Luxon
La demo
Nel demo codepen.ioil businessDiff() il metodo viene utilizzato per affettare il chiudere e timestamp matrici al giorno dopo il targetPriceCalcDatein modo da poter cercare il primo giorno in cui il prezzo di chiusura del titolo corrisponde o supera il prezzo target, utilizzando il Array.findIndex() metodo:
const targetPriceAchievedIndex = pricesFromTargetPriceCalcDate.findIndex(price => price >= targetPrice) + 1;
Conclusione
Non sei un fan del loop? Perché non lasciare che qualcun altro gestisca il carico dell’iterazione dell’array per te? Grazie a metodi come diff(), businessDiff(), Trovare()e trovaIndice()puoi dimenticare tutto sui loop e sul codice in un modo più orientato al metodo che è più vicino alla programmazione funzionale rispetto al tuo tipico JavaScript.
Leggi di più Tutorial di programmazione JavaScript e sviluppo web.