JavaRush /Blog Java /Random-PL /Intuicyjna, solidna biblioteka do pracy z godzinami i dat...
theGrass
Poziom 24
Саратов

Intuicyjna, solidna biblioteka do pracy z godzinami i datami jest wreszcie dostępna w Javie (część 2).

Opublikowano w grupie Random-PL
Pory dnia
    Więc przejdźmy dalej. Następną jednostką po dacie jest godzina reprezentowana przez klasę LocalTime . Klasycznym przykładem są godziny otwarcia sklepu, powiedzmy od 7:00 do 23:00. Sklepy są obecnie otwarte w całym kraju, ale faktyczne godziny otwarcia mogą się różnić w zależności od strefy czasowej.     LocalTime to klasa wartości, która przechowuje tylko czas, bez powiązanej daty i strefy czasowej. Podczas dodawania lub odejmowania okresu czasu zostanie on ucięty o północy. Oznacza to, że 20:00 plus 6 godzin to 2:00. Używanie LocalTime jest podobne do LocalDate : LocalTime time = LocalTime.of(20, 30); int hour = date.getHour(); // 20 int minute = date.getMinute(); // 30 time = time.withSecond(6); // 20:30:06 time = time.plusMinutes(3); // 20:33:06     Modyfikatory mogą współpracować z LocalTime , ale operacje na czasie zwykle nie są tak skomplikowane, że wymagane są modyfikatory.
Łączenie daty i godziny
    Następną klasą, której się przyjrzymy, jest LocalDateTime . Ta klasa wartości jest kombinacją LocalDate i LocalTime . Reprezentuje zarówno datę, jak i godzinę, bez strefy czasowej.      LocalDateTime można utworzyć bezpośrednio lub poprzez połączenie daty i godziny: LocalDateTime dt1 = LocalDateTime.of(2014, Month.JUNE, 10, 20, 30); LocalDateTime dt2 = LocalDateTime.of(date, time); LocalDateTime dt3 = date.atTime(20, 30); LocalDateTime dt4 = date.atTime(time);     Trzecia i czwarta opcja wykorzystują metodę atTime() , która zapewnia elastyczny sposób łączenia daty i godziny. Większość klas systemów daty i godziny ma metody „at”, których można użyć podczas łączenia obiektu z innym w celu utworzenia bardziej złożonego obiektu. Pozostałe metody klasy LocalDateTime są podobne do metod LocalDate i LocalTime . Podobne wzorce nazewnictwa metod ułatwiają naukę interfejsu API . W poniższej tabeli wymieniono wszystkie przedrostki metod, których to dotyczy: Intuicyjna, solidna biblioteka do pracy z godzinami i datami jest wreszcie dostępna w Javie (część 2).  - 1
Natychmiastowy
    Kiedy mamy do czynienia z datami i godzinami, zwykle pracujemy z latami, miesiącami, dniami, godzinami, minutami i sekundami. Jest to jednak tylko jeden model czasu, który można nazwać „ludzkim”. Drugim powszechnie stosowanym modelem jest czas „maszynowy” lub „ciągły”. W tym modelu punkt na osi czasu jest reprezentowany przez jedną dużą liczbę. Takie podejście upraszcza algorytmy obliczeniowe i służy do przechowywania czasu w systemie operacyjnym Unix , gdzie czas jest reprezentowany przez liczbę sekund, które upłynęły od 1 stycznia 1970 roku. Podobnie w Javie czas jest przechowywany jako liczba milisekund, które upłynęły od 1 stycznia 1970 r. Maszynowe podejście do obliczeń czasu w interfejsie API java.time zapewnia klasa wartości Instant . Zapewnia możliwość przedstawienia punktu na osi czasu bez wszystkich towarzyszących informacji, takich jak strefa czasowa. W rzeczywistości ta klasa zawiera liczbę nanosekund, które upłynęły od północy 1 stycznia 1970 roku. Instant start = Instant.now(); // произведем вычисления Instant end = Instant.now(); assert end.isAfter(start); //машина времени не сработала     Zazwyczaj klasa Instant służy do przechowywania i porównywania punktów w czasie, gdy trzeba zapisać, kiedy miało miejsce jakieś zdarzenie, ale nie przejmuje się strefą czasową, w której to nastąpiło. W większości przypadków bardziej interesujące jest to, czego nie możemy zrobić z klasą Instant , niż to, co możemy z nią zrobić. Na przykład poniższe wiersze kodu spowodują wyjątki: instant.get(ChronoField.MONTH_OF_YEAR); instant.plus(6, ChronoUnit.YEARS);     Wyjątki występują, ponieważ obiekt błyskawiczny przechowuje tylko liczbę nanosekund i nie zapewnia możliwości pracy z jednostkami czasu, które są bardziej przydatne dla ludzi. Aby użyć innych jednostek miary, musisz przynajmniej określić strefę czasową.
