Mam problemy z klasą Date w Javie. Klasa Date zwraca lokalną datę maszyny, ale potrzebuję UTC-0.
Wyszukałem w Google i znalazłem świetne rozwiązanie dla JavaScript, ale dla Javy nic przydatnego.
Jak uzyskać datę UTC + 0 w Javie 8?
Mam problemy z klasą Date w Javie. Klasa Date zwraca lokalną datę maszyny, ale potrzebuję UTC-0.
Wyszukałem w Google i znalazłem świetne rozwiązanie dla JavaScript, ale dla Javy nic przydatnego.
Jak uzyskać datę UTC + 0 w Javie 8?
Odpowiedzi:
W Javie 8 możesz pisać:
OffsetDateTime utc = OffsetDateTime.now(ZoneOffset.UTC);
Aby odpowiedzieć na swój komentarz, możesz następnie przekonwertować go na datę (chyba że polegasz na starszym kodzie, nie widzę żadnego powodu) lub na milis od epok:
Date date = Date.from(utc.toInstant());
long epochMillis = utc.toEpochSecond() * 1000;
OffsetDateTime, niż ZonedDateTimebiorąc pod uwagę, że pracujemy z przesunięciem względem UTC, a nie z pełną strefą czasową?
Instant.now()
Kłopotliwe stare klasy daty i godziny dołączone do najwcześniejszych wersji Javy zostały zastąpione przez klasy java.time wbudowane w Javę 8 i nowsze. Zobacz samouczek Oracle . Wiele funkcji zostało przeniesionych do Java 6 i 7 w ThreeTen-Backport i dodatkowo dostosowanych do systemu Android w ThreeTenABP .
InstantSymbol Instantreprezentuje moment na osi czasu w UTC z rozdzielczością do nanosekund .
Instant instant = Instant.now();
toStringMetoda generuje obiekt String z tekstem reprezentującego wartość data-czas, korzystając z jednego ze standardowych ISO 8601 formatach.
String output = instant.toString();
2016-06-27T19: 15: 25.864Z
InstantKlasa podstawowa klasa budynku blok w java.time. Powinna to być klasa, na którą powinieneś przejść podczas obsługi daty i godziny, ponieważ ogólnie najlepszą praktyką jest śledzenie, przechowywanie i wymiana wartości daty i czasu w UTC.
OffsetDateTimeAle Instantma ograniczenia, takie jak brak opcji formatowania do generowania ciągów w alternatywnych formatach. Aby uzyskać większą elastyczność, przekonwertuj z Instantna OffsetDateTime. Określ przesunięcie od czasu UTC . W java.time oznacza to ZoneOffsetobiekt. Tutaj chcemy trzymać się UTC (+00), abyśmy mogli użyć wygodnej stałej ZoneOffset.UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
2016-06-27T19: 15: 25.864Z
Lub pomiń Instantzajęcia.
OffsetDateTime.now( ZoneOffset.UTC )
Teraz, mając OffsetDateTimeobiekt w dłoni, możesz użyć go DateTimeFormatterdo tworzenia obiektów typu String z tekstem w alternatywnych formatach. Wyszukaj przepełnienie stosu dla wielu przykładów użycia DateTimeFormatter.
ZonedDateTimeJeśli chcesz wyświetlić zegar ścienny dla określonej strefy czasowej, zastosuj ZoneIdznak ZonedDateTime.
W tym przykładzie stosujemy strefę czasową Montréal. Latem, pod nonsensem czasu letniego (DST) , strefa ma przesunięcie -04:00. Zwróć więc uwagę, że pora dnia jest o cztery godziny wcześniejsza 15niż 19godziny. Instanta ZonedDateTimeoba przedstawiają ten sam jednoczesny moment, oglądany tylko przez dwie różne soczewki.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
2016-06-27T15: 15: 25.864-04: 00 [Ameryka / Montreal]
Chociaż powinieneś unikać starych klas daty i godziny, jeśli musisz, możesz konwertować przy użyciu nowych metod dodanych do starych klas. Tutaj używamy java.util.Date.from( Instant )i java.util.Date::toInstant.
java.util.Date utilDate = java.util.Date.from( instant );
I idzie w innym kierunku.
Instant instant= utilDate.toInstant();
Podobnie poszukaj nowych metod dodanych do GregorianCalendar(podklasy Calendar) w celu konwersji na i z java.time.ZonedDateTime.
Struktura java.time jest wbudowana w Javę 8 i nowsze. Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak java.util.Date, Calendar, i SimpleDateFormat.
Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj Stack Overflow, aby znaleźć wiele przykładów i wyjaśnień. Specyfikacja to JSR 310 .
Projekt Joda-Time , obecnie w trybie konserwacji , zaleca migrację do klas java.time .
Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie ma potrzeby stosowania ciągów ani java.sql.*klas. Hibernate 5 i JPA 2.2 obsługują java.time .
Skąd wziąć klasy java.time?
ZonedDateTime, nie byłby potrzebny, ponieważ wszystko ZoneIdbyłoby mapowane na taki, ZoneOffsetktórego moglibyśmy po prostu użyć OffsetDateTime?
W java8 użyłbym Instantklasy, która jest już w UTC i jest wygodna w obsłudze .
import java.time.Instant;
Instant ins = Instant.now();
long ts = ins.toEpochMilli();
Instant ins2 = Instant.ofEpochMilli(ts)
Alternatywnie możesz skorzystać z:
import java.time.*;
Instant ins = Instant.now();
OffsetDateTime odt = ins.atOffset(ZoneOffset.UTC);
ZonedDateTime zdt = ins.atZone(ZoneId.of("UTC"));
Wrócić do Instant
Instant ins4 = Instant.from(odt);
Instant jest to czas lokalny. Z Instantdefinicji jest to UTC. Więc nie ma potrzeby, aby machinacje widoczne w tej odpowiedzi próbowały dostać się do UTC; Instantjuż jest w UTC. Zobacz moją odpowiedź, aby uzyskać więcej informacji i znacznie prostszy kod.
W Java8 używasz nowego interfejsu API czasu i konwertujesz natychmiastową in na ZonedDateTime przy użyciu strefy czasowej UTC
Rozwiązanie 1-liniowe w Javie 8:
public Date getCurrentUtcTime() {
return Date.from(Instant.now());
}
java.util.Datenigdy nie jest datą maszyny lokalnej. Jest zawsze definiowany jako upływające milisekundy od 1970-01-01 względem UTC + 00: 00. Być może zachowanie tej metody wprowadza w błądtoString(), ponieważ rzeczywiście używasz reprezentacji w lokalnej strefie czasowej.