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

Author: manuel aldana, 2015-09-07

4 answers

Tabela wszystkich typów daty i czasu w Javie, zarówno nowoczesnych, jak i starszych

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

Tutaj wpisz opis obrazka

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

Tutaj wpisz opis obrazka

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

Tutaj wpisz opis obrazka

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

Tutaj wpisz opis obrazka

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

Tutaj wpisz opis obrazka

Pomyśl o ZonedDateTime koncepcyjnie jako {[10] } z przypisanym ZoneId.

Zoneddatetime = (Instant + Zoneid)

[74]} aby uchwycić aktualną chwilę, jak widać w zegar ścienny czas używany przez ludzi z określonego regionu (strefy czasowej): [78]}
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

Diagram pokazujący tylko kalendarz dla danej miejscowości.

Diagram pokazujący tylko zegar dla czasu lokalnego.

Diagram pokazujący Kalendarz Plus Zegar Dla 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.

Uważam tę sprawę za niewłaściwą i nierozsądną. Jeśli strefa lub przesunięcie jest zamierzone, ale nieokreślone, masz złe dane. To byłoby jak przechowywanie ceny produktu bez znajomości zamierzonej waluty (dolary, funty, Euro itp.). Nie za dobrze. pomysł.

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.

Tabela wszystkich typów daty i czasu w Javie (zarówno nowoczesnych i starszych), jak i w standardzie SQL.

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.

Ale nie martw się. Możemy łatwo konwertować tam iz powrotem.

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?

Tabela w tym java.biblioteka czasu do wykorzystania z jaką wersją Javy lub Androida

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.

 1056
Author: Basil Bourque,
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 .

 24
Author: Dariusz,
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ść.

 12
Author: Tunaki,
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.

 -2
Author: user2418306,
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