Perché non esiste un vero tipo di dati "Solo data"?


24

Sono così ridicolmente frustrato dal dover usare i valori DateTime per set di dati che sono veramente "solo un giorno". I compleanni sono l'esempio più comune, ma questo si presenta sempre nelle applicazioni aziendali.

Mi sono abituato a impostare solo la parte Ora dei record "solo data" su "mezzogiorno" (che evita che la data cambi mai indipendentemente dal fuso orario). Sembra un trucco e trovo per sempre bug dagli sviluppatori junior che inciampano in questo problema.

Il tempo è sempre relativo a un punto fisso. Le 16:00 sono 4 ore dopo il meridiano o mezzogiorno. Il punto più alto del sole in transito è osservabile e ci consente di impostare un sistema di coordinate. 3 ore prima di mezzogiorno (Ante Meridian), 2 ore dopo mezzogiorno, 1441899402938 millisecondi dal 1 ° gennaio 1970. Per le persone cresciute in un mondo cartesiano, questa è una seconda natura.

Ma il nostro calendario precede Cartesio. La mia tesi è che è più propriamente considerata un'enumerazione su cui viene applicata una funzione modulo. Il lunedì segue la domenica e così via fino a quando non si arriva al fatto che la domenica segue il sabato. Non c'è positivo e negativo, è un modulo o valore assoluto.

Allo stesso modo con anni che si ripetono. Ogni 365 giorni (o giù di lì) ci sono diversi giorni speciali per me: compleanni, anniversari, compleanni per bambini, ecc. Ecc. Le applicazioni di pianificazione aziendale sono piene di esempi di incontri ogni sette giorni, il primo martedì del mese, ecc. Solo perché possiamo mapparlo su un numero in virgola mobile, e in realtà mapparlo su detto numero risolve MOLTI problemi che sono davvero difficili alla vecchia maniera, ma ciò non significa che sia l'unico modo per farlo.

La consapevolezza e la comprensione della natura "piolo quadrato in un buco rotondo" dell'uso di DateTimes per memorizzare le date, secondo me, ti rende un programmatore migliore.

Esiste un valore in un'applicazione esplicitamente inteso come un'applicazione di pianificazione nella definizione di una classe Date o "l'approccio migliore è sempre impostato su mezzogiorno"? Quali potrebbero essere i problemi con l'utilizzo di DateTime e l'impostazione del componente Time su Noon? È possibile tenere conto del trasferimento del fuso orario in un simile approccio? Ho usato MomentJS, ma penso che sia solo una migliore classe Date.


7
questa è una domanda piuttosto interessante, penso. Prendi l'esempio del compleanno, ha davvero senso nell'essere umano, vivo in un posto e tutti si svegliano allo stesso tempo, in un certo senso. non appena è necessario esprimerlo matematicamente diventa molto complesso. Lo stesso vale per cose come l'orario di inizio / fine del turno di lavoro, ecc. Non sono "volte", sono "ore del giorno nel fuso orario in cui si sta lavorando"
Ewan,