Strefy czasowe
    Zasada stref czasowych powstała w Anglii, kiedy wynaleziono kolej i ulepszenia innych środków komunikacji, umożliwiono ludziom pokonywanie odległości wystarczających, aby różnice w czasie słonecznym były zauważalne. Do tego czasu każda wioska i miasto żyły według własnego czasu, który najczęściej mierzono zegarem słonecznym. To zdjęcie pokazuje przykład trudności, do jakich to doprowadziło - czerwone wskazówki zegara pokazują czas Greenwich, a czarne wskazówki pokazują czas lokalny, który różni się o 10 minut: rozwinął się system stref czasowych, zastępując lokalny czas słoneczny Intuicyjna, solidna biblioteka do pracy z godzinami i datami jest wreszcie dostępna w Javie (część 2).  - 2     . Kluczowym faktem jest jednak to, że strefy czasowe są tworzone przez polityków i często wykorzystywane do wykazania kontroli politycznej nad danym obszarem. Jak każda polityka, zasady dotyczące stref czasowych często zaprzeczają logice. Poza tym zasady te mogą się zmieniać, i to często, bez ostrzeżenia. Zasady dotyczące stref czasowych są opracowywane przez międzynarodową grupę publikującą bazę danych stref czasowych IANA . Zawiera identyfikator każdego regionu Ziemi i historię zmian stref czasowych dla niego. Identyfikatory wyglądają jak „Europa/Londyn” lub „Ameryka/Nowy_Jork” . Przed udostępnieniem interfejsu API java.time do reprezentowania strefy czasowej używana była klasa TimeZone . Teraz zamiast tego używany jest ZoneId . Istnieją dwie kluczowe różnice między nimi. Po pierwsze, ZoneId jest niezmienny, co umożliwia między innymi przechowywanie obiektów tej klasy w zmiennych statycznych. Po drugie, same reguły przechowywane są w klasie ZoneRules , a nie w samej ZoneId , a żeby je uzyskać należy wywołać metodę getRules() na obiekcie klasy ZoneId . Wspólną cechą wszystkich stref czasowych jest stałe przesunięcie w stosunku do czasu UTC/Greenwich . Najczęściej używasz tego, mówiąc o różnicach czasu między różnymi miastami, np. „Nowy Jork jest 5 godzin za Londynem”. Klasa ZoneOffset , potomek ZoneId , reprezentuje różnicę czasu z południkiem zerowym przechodzącym przez Greenwich w Londynie. Z punktu widzenia programisty byłoby wspaniale nie mieć do czynienia ze strefami czasowymi i ich złożonością. API java.time pozwala to robić tak długo, jak to możliwe. Tam, gdzie to możliwe, używaj klas LocalDate, LocalTime, LocalDateTime i Instant . Jeśli nie możesz obejść się bez stref czasowych, użyj klasy ZonedDateTime . Klasa ZonedDateTimepozwala na przeliczenie dat i godzin z ludzkich jednostek miary, które widzimy na kalendarzach i zegarkach, na jednostki maszynowe. W rezultacie możesz utworzyć ZonedTimeDate albo z klasy Local , albo z klasy Instant : ZoneId zone = ZoneId.of("Europe/Paris"); LocalDate date = LocalDate.of(2014, Month.JUNE, 10); ZonedDateTime zdt1 = date.atStartOfDay(zone); Instant instant = Instant.now(); ZonedDateTime zdt2 = instant.atZone(zone);     Jedną z najbardziej nieprzyjemnych cech stref czasowych jest tak zwany czas letni. W przypadku zmiany czasu letniego na i z Greenwich różnica stref czasowych w stosunku do Greenwich zmienia się dwa razy (lub częściej) w roku, zwykle zwiększając się wiosną i zmniejszając jesienią. Kiedy tak się stanie, będziemy musieli przestawić wszystkie zegary w naszym domu. W klasach Java.time dane przesunięcia są reprezentowane jako „transformacje przesunięcia” . Wiosną powoduje to „lukę” w czasie, gdy niektóre wartości czasu są niemożliwe, a jesienią wręcz przeciwnie, niektóre wartości czasu występują dwukrotnie. Wszystko to jest obsługiwane przez klasę ZonedDateTime poprzez jej metody fabryczne i metody konwertera. Na przykład dodanie jednego dnia powoduje dodanie dnia logicznego, który może być reprezentowany przez więcej lub mniej niż 24 godziny, jeśli przejdziemy na czas letni lub odwrotnie. Podobnie nazywa się metoda atStartOfDay() ponieważ nie możemy zagwarantować, że dzień zacznie się dokładnie o północy - musimy uwzględnić różnicę czasową przy przejściu na czas letni. I ostatnia wskazówka dotycząca czasu letniego. Jeśli chcesz wykazać, że uwzględniłeś nakładanie się czasu podczas przejścia z lata na zimę (gdy ta sama wartość czasu pojawia się dwukrotnie), możesz skorzystać z jednej z dwóch specjalnych metod przeznaczonych dla takich sytuacji: Metody te zwrócą wcześniejszą lub późniejszą zdt = zdt.withEarlierOffsetAtOverlap(); zdt = zdt.withLaterOffsetAtOverlap();     wartość , jeśli obiekt zostanie nałożony na siebie podczas przejścia z czasu letniego na zimowy. We wszystkich innych sytuacjach zwracane wartości będą takie same.
