Joda-Time: DateTime, DateMidnight e l'uso LocalDate
Domanda
Joda Time comprende diverse classi datetime
DateTime - sostituzione Immutabile per JDK Calendario
DateMidnight - Classe Immutabile che rappresenta una data in cui il tempo è costretto a mezzanotte
LocalDateTime - Classe Immutabile che rappresenta un locale data e ora (senza fuso orario)
Mi chiedo come stai usando queste classi nel vostro Applicazioni stratificate .
vedo vantaggi nell'avere quasi tutte le interfacce utilizzando LocalDateTime (al livello di servizio almeno) in modo che la mia domanda non ha per gestire Fusi orari e può tranquillamente assumere Volte sempre in UTC. La mia app potrebbe quindi utilizzare DateTime per gestire Timezones proprio all'inizio del flusso del Execution.
Sto anche chiedendo in quale scenario può DateMidnight essere utile.
Soluzione
vedo vantaggi nell'avere quasi tutti interfacce utilizzando LocalDateTime (at il livello di servizio, almeno) in modo che la mia L'applicazione non deve gestire Fusi orari e possono avere la certezza tempi sempre in UTC.
Non sono sicuro di aver capito la tua linea di pensiero qui. LocalDateTime
e DateTime
rappresentano due concetti molto diversi. Non è il caso che un LocalDateTime
ha qualche fuso orario UTC implicita: in realtà ha non fuso orario (internamente può essere rappresentato come un DateTime
con fuso orario UTC, ma è solo un dettaglio di implementazione, non importa a il programmatore che lo usa).
Si può vedere nella documentazione API che, mentre un DateTime
è un " Instant
" (un punto nella linea del tempo del mondo, un concetto fisico), un LocalDateTime
non è una cosa del genere. Il LocalDateTime
è in realtà un Partial
, (una " concetto civile"), in una gerarchia di classe diversa. I nomi classi potrebbero -unfortunately- fanno pensare che LocalDateTime
è una certa specializzazione delle DateTime
: bene, non è
Un LocalDateTime
deve essere considerato come una coppia { Date
(Y/M/D
); Time
(hh:mm:ss.msec
)}, una serie di numeri che corrisponde alla rappresentazione standard "civile" di dati temporali. Se ci viene dato un LocalDateTime
, non siamo in grado di convertire direttamente ad un DateTime
, abbiamo bisogno di specificare un fuso orario; e che la conversione ci porta a un altro tipo di entità. (Un'analogia: stringhe e flussi di byte in Java: per la conversione tra di loro è necessario specificare una codifica caratteri, perché sono cose concettualmente differenti)
Quando utilizzare uno o l'altro nell'applicazione ... a volte è discutibile, ma spesso è abbastanza chiara, una volta che i concetti Jodatime sono capiti. E IMO non è molto legato alla "strati", forse più di casi d'uso o scenari.
Un esempio -borderline- non banale: Si lavora in Google, la programmazione del calendario. È necessario permettere all'utente di gestire (aggiungere, vedere, modificare) un evento che comprende un data-ora (lascia ignorare eventi ricorrenti), dire " Ho un appuntamento con il mio medico il 2019-Luglio-3 alle 10:00 am ". Qual è l'entità di tempo data da utilizzare nello strato software (per questo usecase )? Direi: un LocalDateTime
. Poiché l'utente non è realmente a che fare con un punto fisico nel tempo, ma con un tempo civile: la data e l'ora che visualizza l'orologio al polso o nella sua casa. Egli non pensa neppure di fusi orari (lascia ignorare il caso particolare di un utente che è in giro per il mondo ...) Poi, nello strato di bussiness e la presentazione, un LocalDateTime
sembra l'entità destra.
Ma supponiamo che si deve anche il codice uno scenario diverso: un promemoria. Quando lo scheduler interno Google rileva che l'evento memorizzato dall'utente è N minuti nel futuro da oggi, lo deve inviare un promemoria. Qui, " N minuti da oggi " è un concetto totalmente "fisica" del tempo, ecco il "livello di business" si occuperebbe di un DateTime
. Ci sono diverse alternative, ad esempio: l'evento è stato memorizzato nel DB come LocalDateTime
(cioè solo il tempo e la data, senza fuso orario - si usa spesso un timestamp UTC per rappresentare che, ma questo dettaglio un'implementazione.). In questo scenario (solo in questo) dobbiamo caricarlo come un DateTime
, convertiamo utilizzando un fuso orario, probabilmente dal profilo dell'utente.
Altri suggerimenti
La risposta da leonbloy sia corretto e di vitale importanza. Sto semplicemente traducendo alle classi java.time che sostituiscono il progetto Joda-Time.
java.time
momento specifico
Per un momento specifico sulla linea temporale:
- Sempre in UTC è rappresentato da
Instant
. - Assegnato un offset-da-UTC è rappresentato da
OffsetDateTime
. - Assegna un fuso orario pieno, piuttosto che mera compensato è rappresentato da
ZonedDateTime
.
Questi tutti sostituire la classe Instant
& DateTime
a Joda-Time. Queste classi java.time tutti hanno una risoluzione di contro i millisecondi utilizzati da Joda-Time.
Midnight contro Inizio del giorno
Per la mezzanotte, il progetto Joda a tempo parziale concluso “a mezzanotte” è un concetto vago e improduttivo. Le classi e midnights mezzanotte relativi sono stati tutti deprecati nelle versioni successive di Joda-Time, sostituito con il concetto pratico di “primo momento della giornata”.
Le classi java.time hanno preso la stessa lezione, utilizzando un "primo momento della giornata" approccio. Cercare metodi atStartOfDay
su classi java.time quali LocalDate
.
Mai dare per scontato una giornata inizia alle 00:00. Anomalie come l'ora legale (DST) significano la giornata può iniziare in altri momenti, come 01:00.
ZonedDateTime zdt =
LocalDate.of( 2017 , Month.MARCH , 12 ) // Instantiate a date-only value without time zone.
.atStartOfDay( ZoneId.of( "America/Havana" ) ) ; // Cuba jumps from 00:00 to 01:00 on Spring DST cut-over.
Per esempio, vedere come Cuba inizia la giornata al 1:00 sulla loro Primavera DST cut-over.
zdt: 2017-03-12T01: 00-04: 00 [America / Havana]
Unzoned
Per rappresentare l'idea vaga di possibili momenti in un range di circa 26-27 ore, ma non un vero e proprio momento sulla timeline, utilizzare LocalDateTime
. Questa classe manca volutamente qualsiasi offset da-UTC o il fuso orario.
LocalDateTime ldt = LocalDateTime.of( 2017 , Month.JANUARY , 23 , 1 , 2 , 3 , 0 ) ;
Se il contesto di business implica un fuso orario specifico, è possibile applicarlo per ottenere un ZonedDateTime
.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ; // Determine a specific point on timeline by providing the context of a time zone.
A proposito di java.time
Il java.time quadro è integrato in Java 8 e versioni successive. Queste classi soppiantare la fastidiosi come java.util.Date
, Calendar
, e SimpleDateFormat
.
Il Joda Time progetto, ora in modalità manutenzione , consiglia migrazione al classi java.time .
Per ulteriori informazioni, vedere la Oracle Tutorial . E cercare Stack Overflow per molti esempi e spiegazioni. Le specifiche sono JSR 310 .
Dove ottenere le classi java.time?
- Java SE 8 , Java SE 9 , e più tardi
- Built-in.
- Parte delle API Java standard con un'implementazione in bundle.
- Java 9 aggiunge alcune funzionalità minori e correzioni.
- Java SE 6 e Java SE 7
- La maggior parte delle funzionalità java.time è di back-porting per Java 6 & 7 a ThreeTen-Backport .
- Android
- Il ThreeTenABP progetto adatta < em> ThreeTen-Backport (di cui sopra) per Android in particolare.
- Come utilizzare ThreeTenABP ... .
Il ThreeTen-Extra progetto estende java.time con classi aggiuntive. Questo progetto è un banco di prova per eventuali aggiunte future java.time. Si possono trovare alcune classi utili, come per esempio Interval
, YearWeek
, YearQuarter
, e informazioni .