3
NodaTime (una libreria C # per data e ora) ha un tipo di date.
CodesInChaos,

5
Memorizza i tuoi orari come UTC, senza problemi di data, senza problemi di fuso orario.
Loren Pechtel,

3
"Ma Dio, questo sembra un trucco, e trovo sempre bug dagli sviluppatori junior che inciampano in questo problema." - perché non creare semplicemente la tua lezione DateOnly o altro e chiamarla un giorno.
Brandin,

5
@MichaelBlackburn Sono serio. La tua spiegazione suona esattamente la situazione per un proprio tipo di dati che impone la regola aziendale (solo la data, ad es. È possibile memorizzarla internamente come "DateTime" con la parte temporale impostata su mezzogiorno), ma quindi esporre solo le parti desiderate (mese , giorno ecc. anno / nessun anno).
Brandin,

Risposte:


15

Prima di tutto, togliamo una cosa: i compleanni sono una cosa, le date di nascita sono un'altra. Un compleanno è un tipo di dati esotico perché manca non solo i componenti di ore, minuti ecc. Ma manca anche il componente dell'anno. Se vuoi davvero avere a che fare con i compleanni, consiglierei di inventare il tuo tipo di dati che contiene nient'altro che un numero di mese e un numero di giorno e non è correlato a nessuno dei tipi di dati data-ora incorporati.

D'altra parte, se vuoi tenere traccia anche dell'anno di nascita, allora ciò che hai non sono i compleanni, sono le date di nascita . Quindi, la domanda ora diventa perché non esiste un tipo di dati solo per la data, in modo che tu possa rappresentare comodamente le date di nascita, e invece le lingue popolari sembrano costringerti a usare un tipo che include anche un componente orario.

Consentitemi di menzionare brevemente che non è vero che tutti i linguaggi di programmazione offrono solo tipi di dati temporali che includono una componente temporale. Mi sono imbattuto in tipi di dati solo per la data in RDBMS e nei loro corrispondenti dialetti SQL. Ma questo è irrilevante: il fatto che esistano questi tipi di dati non significa che siano una buona cosa da avere, e gli RDBMS hanno una lunga storia di confusione dell'archiviazione con la rappresentazione.

Capirai perché è una cattiva idea avere tali tipi di dati solo per la data nel momento in cui ti rendi conto che il tempo è una coordinata. La maggior parte delle persone ha un'idea molto vaga di che ore sono e questa idea contiene nozioni culturali arcane come anni, mesi e giorni, senza rendersi conto che queste nozioni sono esclusivamente rappresentative : sono utili solo per rappresentare il tempo a un essere umano e per ricevere tempo come input da un essere umano. In qualsiasi livello al di sotto dell'attuale controllo della GUI per l'immissione del tempo, il tempo dovrebbe essere, e di solito è, rappresentato come coordinata temporale, che è un singolo numero di unità di tempo da qualche origine.

Ad esempio, nel DateTimetipo di dati di Microsoft Dotnet, l'unità di tempo è 100 nanosecondi e l'origine del tempo è 12:00 mezzanotte, 1 gennaio 0001 CE

Un altro esempio di una notazione arcana, esclusivamente rappresentativa, è la misurazione dell'angolo usando gradi, minuti di un grado e secondi di un grado. Naturalmente, al fine di ottenere qualsiasi utile calcolo fatto, è necessario utilizzare internamente i radianti e, se necessario, convertirli in e da gradi quando si interagisce con un utente umano.

Pertanto, non confondere la rappresentazione leggibile dall'uomo di una misurazione con la natura effettiva della misurazione. Molto spesso il metodo ideale per realizzare una misurazione, che si avvicina maggiormente alla natura della misurazione, è molto diverso dalla rappresentazione leggibile dall'uomo di quella misurazione.

Alla luce di tutto ciò, la tua richiesta per un tipo di dati temporale che rappresenta solo le date è simile a una richiesta per un tipo di dati angolare che sarebbe solo in grado di rappresentare gradi, impedendo esplicitamente qualsiasi maggiore precisione. Un tale tipo di dati sarebbe piuttosto limitato, e alla fine inutile, perché dovresti comunque convertirlo da e verso i radianti per fare qualcosa di utile con esso.

Il tuo problema con la data di nascita è che hai una coordinazione temporale imprecisa : la persona, ovviamente, è nata in un momento specifico nel tempo, ma l'ora e il minuto non sono stati registrati dall'ospedale, oppure no prenditi cura di loro. Quindi, ciò che sta realmente accadendo è che le coordinate del tuo tempo di data e ora di nascita hanno un margine di errore, una tolleranza o incertezza se lo desideri, ed è meglio trattarlo come tale: mettilo esattamente nel mezzo del giorno e considera un'incertezza implicita di +12 -12 ore. E questa è esattamente la soluzione a cui sei arrivato intuitivamente.


4
Questo non è vero per i "Giorni" che sono un concetto ancora più antico del Tempo. Sono giustamente pensati come un elenco o un modulo. La domenica segue il lunedì, ecc. Fino al ritorno alla domenica, che segue il sabato. È davvero una cosa diversa.
Michael Blackburn,

10
Beh, ovviamente l'ospedale ha scritto l'ora della nascita - questa è una pratica standard nella maggior parte degli ospedali. Questo non è affatto il problema. Il problema è che ai fini della commemorazione di eventi (compleanni, festività, anniversari, ecc.) Le persone non usano o vogliono una risoluzione migliore di 1 giorno. Vai a chiedere alla prima persona che vedi quando compie gli anni e ti daranno un mese e un giorno, ma mai un'ora e un minuto. Inoltre: utilizziamo unità che includono sempre la scala: millimetri, chilogrammi, megawatt e, in effetti, microfarad.
Caleb,

4
-1: non tutti gli usi del tempo devono rappresentare un singolo momento nel tempo. Un compleanno è un'idea diversa, rappresentata da un mese e un giorno nel calendario gregoriano. Ha senso chiedersi "è il compleanno di Kevin oggi?" La risposta dipende dalla posizione. Se fossi a Sydney, potrebbe essere il mio compleanno, ma se fossi a Honolulu, non sarebbe ancora per alcune ore.
Kevin Cline,

6
@MikeNakis Il risultato sarebbe microampere, non sciocchezze. Ancora più importante: quando usi una data piuttosto che un secondo o millisecondo, stai generalmente parlando dell'intero giorno - un periodo di tempo - piuttosto che di un orario specifico e, a seconda del contesto, potrebbe essere un evento ricorrente.
Caleb,

4
L'OP stava parlando dei compleanni, che sono esattamente rappresentati da java.util.MonthDay. Un compleanno non è una misura, è l'idea umana di un giorno che si ripete ogni anno. Ci sono molte idee umane sul tempo che non sono rappresentate da un singolo punto nel tempo.
Kevin Cline,

9

Le date e gli orari sono molte cose diverse a seconda del contesto e sono necessari molti tipi separati per coprire tutti i casi d'uso.

Il DateTimetipo presente in molte lingue rappresenta un preciso momento ("tempo istantaneo"). Oltre a ciò, abbiamo una serie di concetti relativi o temporali relativi o "umani" come giorni di calendario, date ricorrenti, mesi, anni ecc. Che sono in molti casi ambigui e dipendenti dal contesto. Questi tipi non sono così universalmente utili, ma necessari in domini applicativi specifici come calendari, strumenti di pianificazione e altre applicazioni che interagiscono con i concetti umani del tempo.

Se stai scrivendo qualcosa di simile a un'app di calendario, trarrai sicuramente beneficio dall'utilizzo di una libreria come Joda-time che offre un set più ricco di tipi di tempo. Ad esempio LocalDate, una data senza ora. Questo ha una semantica diversa rispetto a un normale DateTimecon la parte temporale impostata su zero, poiché DateTimeindica ancora un punto temporale specifico (mezzanotte in un fuso orario specifico), mentre LocalDateindica tutto il giorno e non è legato a un fuso orario specifico. Questo significa anche che non puoi tradurre direttamente l'uno nell'altro.

LocalDateè certamente più semplice rispetto al DateTimefatto che non deve prendere in considerazione i fusi orari, ma è necessario essere consapevoli degli altri problemi, ad esempio che la data corrente potrebbe effettivamente tornare indietro quando si attraversa un fuso orario e che lo stesso istante nel tempo potrebbe corrispondono a date diverse in fusi orari diversi. Se si utilizzano date locali in app in rete o Web, è necessario prestare molta attenzione a questi problemi. La rimozione del fuso orario da una data non risolve il problema fondamentale dei fusi orari! E se prendi in considerazione date storiche e culture diverse diventa ancora più complicato, dal momento che la stessa data può corrispondere a istanze selvaggiamente diverse nel tempo, ad esempio il calendario giuliano contro il calendario gregoriano.

Ora chiedi perché le lingue non hanno qualcosa di simile al LocalDate built-in . Prima di tutto, alcuni linguaggi come SQL e Visual Basic hanno un tipo di data senza la parte di tempo. E Java ha anche aggiunto un LocalDatenella versione recente. Ma altre piattaforme come .Net no. Solo i progettisti del linguaggio possono davvero rispondere al perché questo non è incluso nella libreria standard, ma la mia ipotesi sarebbe che il "tempo istantaneo" sia concettualmente semplice e universalmente utile, mentre gli altri concetti temporali sono utili solo per domini applicativi specifici (come calendari ecc. .). Quindi ha senso lasciare che lo sviluppatore dell'applicazione scriva tipi personalizzati per gestire i casi d'uso più complessi o che sia gestito da una libreria di terze parti (come Joda-time).


5

Sono così ridicolmente frustrato dal dover usare i valori DateTime per set di dati che sono veramente "solo un giorno". I compleanni sono l'esempio più comune, ma questo si presenta sempre nelle applicazioni aziendali.

Ciò è probabilmente dovuto al fatto che i calendari sono complicati e utilizzati in così tanti modi diversi che nessuno è stato in grado di capire una classe che sia semplice ma abbastanza generale da essere utile in molti campi.

Il tipo di data che si trova comunemente nei linguaggi di programmazione può essere utilizzato per datare con precisione le transazioni in un sistema informatico. È probabile che altri casi d'uso richiedano una libreria personalizzata.

Ecco un breve elenco di fatti sui calendari, che dimostrano la loro complessità - la maggior parte di essi sono storici, quindi se stai limitando la tua attenzione alle date successive all'1.1.1970, non ne sarai influenzato. Tuttavia, se l'applicazione deve funzionare con date che si verificano prima della fine del 19 ° secolo, questi fatti contano. I possibili casi d'uso sono database storici di ogni tipo (libri, genealogia) ma anche beni di grandi aziende o organizzazioni ancora in attività oggi.

Tutti questi fatti sono citati dalle eccellenti FAQ trovate nella libreria del calendario per OCaml scritta da Julien Signolles.

  1. Il calendario giuliano fu introdotto da Giulio Cesare nel 45 a.C. Era in uso fino al 1500, quando i paesi iniziarono a cambiare il calendario gregoriano (sezione 2.2). Tuttavia, alcuni paesi (ad esempio, Grecia e Russia) lo usarono nel 1900 e la chiesa ortodossa in Russia lo usa ancora, così come alcune altre chiese ortodosse.

  2. Il passaggio dal calendario giuliano al calendario gregoriano non è avvenuto in modo uniforme e, a seconda dell'anno di cambiamento, sono stati eliminati da 10 a 13 giorni. Ad esempio in Francia il 9 dicembre 1582 fu seguito dal 20 dicembre 1582 e in Grecia il 9 marzo 1924 fu seguito dal 23 marzo 1924.

  3. Anche nell'era moderna, vengono usati molti calendari diversi (gregoriano, ortodosso, islamico e cinese) per citarne alcuni, che usano tutti modi diversi per calcolare anni e anniversari o la data delle celebrazioni religiose.

Ora speri in un tipo di data in bundle con operazioni utili per operazioni commerciali generali. Immagino che non esistano operazioni commerciali generali. Ad esempio, nel mondo della finanza, dobbiamo calcolare:

  1. Le frazioni dell'anno (come "6 mesi" corrispondono a "0,5"), che vengono utilizzate insieme a un tasso di interesse per calcolare l'interesse effettivo su un prestito per un determinato periodo. Esistono da 6 a 10 ricette per calcolare queste frazioni, ognuna diversa per il modo in cui gestiscono la durata di un anno bisestile, la posizione del periodo rispetto all'ultimo giorno di febbraio e la durata di un mese.

  2. Durante il calcolo delle ricorrenze, usiamo un calendario aziendale e una regola (scelti da una serie di più di 6 regole diverse) per spostare un anniversario da una vacanza a un giorno lavorativo.

Per le persone che lavorano nel settore finanziario, qualsiasi tipo di calendario che non implementa tutte queste funzioni e regole è inutile. È probabile che molte altre industrie abbiano altri tipi di abitudini e convenzioni che richiedono calcoli personalizzati sul calendario.

Esiste un valore in un'applicazione esplicitamente inteso come un'applicazione di pianificazione nella definizione di una classe Date o "l'approccio migliore è sempre impostato su mezzogiorno"? Quali potrebbero essere i problemi con l'utilizzo di DateTime e l'impostazione del componente Time su Noon? È possibile tenere conto del trasferimento del fuso orario in un simile approccio? Ho usato MomentJS, ma penso che sia solo una migliore classe Date.

Se è necessario tenere traccia di un singolo giorno di calendario, il modo migliore è probabilmente quello di utilizzare un numero intero grande che rappresenti il ​​giorno giuliano di quel giorno di calendario. Gli algoritmi per convertire avanti e indietro dal giorno giuliano al giorno di calendario - descritti con anno, mese e calendario - sono ampiamente conosciuti e accuratamente testati, in modo da poterli implementare facilmente nella tua applicazione - e capire quale regola è pertinente nella tua caso per calcolare l'anniversario di un evento che si è verificato il 29 febbraio.


2

Penso che Mike Nakis nella sua risposta sopra faccia un lavoro migliore di quello che posso per spiegare come il tempo in generale sia una coordinata misurata assoluta e qualsiasi altra comunicazione, stato presunto o persistenza di quella coordinata temporale sia semplicemente una rappresentazione astratta di detta coordinata temporale.

Parli con tali rappresentazioni quando ti riferisci al Giorno della Settimana semplicemente come un qualche tipo di modulo di rappresentazione di un momento reale nel tempo. In realtà è un po 'più complicato di così. Se ti è stato assegnato il compito di scrivere una funzione che restituirà il Giorno della settimana per un determinato momento, considera le seguenti informazioni che ti serviranno come input per tale algoritmo. Richiederai il punto nel tempo, il Calendario, il fuso orario da tenere in considerazione (tieni presente che i fusi orari cambiano TUTTO IL TEMPO, quindi devi sapere quando è iniziato quel fuso orario efficace quando si è concluso con coordinate temporali specifiche. La Corea del Nord ha recentemente appena hanno cambiato il loro ad esempio!), e se è in vigore l'ora legale, anche questo cambia nel tempo. Ora considera se ti è stato dato un DateTime nel fuso orario locale,

Puoi vedere quanto possa essere veramente complicata questa domanda apparentemente semplice.

Conosco il dolore che provi mentre ero nei tuoi panni ad un certo punto risolvendo tutti i bug in un'applicazione di pianificazione delle visite per un prodotto che era stato scritto da sviluppatori inesperti. L'intera cosa ha dovuto essere demolita.

Il tempo è davvero una coordinata, ma oltre a una semplice Data, considera altri dati sensibili al tempo che potrebbero essere necessari come:

Durata: potrebbe verificarsi un intervallo di millisecondi che indica una lunghezza o un passaggio di tempo senza specifiche coordinate temporali specificate. Un caso d'uso potrebbe essere,

Come utente, vorrei che questo compito venisse eseguito 15 secondi dopo il completamento del lavoro di mezzanotte ogni due mercoledì.

Intervallo: intervallo di tempo tra due coordinate temporali specifiche. Un caso d'uso in cui potresti voler considerare un intervallo.

Come utente, devo vedere tutti i giorni del mese interamente contenuti entro un intervallo di tempo specificato.

Un altro punto rapido che volevo sottolineare è che hai fatto un commento sui numeri in virgola mobile per i dati basati sul tempo e sconsiglio. L'aritmetica in virgola mobile porta inevitabilmente a errori di arrotondamento che potrebbero non fornire una misurazione tanto precisa quanto necessaria per il tempo.

Quindi, in conclusione, tutte queste informazioni portano inevitabilmente alle seguenti considerazioni di progettazione:

  • Punti o intervalli specifici nel tempo devono essere mantenuti in UTC o in alcuni tipi di dati che contengono informazioni sufficienti per essere facilmente astratti in UTC dove necessario
  • La logica dell'applicazione deve essere scritta per formattare UTC o un intervallo di coordinate UTC in uno stato di dati rappresentativo più digeribile per l'utente finale.
  • Le durate importanti dovrebbero essere mantenute in millisecondi
  • Le preferenze specifiche della locale o dell'utente finale sulla visualizzazione di qualsiasi dato relativo al tempo devono essere mantenute come dati aggiuntivi e trattate come un'opzione di visualizzazione. (Ad es. Kiosk A, fuso orario centrale, formato dell'ora militare o preferenze dell'utente B, ora standard a Tel Aviv (GMT + 7: 00) fuso orario, ecc ...)
  • Evita i numeri FP

1
Niente di tutto questo è "inevitabile". Può essere comune per molte applicazioni, ma il Large Hadron Collider si occupa di eventi su scala dei nanosecondi. I tempi di sistema sono passati a microsecondi perché i millisecondi non hanno una precisione sufficiente. Le app di calendario devono avere un concetto di data che si verifica in un giorno di calendario locale indipendentemente dal fatto che tu sia o meno nello stesso fuso orario in cui hai creato l'evento.
Alan Shutko,

1
@AlanShutko E sì, i "dati aggiuntivi" necessari sono elementi come il fuso orario locale, i giorni e qualsiasi altro dato importante che deve essere acquisito. Queste sono solo astrazioni tuttavia per un singolo punto nel tempo, anche se il punto nel tempo non è importante per il tuo algoritmo. Per quanto riguarda i nanosecondi e persino la scala dei microsecondi, la mia risposta è orientata maggiormente verso software di tipo web e LOB. Dubito che il linguaggio scelto da LHC sia C # o Javascript.
maple_shaft

1
I millisecondi sono ottimi per processi fisici ripetibili. Per l'attività umana, a volte l'unità appropriata è un giorno nominale, ad esempio se spedita alla fine della giornata sarà disponibile per l'uso a destinazione tre giorni dopo.
Kevin Cline,

In passato ho preso in considerazione l'utilizzo di numeri in virgola mobile a 64 bit per le coordinate temporali e, soprattutto, per gli intervalli di tempo, perché consentono di esprimere piccole quantità con grande precisione, così come enormi quantità, in cui la perdita di precisione non conta davvero . (Quindi cosa succede se i dinosauri sono morti 65 milioni di anni fa, ne danno o ne prendono alcuni?) Quindi, perché dici che dovrebbero essere evitati?
Mike Nakis,

Mike, penso che la sua preoccupazione sia per la matematica di FP inevitabilmente arrotondata mentre si sta convertendo da valori decimali a valori binari. Ad esempio, 0,3 è un decimale ripetuto quando espresso come un numero FP binario e quindi non può essere rappresentato esattamente. Non è che ti manchi la capacità, ma ti manca la precisione.
Michael Blackburn,

2

In breve, perché la maggior parte dei tipi di orario basati su computer sono focalizzati sulla gestione corretta dell'ora e del fuso orario.

Ci sono 2 casi limite che non sono ben serviti dal solito approccio. L'impostazione di un punto temporale che si trova dall'altra parte di una modifica dell'ora legale utilizzando l'ora locale, che viene quindi convertita nell'ora UTC da un livello di astrazione inferiore e quindi ti consente di arrivare 1 ora prima / tardi per la riunione.

L'altro sta modellando (secondo la domanda) informazioni sulla data arbitrarie, come la registrazione della data di nascita di una persona. Immagina il caso in cui due persone sono nate contemporaneamente, una in Nuova Zelanda, l'altra alle Hawaii. La probabilità è che abbiano diverse date di nascita sui loro passaporti e se la persona nata alle Hawaii si trasferisce in Nuova Zelanda, sarà considerata un giorno più vecchia della persona nata in Nuova Zelanda, nonostante abbia vissuto esattamente nello stesso momento.

Il suggerimento nella domanda come impostare la data per avere un'ora di mezzogiorno, UTC funzionerà, QUASI ovunque. Gli offset UTC vanno da -12 a +14, quindi ci sono alcuni punti nel Pacifico dove questo approccio fallirà. Tendo a trattare questi tipi di dati come stringhe, in un formato yyyymmdd, e se devo fare calcoli di confronto tra due date, questo può essere tranquillamente fatto come un confronto di stringhe. Quando si eseguono confronti delta (ad es. Tra data e ora, o per quanto tempo prima che raggiungano l'età X), è necessario assicurarsi che tutte le date vengano create nello stesso offset UTC e quindi utilizzare le funzioni di ora standard per eseguire il lavoro.


3
" Tendo a trattare questi tipi di dati come stringhe, in un formato yyyymmdd, e se devo fare calcoli di confronto tra due date, questo può essere tranquillamente fatto come un confronto di stringhe. " Questo suona sicuramente come un Datetipo di dati, appena portato dentro aString
Ross Patterson,

Proprio come dici tu, è una rappresentazione in forma di stringa di una data e, diversamente dal poster originale, la data non viene modificata essendo in un fuso orario UTC + 13.
Michael Shaw,

2

Perché non esiste un vero tipo di dati "Solo data"?

Per le stesse ragioni, penso, che i valori di DateTime siano generalmente specificati in UTC: semplicità e affidabilità . Il punto di un valore DateTime è specificare un singolo punto nel tempo che non è interessato da fuso orario, ora legale, calendario e altre regolazioni locali. I valori DateTime specificano un istante (fino al limite della risoluzione del tipo), non un periodo di tempo o un insieme di orari. Queste limitazioni consentono di confrontare i valori di DateTime in modo affidabile, prevedibile e semplice.

Cercare di specificare una data con un valore DateTime è come provare a usare un punto per specificare un'area.Puoi farlo funzionare usando una convenzione, come "questo punto rappresenta il centro di un cerchio con un raggio di 100 m", ma ci sono molti problemi lì: tutti devono usare la stessa convenzione, devi scrivere un sacco di codice di supporto per rendere meno doloroso lavorare con il tipo sbagliato ed è praticamente garantito che ad un certo punto dovrai specificare un'area più grande o più piccola dell'area convenzionale. Lo stesso vale per le date: puoi usare "mezzogiorno" come orario convenzionale per specificare le date, ma poi entri nei fusi orari perché le persone si aspettano di specificare le date nell'ora locale anziché nell'ora UTC. E anche se trovi un modo soddisfacente per utilizzare un DateTime per specificare una data, avrai bisogno di maggiori informazioni per sapere se è una data assoluta o relativa: è il 4 luglio, 1776 o ogni 4 luglio? Cosa succede se si desidera ripetere utilizzando un altro periodo? E i calendari hanno ogni sorta di problemi folli: alcuni mesi sono più lunghi di altri, alcuni anni sono più lunghi di altri, alcuni giorni sono anche più lunghi di altri e alcuni calendari presentano delle lacune. Non vorresti risolvere questi problemi solo per intere giornate, perché gli stessi problemi si presentano per periodi più brevi: probabilmente ti piacerebbe essere in grado di scrivere codice che esprima "prendi 1 pillola ogni 4 ore" con la stessa prontezza di "il il gruppo si riunisce ogni terzo venerdì ".

Quindi, ci sono molte complicazioni nel lavorare con le date. È relativamente (senza intendere il gioco di parole) facile fornire un tipo che specifica un momento nel tempo e lavorare con esso come faresti con un numero, ma estremamente difficile fornire un tipo che affronti tutti i modi in cui le date vengono utilizzate.

Come altri hanno sottolineato, ci sono lingue e librerie che forniscono un buon supporto per le date, ed è spesso una buona idea usarle dato che è abbastanza difficile ottenere esattamente il codice relativo alla data.


2
"Difficile fornire un tipo che affronti tutti i modi in cui vengono utilizzate le date." È vero, ecco perché è un'idea orribile provare a fornire un solo tipo per fare tutto. Le prime versioni di Java hanno fornito solo java.util.Date e il risultato è stato orribile. Quindi hanno aggiunto una complessa gerarchia java.util.Calendar e non è andata molto meglio.
Kevin Cline,

1
@kevincline Completamente d'accordo. OP non ha specificato una lingua, quindi miravo alla generalità.
Caleb,

" Per le stesse ragioni, penso, che i valori di DateTime siano generalmente specificati in UTC " ... Oh, sarebbe vero. È il 2015 e c'è ancora molto codice da scrivere usando il fuso orario di casa dell'autore :-(
Ross Patterson,

1
Mi stavo davvero chiedendo perché non ci fosse una convenzione generalmente accettata in merito alle date. Il tuo "utilizzo di un punto per rappresentare un'area" incapsula perfettamente la mia frustrazione.
Michael Blackburn,

2

Perché non esiste un vero tipo di dati "Solo data"?

Esistono molti tipi di questo tipo in varie librerie per varie lingue. Ce n'è quasi sicuramente uno per la tua lingua attuale. Il pacchetto util Java aveva un'API orribile per i calcoli del tempo, ma l'introduzione del pacchetto java.time ha reso la vita molto migliore. Vedi java.time.LocalDate, contenente un valore per anno-mese-giorno o java.time.MonthDay, contenente solo un numero di mese e giorno.


1

La manipolazione di calendari è uno degli aspetti più comprensibili dell'informatica. Interi libri sono stati scritti sull'argomento. @MichealBlackburn ha assolutamente ragione nel chiedere un tipo di dati solo per la data, uno che non si risolve fino a un punto su una sequenza temporale, soggetto a reinterpretazione. Storicamente, ci sono state legittime controversie sul significato di una data. Non si deve guardare oltre l'adozione del calendario gregoriano per scoprire quanto possa essere complesso. Inoltre, gli anni non sono sempre iniziati il ​​1 ° gennaio, nemmeno nell'Europa occidentale e nelle sue colonie ( ad esempio , la Gran Bretagna e l'America britannica hanno iniziato l'anno il 25 marzo).


1
È giusto. Il calendario FAQ che cito nella mia risposta è un'ottima risorsa per scoprire le complessità e le sottigliezze delle manipolazioni clandestine
Michael Le Barbier Grünewald,

-2

In risposta a:

Bene, vorrei sinceramente sapere perché quasi tutte le lingue hanno un solo tipo di dati per questo.

Il motivo più comune potrebbe essere "perché non è necessario". Se si desidera un orario di data che non si preoccupa di ore, minuti, secondi, ecc., È necessario inizializzarlo in questo modo:

date = new DateTime(year, month, day, 0, 0, 0);

Se lo desideri, puoi estendere DateTime tu stesso:

public class Date extends DateTime {
    ...
    public Date(int year, int month, int day) {
        this(year, month, day, 0, 0, 0);
    }
}

Nota: sto intenzionalmente ignorando l'ora e il fuso orario predefiniti. Non importa davvero cosa li hai impostati, a condizione che siano gli stessi per tutti Date. Puoi presentare una richiesta per UTC. Puoi fare un caso per utilizzare il fuso orario in cui si trova il tuo server - in entrambi i casi non credo sia importante per rappresentare un valore impreciso come Date. Lo stesso con l'ora predefinita: puoi impostarlo su 0, puoi farlo a mezzogiorno. Non importa Se Facebook mi invia una notifica di compleanno alle 00:01 ma sono nato alle 23:59, non mi interessa davvero, e non mi offenderò per il fatto che siano stati più di 12 ore libere.

Quanto sopra è in Java, ma funzionerebbe in modo simile in qualsiasi lingua con a DateTimeed ereditarietà. Java in realtà ha molti modi per risolvere questo problema e quanto sopra è deprecato (vogliono che tu lo usi Calendarora). Ma, come gli altri ha scritto in commenti, alcune lingue in realtà non forniscono una Dateclasse, presumibilmente proprio per questo motivo.

Con ogni probabilità, ogni Dateimplementazione è probabilmente solo un wrapper per il linguaggio DateTimee azzera i tempi. Altrimenti avresti bisogno di un codice duplicato per risolvere problemi come il numero di giorni tra due Date / DateTimes o se due Dates sono uguali (che dire di 29 febbraio e 1 marzo?). Questi tipi di cose sono generalmente risolti in DateTimeclasse. Ha senso riutilizzare lo stesso codice per a Date.


4
-1: Usa LocalDate se vuoi solo anno + mese + giorno. L'uso di DateTime a tale scopo porterà a bug quando un altro programmatore vede DateTime e presume che rappresenti un momento nel tempo.
Kevin Cline,

@kevincline Non pensavo fosse necessario perché questa domanda è indipendente dalla lingua. Penserei anche che sia ovvio che l'uso del codice etichettato "obsoleto" sia uno scenario a rischio tuo. Ancora più importante, l'ho usato solo come esempio di qualcosa che puoi fare in uno scenario in cui una lingua non ha una LocalDate, o Datedigita una classe e devi 'roll-your-own'.
Shaz,

1
Ma "è necessario" per un codice chiaro, conciso e corretto, che coinvolga le regole aziendali sul tempo (al contrario del tempo fisico). se la libreria non fornisce tipi per il tempo nominale, sarà necessario che il programmatore li inventa e il modo per farlo non inizia con "DateTime".
Kevin Cline,

@kevincline Non vedo come il codice sarebbe meno chiaro o conciso. Qual è la differenza dal punto di vista di un programmatore tra new Date(2000, 1, 1);e new Date(2000, 1, 1);? Puoi dire quale ha ore, minuti e secondi vuoti sotto? Se sei preoccupato per le funzioni extra che appaiono (come setMinutes ()), allora potresti seguire la strada del Datewrapping DateTimeinvece di ereditarne, e quindi esporre solo setYear, setMonth, setDay, ecc. E certamente non è da meno corretto rispetto al DateTime della libreria che si sta utilizzando.
Shaz,

Il mio background è in gran parte C #, che non ha un costrutto analogo a LocalDate. Abbiamo appena appena DateTime e abbiamo confuso, a quanto pare.
Michael Blackburn,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.