Jaka jest różnica między Instant i LocalDateTime?
Wiem, że:
- Instant jest raczej "techniczną" reprezentacją znaczników czasu (nanosekund) do obliczeń.
- LocalDateTime jest raczej reprezentacją daty/zegara, w tym stref czasowych dla ludzi.
Nadal w końcu IMO oba mogą być brane jako typ dla większości zastosowań aplikacji. Jako przykład: obecnie uruchamiam zadanie wsadowe, w którym muszę obliczyć następny bieg na podstawie dat i staram się znaleźć plusy / minusy między te dwa typy (oprócz nanosekund precision advantage of Instant i time-zone część LocalDateTime).
Czy możesz podać przykłady aplikacji, w których należy używać Tylko Instant lub LocalDateTime?
Edit: uwaga na błędne odczyty dokumentacji LocalDateTime dotyczące precyzji i strefy czasowej
4 answers
Tl;dr
Instant
i LocalDateTime
są dwoma zupełnie różnymi zwierzętami: jedno reprezentuje chwilę, drugie nie.
-
Instant
reprezentuje moment, określony punkt w osi czasu. -
LocalDateTime
przedstawia datę i godzinę dnia. Jednak Brak strefy czasowej lub przesunięcia od UTC, ta klasa nie może reprezentować chwili. Reprezentuje potencjał momentów w przedziale od około 26 do 27 godzin, zakres wszystkie strefy czasowe na całym świecie. WartośćLocalDateTime
jest z natury niejednoznaczna .
Błędne Domniemanie
LocalDateTime
jest raczej reprezentacją daty/zegara, w tym stref czasowych dla ludzi.
Twoje stwierdzenie jest nieprawidłowe: A LocalDateTime
posiada brak strefy czasowej . Brak strefy czasowej to cały punkt tej klasy.
Cytując klasę "doc":
Ta klasa nie przechowuje ani nie reprezentuje strefy czasowej. Zamiast tego jest to opis daty, używany na urodziny, w połączeniu z czasem lokalnym, jak widać na zegar ścienny. Nie może reprezentować chwili na linii czasowej bez dodatkowych informacji, takich jak offset lub Strefa czasowa.
Więc Local…
oznacza "bez stref, bez przesunięcia".
Instant
An Instant
jest momentem na osi czasu w UTC , liczonym nanosekund od epoki pierwszej chwili z 1970 UTC (w zasadzie, patrz Klasa doc dla szczegółów nitty-gritty). Ponieważ większość logiki biznesowej, przechowywania danych i wymiany danych powinna być w UTC, jest to przydatna klasa, którą można często używać.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
OffsetDateTime
Klasa OffsetDateTime
Klasa reprezentuje moment jako datę i godzinę z kontekstem pewnej liczby godzin-minut-sekund przed lub za UTC. Ilość offsetu, liczba godzin-minut-sekund, jest reprezentowana przez ZoneOffset
klasy.
Jeśli liczba godzin-minut-sekund jest równa zeru,OffsetDateTime
reprezentuje moment w UTC taki sam jak Instant
.
ZoneOffset
The ZoneOffset
Klasa reprezentuje offset-from-UTC , liczbę godzin-minut-sekund przed UTC lub za UTC.
A ZoneOffset
to tylko liczba godzin-minut-sekund, nic więcej. Strefa to znacznie więcej, o nazwie i historia zmian w offsecie. Dlatego używanie strefy jest zawsze preferowane niż zwykłe przesunięcie.
ZoneId
A Strefa czasowa jest reprezentowana przez ZoneId
klasy.
Nowy dzień świta wcześniej wParyżu niż wMontréal {77]}, na przykład. Musimy więc przesunąć ręce zegara, aby lepiej odbijało południe (gdy słońce znajduje się bezpośrednio nad głową) dla danego regionu. Im dalej na wschód/zachód od linii UTC w Europie zachodniej / Afryce im większe przesunięcie.
Strefa czasowa jest zbiorem zasad postępowania z korektami i anomaliami praktykowanymi przez lokalną społeczność lub region. Najczęściej spotykaną anomalią jest zbyt popularny lunacy znany jako[190]}Daylight Saving Time (DST) {77]}.Strefa czasowa ma historię przeszłych zasad, obecnych zasad i zasad potwierdzonych na najbliższą przyszłość.
Te zasady zmieniają się częściej niż można się spodziewać. Pamiętaj, aby zachować swoje zasady biblioteki date-time, Zwykle Kopia bazy danych " tz " , aktualna. Aktualizowanie danych jest teraz łatwiejsze niż kiedykolwiek w Javie 8-Oracle wydało narzędzie do aktualizacji strefy czasowej .
Określ właściwą nazwę strefy czasowej w formacie Continent/Region
, na przykład America/Montreal
, Africa/Casablanca
, lub Pacific/Auckland
. Nigdy nie używaj skrótów 2-4 literowych, takich jak EST
lub IST
, ponieważ są one a nie prawdziwymi strefami czasowymi, nie znormalizowanymi, a nawet unikalnymi(!).
Strefa Czasowa = Offset + Zasady korekt
ZoneId z = ZoneId.of( “Africa/Tunis” ) ;
ZonedDateTime
Pomyśl o ZonedDateTime
koncepcyjnie jako {[10] } z przypisanym ZoneId
.
[74]} aby uchwycić aktualną chwilę, jak widać w zegar ścienny czas używany przez ludzi z określonego regionu (strefy czasowej): [78]}Zoneddatetime = (Instant + Zoneid)
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Pass a `ZoneId` object such as `ZoneId.of( "Europe/Paris" )`.
Prawie cały backend, baza danych, logika biznesowa, trwałość danych, wymiana danych powinny wszystko bądź w UTC. Ale do prezentacji dla użytkowników trzeba dostosować się do strefy czasowej oczekiwanej przez użytkownika. Jest to cel klasy ZonedDateTime
I klasy formatera używanych do generowania reprezentacji łańcuchów tych wartości daty i czasu.
ZonedDateTime zdt = instant.atZone( z ) ;
String output = zdt.toString() ; // Standard ISO 8601 format.
Możesz wygenerować tekst w formacie zlokalizowanym za pomocą DateTimeFormatter
.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ) ;
String outputFormatted = zdt.format( f ) ;
Mardi 30 avril 2019 à 23 h 22 min 55 s heure de l ' Inde
LocalDate
, LocalTime
, LocalDateTime
Klasy "local" date time, LocalDateTime
, LocalDate
, LocalTime
, to inny rodzaj stworzeń. Nie są związane z jedną lokalizacją ani strefą czasową. Nie są związane z osią czasu. nie mają prawdziwego znaczenia dopóki nie zastosujesz ich do miejscowości, aby znaleźć punkt na osi czasu.
Słowo "lokalne" w nazwach tych klas może być intuicyjny dla niewtajemniczonych. Słowo to oznacza dowolną miejscowość, lub każdą miejscowość, ale nie konkretną miejscowość.
Tak więc w aplikacjach biznesowych typy "lokalne" nie są często używane, ponieważ reprezentują tylko ogólną ideę możliwej daty lub godziny, a nie konkretnego momentu na osi czasu. Aplikacje biznesowe Zwykle dbają o moment, w którym dotarła faktura, produkt wysłany do transportu, pracownik został zatrudniony lub taksówka opuściła Garaż. Więc biznes programiści aplikacji najczęściej używają klas Instant
i ZonedDateTime
.
Kiedy użyjemy LocalDateTime
? W trzech sytuacjach:
- chcemy zastosować określoną datę i godzinę dnia w wielu lokalizacjach.
- rezerwujemy spotkania.
- mamy planowaną jeszcze nieokreśloną strefę czasową.
Zauważ, że żaden z tych trzech przypadków nie wiąże się z jednym określonym punktem na osi czasu, żaden z nich nie jest momentem.
One time-of-day, multiple chwile
Czasami chcemy reprezentować określoną porę dnia w określonym dniu, ale chcemy zastosować ją w wielu miejscach w różnych strefach czasowych.
Na przykład "Boże Narodzenie zaczyna się o północy 25 grudnia 2015 roku" to LocalDateTime
. Midnight uderza w różnych momentach w Paryżu niż w Montréal, i znowu inny w Seattle i w Auckland {77]}.
LocalDate ld = LocalDate.of( 2018 , Month.DECEMBER , 25 ) ;
LocalTime lt = LocalTime.MIN ; // 00:00:00
LocalDateTime ldt = LocalDateTime.of( ld , lt ) ; // Christmas morning anywhere.
[74]}inny przykład: "firma Acme ma politykę, która zaczyna się o godzinie 12: 30 w każda z jego fabryk na całym świecie " jest LocalTime
. Aby mieć prawdziwe znaczenie, należy zastosować go do osi czasu, aby obliczyć moment 12:30 w fabryce Stuttgart lub 12:30 w fabryce Rabat lub 12:30 w fabryce {304]}Sydney {77]}.
Rezerwacja wizyt
Inną sytuacją do wykorzystania LocalDateTime
jest rezerwacja przyszłych wydarzeń (np. wizyty u dentysty). Te nominacje mogą być na tyle daleko w przyszłości, że ryzykujesz, że politycy przedefiniują czas Strefa. Politycy często dają mało uprzedzeń, a nawet w ogóle nie ostrzegają. Jeśli masz na myśli "3 PM next January 23rd" niezależnie od tego, jak politycy mogą bawić się z zegarem, to nie możesz nagrać chwili – że 3 pm zamienia się w 2 PM lub 4 PM, jeśli region przyjął lub spadł czas letni, na przykład.
Na spotkania, przechowywać LocalDateTime
i ZoneId
, przechowywane oddzielnie. Następnie, podczas generowania harmonogramu, w locie określ moment, wywołując LocalDateTime::atZone( ZoneId )
, aby wygenerować ZonedDateTime
obiekt.
ZonedDateTime zdt = ldt.atZone( z ) ; // Given a date, a time-of-day, and a time zone, determine a moment, a point on the timeline.
W razie potrzeby można dostosować UTC. Wyodrębnij Instant
z ZonedDateTime
.
Instant instant = zdt.toInstant() ; // Adjust from some zone to UTC. Same moment, same point on the timeline, different wall-clock time.
Nieznana Strefa
Niektórzy ludzie mogą używać LocalDateTime
w sytuacji, gdy Strefa czasowa lub przesunięcie jest nieznane.
Wszystkie typy daty i czasu
Dla kompletności, oto tabela wszystkich możliwych typów daty i czasu, zarówno nowoczesnych i starszych w Javie, jak i tych zdefiniowanych przez standard SQL. To może pomóc umieścić Instant
& LocalDateTime
klasy w szerszym kontekście.
Zwróć uwagę na dziwne wybory dokonane przez zespół Javy przy projektowaniu JDBC 4.2. Zdecydowali się wspierać wszystkie java.czas razy ... z wyjątkiem dwóch najczęściej używanych klas: Instant
& ZonedDateTime
.
Konwertowanie Instant
.
// Storing
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
// Retrieving
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;
Konwertowanie ZonedDateTime
.
// Storing
OffsetDateTime odt = zdt.toOffsetDateTime() ;
myPreparedStatement.setObject( … , odt ) ;
// Retrieving
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZone( z ) ;
O Javie.czas
The java.czas framework jest wbudowany w Java 8 i nowsze. Klasy te zastępują kłopotliwe staredziedzictwo klasy date-time, takie jak java.util.Date
, Calendar
, & SimpleDateFormat
.
Aby dowiedzieć się więcej, Zobacz Samouczek Oracle. I wyszukaj przepełnienie stosu dla wielu przykładów i wyjaśnień. Specyfikacja to JSR 310 .
The Joda-czas projekt, obecnie w trybie konserwacji , radzi migrację do java.czas klasy.
Możesz wymienić Javę.obiekty time {[89] } bezpośrednio z bazą danych. Użyj sterownika JDBCzgodnego z JDBC 4.2 lub nowszego. No need for strings, no need for Klasy. Hibernate 5 & JPA 2.2 wsparcie java.czas .
Skąd pobrać Javę.zajęcia czasowe?
-
Java SE 8, Java SE 9, Java SE 10, Java SE 11, a później-część standardowego API Javy z dołączoną implementacją.
- Java 9 przyniósł kilka drobnych funkcji i poprawek.
-
Java SE 6 oraz Java SE 7
- Większość java.czas funkcjonalność została przeniesiona do Java 6 & 7 w ThreeTen-Backport.
-
Android
-
[[84]}późniejsze wersje Androida (26+) implementacje pakietu java.czas klasy.
- dla wcześniejszego Androida (API desugaring podzbiór java.czas funkcjonalność pierwotnie nie wbudowana w Androida.
- jeśli desugaring nie oferuje tego, czego potrzebujesz, ThreeTenABP projekt dostosowuje ThreeTen-Backport (wymienione powyżej) do Androida. Zobacz też Jak stosować ThreeTenABP....
The ThreeTen-Extra projekt rozszerza Javę.czas z dodatkowymi zajęciami. Ten projekt jest poligonem dla potencjalnych przyszłych dodatków do Javy.czas. Możesz znaleźć tutaj kilka przydatnych klas, takich jak Interval
, YearWeek
, YearQuarter
, i więcej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-24 04:08:00
Główną różnicą jest Local
Część LocalDateTime
. Jeśli mieszkasz w Niemczech i tworzysz instancję LocalDateTime
, a ktoś inny mieszka w USA i tworzy inną instancję w tym samym momencie ( pod warunkiem, że zegary są odpowiednio ustawione) - wartość tych obiektów byłaby inna. Nie dotyczy to Instant
, która jest obliczana niezależnie od strefy czasowej.
LocalDateTime
przechowuje datę i czas bez strefy czasowej, ale jej wartość początkowa zależy od strefy czasowej. Instant
'S is nie.
Ponadto, LocalDateTime
dostarcza metod manipulacji składnikami daty, takimi jak dni, godziny, miesiące. An Instant
nie.
Oprócz nanosekundowej precyzji zaletą Instant i część strefy czasowej LocalDateTime
Obie klasy mają tę samą precyzję. LocalDateTime
nie przechowuje strefy czasowej. Przeczytaj dokładnie javadocs, ponieważ możesz popełnić duży błąd przy takich błędnych założeniach: Instant i LocalDateTime .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-07 11:55:08
Mylisz się co do LocalDateTime
: nie przechowuje żadnych informacji o strefie czasowej i ma nanosekundową precyzję. Cytując Javadoc (emfaza):
Data-czas bez strefy czasowej w systemie kalendarza ISO-8601, np. 2007-12-03T10:15:30.
LocalDateTime jest niezmiennym obiektem date-time, który reprezentuje datę-czas, często postrzegany jako Rok-Miesiąc-Dzień-godzina-minuta-sekunda. Inne pola daty i czasu, takie jak dzień roku, Dzień tygodnia i tydzień roku, można również uzyskać dostęp. Czas jest reprezentowany z nanosekundową precyzją. Na przykład wartość "2nd October 2007 at 13: 45.30.123456789" może być przechowywana w LocalDateTime.
Różnica między nimi jest taka, że Instant
reprezentuje przesunięcie z epoki (01-01-1970) i jako takie reprezentuje konkretną chwilę na linii czasowej. Dwa obiekty utworzone w tym samym momencie w dwóch różnych miejscach ziemi będą miały dokładnie to samo wartość.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-07 15:58:15
Instant
odpowiada czasowi na południku pierwszym (Greenwich).
LocalDateTime
względem ustawień strefy czasowej systemu operacyjnego oraz
Nie może reprezentować chwili bez dodatkowych informacji, takich jak przesunięcie lub Strefa czasowa.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-31 18:08:19