Interwały czasowe
    Wszystkie klasy, które omówiliśmy wcześniej, działają jako punkty na osi czasu. Do reprezentowania przedziałów czasu potrzebne są dwie dodatkowe klasy wartości. Klasa Duration reprezentuje czas mierzony w sekundach i nanosekundach. Na przykład „23,6 sekundy”. Klasa Period reprezentuje okres mierzony w latach, miesiącach i dniach. Na przykład - „3 lata, 2 miesiące i 6 dni”. Przedziały te można dodawać lub odejmować od daty lub godziny: Period sixMonths = Period.ofMonths(6); LocalDate date = LocalDate.now(); LocalDate future = date.plus(sixMonths);
Formatowanie i parsowanie
    Cały pakiet jest przeznaczony do formatowania i wyświetlania dat i godzin - java.time.format . Pakiet dotyczy klasy DateTimeFormatter i jej fabryki DateTimeFormatterBuilder . Najczęstsze sposoby tworzenia formatera to metody statyczne i stałe w DateTimeFormatter , w tym:
  • Stałe dla popularnych formatów opisanych w ISO, takich jak ISO_LOCAL_DATE.
  • Wzorce identyfikowane literami, np. ofPattern("dd/MM/uuuu").
  • Zlokalizowane style, takie jak ofLocalizedDate(FormatStyle.MEDIUM).
    Po utworzeniu formatera zwykle używa się go, przekazując go do odpowiedniej metody klasy date: DateTimeFormatter f = DateTimeFormatter.ofPattern("dd/MM/uuuu"); LocalDate date = LocalDate.parse("24/06/2014", f); String str = date.format(f);     W ten sposób kod odpowiedzialny za formatowanie danych wyjściowych jest izolowany w osobnej klasie. Jeśli chcesz osobno określić ustawienia regionalne dla formatowania daty, użyj metody formatowania withLocale(Locale) . Klasy odpowiedzialne za kalendarz, strefę czasową i wprowadzanie/wyprowadzanie liczb ułamkowych mają podobne metody. Jeśli potrzebujesz więcej opcji dostrajania, zapoznaj się z dokumentacją klasy DateTimeFormatterBuilder , która pozwala krok po kroku tworzyć złożone formatery. Umożliwia także ustawienie analizowania tekstu bez rozróżniania wielkości liter, ignorowanie niektórych błędów analizy, ustawianie przesunięć i elementów opcjonalnych.
Konkluzja
     API java.time to nowy, kompleksowy model pracy z datą i czasem w Java SE 8 . Przenosi pomysły i implementacje z Joda-Time na wyższy poziom i wreszcie pozwala programistom uniknąć używania java.util.Date i Calendar . Teraz praca z datami i godzinami może być świetną zabawą!      Oryginalny artykuł
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION