Wiem to:
- Instant jest raczej „techniczną” reprezentacją znaczników czasowych (nanosekund) do obliczeń.
- LocalDateTime jest raczej reprezentacją daty / godziny, w tym stref czasowych dla ludzi.
Nadal IMO oba mogą być traktowane jako typ dla większości przypadków użycia aplikacji. Jako przykład: obecnie prowadzę zadanie wsadowe, w którym muszę obliczyć kolejny przebieg na podstawie dat i staram się znaleźć zalety / wady między tymi dwoma typami (oprócz nanosekundowej przewagi precyzji Instant i strefy czasowej) LocalDateTime).
Czy możesz wymienić niektóre przykłady aplikacji, w których należy używać tylko Instant lub LocalDateTime?
Edycja: Strzeż się błędnie odczytanych dokumentacji dla LocalDateTime dotyczących precyzji i strefy czasowej
LocalDateTime
ma nie mieć strefę czasową!Odpowiedzi:
tl; dr
Instant
iLocalDateTime
są dwoma zupełnie różnymi zwierzętami: jedno przedstawia chwilę, drugie nie.Instant
reprezentuje chwilę, konkretny punkt na osi czasu.LocalDateTime
reprezentuje datę i porę dnia. Jednak bez strefy czasowej lub przesunięcia względem UTC klasa ta nie może reprezentować chwili . Przedstawia potencjalne momenty w zakresie od około 26 do 27 godzin, zakres wszystkich stref czasowych na całym świecie.Błędne domniemanie
Twoje oświadczenie jest nieprawidłowe: A
LocalDateTime
nie ma strefy czasowej . Brak strefy czasowej to cały punkt tej klasy.Aby zacytować ten dokument klasy:
Local…
Oznacza to więc „bez stref, bez przesunięcia”.Instant
Jest
Instant
to moment na osi czasu w UTC , liczba nanosekund od epoki pierwszego momentu 1970 UTC (w zasadzie, patrz dokument klasy, aby uzyskać szczegóły nitty-ziarnistości). Ponieważ większość logiki biznesowej, przechowywania danych i wymiany danych powinna odbywać się w UTC, jest to przydatna klasa, z której można często korzystać.OffsetDateTime
Klasa
OffsetDateTime
klasy reprezentuje moment jako datę i godzinę w kontekście pewnej liczby godzin-minut-sekund przed lub za UTC. Wielkość przesunięcia, liczba godzin-minut-sekund, jest reprezentowana przezZoneOffset
klasę.Jeśli liczba godzin-minut-sekund wynosi zero, an
OffsetDateTime
oznacza moment w UTC taki sam jak anInstant
.ZoneOffset
ZoneOffset
Klasa oznacza grupę offsetu z-UTC , kilka godzin minutowa sekund wyprzedzając UTC lub za UTC.A
ZoneOffset
to tylko liczba godzin-minut-sekund, nic więcej. Strefa to znacznie więcej, z nazwą i historią zmian do przesunięcia. Dlatego korzystanie ze strefy jest zawsze lepsze niż zwykłe przesunięcie.ZoneId
Strefa czasowa jest reprezentowane przez
ZoneId
klasę.Na przykład nowy dzień zaczyna się wcześniej w Paryżu niż na przykład w Montrealu . Musimy więc przesunąć wskazówki zegara, aby lepiej odzwierciedlić południe (gdy Słońce jest bezpośrednio nad głową) dla danego regionu. Im dalej na wschód / zachód od linii UTC w zachodniej Europie / Afryce, tym większe przesunięcie.
Strefa czasowa to zestaw zasad postępowania z korektami i anomaliami praktykowanymi przez lokalną społeczność lub region. Najczęstszą anomalią jest bardzo popularna szaleństwo zwane czasem letnim (DST) .
Strefa czasowa ma historię przeszłych reguł, obecnych reguł i reguł potwierdzonych w najbliższej przyszłości.
Reguły te zmieniają się częściej, niż można się spodziewać. Pamiętaj o aktualizowaniu reguł biblioteki daty i czasu, zwykle kopii bazy danych „tz” . Utrzymywanie aktualności jest teraz łatwiejsze niż kiedykolwiek w Javie 8 dzięki Oracle udostępniającemu narzędzie aktualizacji stref czasowych .
Określ prawidłową nazwę strefy czasowej w formacie
Continent/Region
, takie jakAmerica/Montreal
,Africa/Casablanca
lubPacific/Auckland
. Nigdy nie używaj 2-4-literowego skrótu, takiego jakEST
lub,IST
ponieważ nie są to prawdziwe strefy czasowe, nie są znormalizowane, a nawet unikalne (!).ZonedDateTime
Myśl
ZonedDateTime
koncepcyjnie jakoInstant
z przypisanymZoneId
.Aby uchwycić bieżący moment widziany w zegarze ściennym używanym przez mieszkańców danego regionu (strefy czasowej):
Prawie wszystkie zaplecze, baza danych, logika biznesowa, trwałość danych, wymiana danych powinny być w UTC. Ale w celu prezentacji użytkownikom musisz dostosować się do strefy czasowej oczekiwanej przez użytkownika. Taki jest cel
ZonedDateTime
klasy i klas formaterów używanych do generowania reprezentacji ciągu tych wartości daty i godziny.Możesz generować tekst w zlokalizowanym formacie za pomocą
DateTimeFormatter
.LocalDate
,LocalTime
,LocalDateTime
Te „lokalne” Klasy czas data,
LocalDateTime
,LocalDate
,LocalTime
, są różnego rodzaju stwora. Nie są powiązane z żadną lokalizacją ani strefą czasową. Nie są powiązane z osią czasu. Nie mają żadnego rzeczywistego znaczenia, dopóki nie zastosujesz ich do lokalizacji, aby znaleźć punkt na osi czasu.Słowo „lokalny” w tych nazwach klas może być sprzeczne z intuicją dla niewtajemniczonych. Słowo oznacza dowolną lokalizację lub każdą lokalizację, ale nie określoną lokalizację.
Dlatego w przypadku aplikacji biznesowych typy „lokalne” nie są często używane, ponieważ reprezentują one jedynie ogólne pojęcie możliwej daty lub godziny, a nie określonego momentu na osi czasu. Aplikacje biznesowe zwykle dbają o to, kiedy dokładnie dotrze faktura, produkt wysłany do transportu, pracownik został zatrudniony lub taksówka opuściła garaż. Dzięki czemu programiści aplikacji biznesowych użytku
Instant
iZonedDateTime
klas najczęściej.Kiedy więc użyjemy
LocalDateTime
? W trzech sytuacjach: gdy chcemy zastosować określoną datę i porę dnia w wielu lokalizacjach, gdzie rezerwujemy terminy spotkań lub w której mamy zamierzoną, jeszcze nieokreśloną strefę czasową. Zauważ, że żaden z tych trzech przypadków nie jest pojedynczym określonym punktem na osi czasu, żaden z nich nie jest momentem.Jedna pora dnia, wiele chwil
Czasami chcemy przedstawić określoną porę dnia w określonym dniu, ale chcemy zastosować to w wielu lokalizacjach w różnych strefach czasowych.
Na przykład „Boże Narodzenie zaczyna się o północy 25 grudnia 2015 r.”
LocalDateTime
. Północ wybija w różnych momentach w Paryżu niż w Montrealu, a także w Seattle i Auckland .Kolejny przykład: „Firma Acme ma politykę, zgodnie z którą pora obiadowa zaczyna się o godzinie 12:30 w każdej z fabryk na całym świecie”
LocalTime
. Aby mieć prawdziwe znaczenie, należy zastosować go do osi czasu, aby określić moment 12:30 w fabryce w Stuttgarcie lub 12:30 w fabryce Rabat lub 12:30 w fabryce w Sydney .Rezerwacja terminów
Inną sytuacją do wykorzystania
LocalDateTime
jest rezerwacja przyszłych wydarzeń (np. Wizyty u dentysty). Spotkania te mogą być na tyle daleko w przyszłości, że ryzykujesz, że politycy redefiniują strefę czasową. Politycy często dają niewiele ostrzeżeń, a nawet nie ostrzegają wcale. Jeśli masz na myśli „15 po południu w dniu 23 stycznia”, niezależnie od tego, jak politycy mogą grać z zegarem, to nie możesz nagrać chwili - to oznaczałoby, że godzina piętnasta zamieni się w 14 lub 16 po południu, jeśli region ten przyjmie lub skróci czas letni, na przykład.W przypadku spotkań przechowuj
LocalDateTime
ai aZoneId
, przechowywane osobno. Później, podczas generowania harmonogramu, w locie określ moment, wzywającLocalDateTime::atZone( ZoneId )
do wygenerowaniaZonedDateTime
obiektu.W razie potrzeby możesz dostosować się do UTC. Wyodrębnij
Instant
zZonedDateTime
.Nieznana strefa
Niektóre osoby mogą używać
LocalDateTime
w sytuacji, gdy strefa czasowa lub przesunięcie są nieznane.Uważam tę sprawę za nieodpowiednią i nierozsądną. Jeśli strefa lub przesunięcie jest zamierzone, ale nie jest określone, masz złe dane. To byłoby jak przechowywanie ceny produktu bez znajomości zamierzonej waluty. To nie jest dobry pomysł.
Wszystkie typy daty i godziny
Dla kompletności, oto tabela wszystkich możliwych typów daty i godziny, zarówno nowoczesnych, jak i starszych w Javie, a także tych zdefiniowanych przez standard SQL. Może to pomóc w umieszczeniu klas
Instant
&LocalDateTime
w szerszym kontekście.Zwróć uwagę na dziwne wybory dokonane przez zespół Java przy projektowaniu JDBC 4.2. Zdecydowali się obsługiwać wszystkie czasy java.time … z wyjątkiem dwóch najczęściej używanych klas:
Instant
iZonedDateTime
.Ale nie martw się. Możemy łatwo konwertować tam iz powrotem.
Konwersja
Instant
.Konwersja
ZonedDateTime
.O java.time
Środowisko java.time jest wbudowane w Javę 8 i nowsze wersje . Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak
java.util.Date
,Calendar
, iSimpleDateFormat
.Projekt Joda-Time , teraz w trybie konserwacji , zaleca migrację do klas java.time .
Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj stos przepełnienia dla wielu przykładów i wyjaśnień. Specyfikacja to JSR 310 .
Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie potrzeba ciągów, nie ma potrzeby
java.sql.*
klas.Gdzie można uzyskać klasy java.time?
Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak
Interval
,YearWeek
,YearQuarter
, i więcej .źródło
Local
nazewnictwa. Moja intuicja dotyczącaLocal
środków w odniesieniu do tego, gdzie jestem ORAZ, kiedy jestem (?!), Co prowadzi mnie do przekonania, że tak naprawdę byłoby to, coZonedDateTime
jest.DateTime
nazwy klasy używanej przez jego poprzednika Joda-Time (produkującąZonedDateTime
), aby podkreślić różnicę w stosunku do klas „lokalnych”. Pomyśl o nazwie „Lokalna” jako o „skradzionej nazwie” wymagającej zastosowania w konkretnej miejscowości ”.Local
może być również sposobem na odróżnienie się od pakietu java.util, chociaż wydaje mi się, że mógł być lepszy wybór słów.Jedną z głównych różnic jest
Local
częśćLocalDateTime
. Jeśli mieszkasz w Niemczech i tworzyszLocalDateTime
instancję, 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 dotyczyInstant
to obliczania niezależnie od strefy czasowej.LocalDateTime
przechowuje datę i godzinę bez strefy czasowej, ale jej wartość początkowa zależy od strefy czasowej.Instant
nie jest.Ponadto
LocalDateTime
zapewnia metody manipulowania składnikami daty, takimi jak dni, godziny, miesiące.Instant
Nie.Obie klasy mają tę samą precyzję.
LocalDateTime
nie przechowuje strefy czasowej. Przeczytaj dokładnie javadocs, ponieważ możesz popełnić duży błąd, przyjmując takie nieprawidłowe założenia: Instant i LocalDateTime .źródło
LocalDateTime stores date and time without timezone, but it's initial value is timezone dependent
? jaka jest wartość początkowa i jak zależy od strefy czasowej? Dzięki.Mylisz się co do tego
LocalDateTime
: nie przechowuje żadnych informacji o strefie czasowej i ma precyzję nanosekundową. Cytując Javadoc (moje podkreślenie):Różnica między nimi polega na tym, że
Instant
reprezentuje przesunięcie w stosunku do Epoki (01-01-1970) i jako taka reprezentuje konkretny moment na linii czasu. DwaInstant
obiekty utworzone w tym samym momencie w dwóch różnych miejscach na Ziemi będą miały dokładnie taką samą wartość.źródło
Instant
odpowiada czasowi na głównym południku (Greenwich).Natomiast w
LocalDateTime
odniesieniu do ustawień strefy czasowej systemu operacyjnego, orazźródło