Joda-Time
Per quanto riguarda l'aggiunta di una dipendenza, temo che java.util.Date e .Calendar siano davvero così male che la prima cosa che faccio a qualsiasi nuovo progetto è aggiungere la libreria Joda-Time. In Java 8 è possibile utilizzare il nuovo pacchetto java.time, ispirato a Joda-Time.
Il nucleo di Joda-Time è la DateTime
classe. A differenza di java.util.Date, comprende il fuso orario assegnato ( DateTimeZone
). Durante la conversione da juDate, assegnare una zona.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTimeQuébec = new DateTime( date , zone );
LocalDate
Un modo per verificare se due date-time arrivano alla stessa data è convertire in LocalDate
oggetti.
Tale conversione dipende dal fuso orario assegnato. Per confrontare gli LocalDate
oggetti, devono essere stati convertiti con la stessa zona.
Ecco un piccolo metodo di utilità.
static public Boolean sameDate ( DateTime dt1 , DateTime dt2 )
{
LocalDate ld1 = new LocalDate( dt1 );
// LocalDate determination depends on the time zone.
// So be sure the date-time values are adjusted to the same time zone.
LocalDate ld2 = new LocalDate( dt2.withZone( dt1.getZone() ) );
Boolean match = ld1.equals( ld2 );
return match;
}
Meglio sarebbe un altro argomento, specificando il fuso orario piuttosto che assumere il fuso orario del primo oggetto DateTime dovrebbe essere usato.
static public Boolean sameDate ( DateTimeZone zone , DateTime dt1 , DateTime dt2 )
{
LocalDate ld1 = new LocalDate( dt1.withZone( zone ) );
// LocalDate determination depends on the time zone.
// So be sure the date-time values are adjusted to the same time zone.
LocalDate ld2 = new LocalDate( dt2.withZone( zone ) );
return ld1.equals( ld2 );
}
Rappresentazione di stringhe
Un altro approccio è quello di creare una rappresentazione in forma di stringa della parte della data di ciascuna data-ora, quindi confrontare le stringhe.
Ancora una volta, il fuso orario assegnato è cruciale.
DateTimeFormatter formatter = ISODateTimeFormat.date(); // Static method.
String s1 = formatter.print( dateTime1 );
String s2 = formatter.print( dateTime2.withZone( dt1.getZone() ) );
Boolean match = s1.equals( s2 );
return match;
Lasso di tempo
La soluzione generalizzata è definire un intervallo di tempo, quindi chiedere se l'intervallo contiene il tuo obiettivo. Questo codice di esempio è in Joda-Time 2.4. Si noti che le classi correlate a "mezzanotte" sono obsolete. Utilizzare invece il withTimeAtStartOfDay
metodo Joda-Time offre tre classi per rappresentare un arco di tempo in vari modi: intervallo, periodo e durata.
Utilizzando l'approccio "Half-Open" in cui l'inizio dell'intervallo è inclusivo e la fine esclusiva.
Il fuso orario del target può essere diverso dal fuso orario dell'intervallo.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime target = new DateTime( 2012, 3, 4, 5, 6, 7, timeZone );
DateTime start = DateTime.now( timeZone ).withTimeAtStartOfDay();
DateTime stop = start.plusDays( 1 ).withTimeAtStartOfDay();
Interval interval = new Interval( start, stop );
boolean containsTarget = interval.contains( target );
java.time
Java 8 e versioni successive vengono forniti con il framework java.time . Ispirato da Joda-Time, definito da JSR 310, e ampliato dal progetto ThreeTen-Extra. Vedi Tutorial .
I creatori di Joda-Time hanno dato istruzioni a tutti noi di passare a java.time non appena è conveniente. Nel frattempo Joda-Time continua come progetto attivamente mantenuto. Ma aspettatevi che i lavori futuri avvengano solo in java.time e ThreeTen-Extra piuttosto che in Joda-Time.
Riassumendo java.time in breve ... An Instant
è un momento sulla linea temporale in UTC. Applicare un fuso orario ( ZoneId
) per ottenere un ZonedDateTime
oggetto. Per spostare fuori la linea temporale, per avere l'idea indefinita vaga di un data-ora, utilizzare le classi "locali": LocalDateTime
, LocalDate
, LocalTime
.
La logica discussa nella sezione Joda-Time di questa risposta si applica a java.time.
La vecchia classe java.util.Date ha un nuovo toInstant
metodo per la conversione in java.time.
Instant instant = yourJavaUtilDate.toInstant(); // Convert into java.time type.
Determinare una data richiede un fuso orario.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
Applichiamo quell'oggetto fuso orario al Instant
per ottenere un ZonedDateTime
. Da ciò estraiamo un valore di sola data (a LocalDate
) poiché il nostro obiettivo è confrontare date (non ore, minuti, ecc.).
ZonedDateTime zdt1 = ZonedDateTime.ofInstant( instant , zoneId );
LocalDate localDate1 = LocalDate.from( zdt1 );
Fai lo stesso con il secondo java.util.Date
oggetto di cui abbiamo bisogno per il confronto. Userò solo il momento attuale invece.
ZonedDateTime zdt2 = ZonedDateTime.now( zoneId );
LocalDate localDate2 = LocalDate.from( zdt2 );
Utilizzare il isEqual
metodo speciale per verificare lo stesso valore di data.
Boolean sameDate = localDate1.isEqual( localDate2 );