Joda-Time
Jeśli chodzi o dodawanie zależności, obawiam się, że java.util.Date & .Calendar są tak złe, że pierwszą rzeczą, którą robię w każdym nowym projekcie, jest dodanie biblioteki Joda-Time. W Javie 8 możesz użyć nowego pakietu java.time, zainspirowanego Joda-Time.
Rdzeniem Joda-Time jest DateTime
klasa. W przeciwieństwie do java.util.Date, rozumie przypisaną strefę czasową ( DateTimeZone
). Podczas konwersji z juDate przypisz strefę.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTimeQuébec = new DateTime( date , zone );
LocalDate
Jednym ze sposobów sprawdzenia, czy dwie daty wylądują w tym samym dniu, jest konwersja na LocalDate
obiekty.
Ta konwersja zależy od przypisanej strefy czasowej. Aby porównać LocalDate
obiekty, muszą zostać przekonwertowane na tę samą strefę.
Oto mała metoda użyteczności.
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;
}
Lepszym rozwiązaniem byłby kolejny argument, określający strefę czasową zamiast zakładania, że należy użyć strefy czasowej pierwszego obiektu DateTime.
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 );
}
Reprezentacja łańcucha
Innym podejściem jest utworzenie ciągu reprezentującego część daty dla każdej daty i godziny, a następnie porównanie ciągów.
Ponownie, przypisana strefa czasowa ma kluczowe znaczenie.
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;
Przedział czasu
Uogólnione rozwiązanie polega na zdefiniowaniu przedziału czasu, a następnie zapytaniu, czy przedział zawiera cel. Ten przykładowy kod znajduje się w Joda-Time 2.4. Zauważ, że klasy związane z „północą” są przestarzałe. Zamiast tego użyj withTimeAtStartOfDay
metody. Joda-Time oferuje trzy klasy reprezentujące przedział czasu na różne sposoby: Interwał, Okres i Czas trwania.
Stosując podejście „półotwarte”, w którym początek zakresu jest włączający, a zakończenie wyłączny.
Strefa czasowa celu może być inna niż strefa czasowa przedziału.
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 i nowsze wersje są dostarczane ze środowiskiem java.time . Zainspirowany przez Joda-Time, zdefiniowany przez JSR 310 i rozszerzony przez projekt ThreeTen-Extra. Zobacz samouczek .
Twórcy Joda-Time poinstruowali nas wszystkich, abyśmy jak najszybciej przenieśli się na java.time. W międzyczasie Joda-Time kontynuuje działalność jako aktywny projekt. Ale oczekuj, że przyszłe prace pojawią się tylko w java.time i ThreeTen-Extra, a nie w Joda-Time.
Podsumowując java.time w pigułce… Instant
To moment na osi czasu w UTC. Zastosuj strefę czasową ( ZoneId
), aby uzyskać ZonedDateTime
obiekt. Aby przenieść się na osi czasu, aby uzyskać mgliste pojęcie o nieokreśloną datę czasie, korzystać z „lokalnych” klas: LocalDateTime
, LocalDate
, LocalTime
.
Logika omówiona w części Joda-Time tej odpowiedzi dotyczy java.time.
Stara klasa java.util.Date ma nową toInstant
metodę konwersji na java.time.
Instant instant = yourJavaUtilDate.toInstant(); // Convert into java.time type.
Określenie daty wymaga strefy czasowej.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
Stosujemy ten obiekt strefy czasowej w Instant
celu uzyskania ZonedDateTime
. Z tego wyodrębniamy wartość tylko daty (a LocalDate
), ponieważ naszym celem jest porównywanie dat (nie godzin, minut itp.).
ZonedDateTime zdt1 = ZonedDateTime.ofInstant( instant , zoneId );
LocalDate localDate1 = LocalDate.from( zdt1 );
Zrób to samo z drugim java.util.Date
obiektem, którego potrzebujemy do porównania. Zamiast tego wykorzystam bieżący moment.
ZonedDateTime zdt2 = ZonedDateTime.now( zoneId );
LocalDate localDate2 = LocalDate.from( zdt2 );
Użyj specjalnej isEqual
metody, aby przetestować tę samą wartość daty.
Boolean sameDate = localDate1.isEqual( localDate2 );