Java 8 ma zupełnie nową bibliotekę dat i godzin w pakiecie java.time, co jest bardzo mile widziane dla każdego, kto musiał wcześniej używać JodaTime lub miał problemy z tworzeniem własnych metod pomocniczych przetwarzania daty. Wiele klas w tym pakiecie reprezentuje znaczniki czasu i mają metody pomocnicze, takie jak getHour()
uzyskiwanie godzin od znacznika czasu, getMinute()
uzyskiwanie minut od znacznika czasu, getNano()
uzyskiwanie nanosów z znacznika czasu itp.
Zauważyłem, że nie mają metody wywołania getMillis()
milisów znacznika czasu. Zamiast tego trzeba by wywołać metodę get(ChronoField.MILLI_OF_SECOND)
. Dla mnie to wydaje się niespójnością w bibliotece. Czy ktoś wie, dlaczego brakuje takiej metody lub skoro Java 8 jest wciąż w fazie rozwoju, czy istnieje możliwość, że zostanie ona dodana później?
https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html
Klasy zdefiniowane tutaj reprezentują podstawowe pojęcia data-czas, w tym momenty, czasy trwania, daty, godziny, strefy czasowe i okresy. Opierają się na systemie kalendarza ISO, który jest de facto kalendarzem światowym, opartym na proleptycznych zasadach gregoriańskich. Wszystkie klasy są niezmienne i bezpieczne dla wątków.
Każda instancja daty i godziny składa się z pól, które są dogodnie udostępniane przez interfejsy API. Aby uzyskać dostęp do pól na niższym poziomie, patrz
java.time.temporal
pakiet. Każda klasa obejmuje obsługę drukowania i analizowania wszystkich dat i godzin. Informacje na tematjava.time.format
opcji dostosowywania znajdują się w pakiecie ...
Przykład tego rodzaju klasy:
https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html
Data i godzina bez strefy czasowej w systemie kalendarza ISO-8601, np. 2007-12-03T10: 15: 30.
LocalDateTime
jest niezmiennym obiektem data-godzina, który reprezentuje datę-godzinę, często postrzeganą jako rok-miesiąc-dzień-godzina-minuta-sekunda. Można również uzyskać dostęp do innych pól daty i godziny, takich jak dzień roku, dzień tygodnia i tydzień roku. Czas jest reprezentowany z dokładnością do nanosekund. Na przykład wartość „2 października 2007 o 13: 45.30.123456789” można zapisać wLocalDateTime
...
get()
, zamiast nadawać im indywidualne, unikalne nazwy. Jeśli ci to przeszkadza, napisz klasę, która dziedziczy klasę oryginalną, i umieść własnągetMillis()
metodę w nowej klasie.Instant
klasyOdpowiedzi:
JSR-310 oparty jest na nanosekundach, a nie milisekundach. Jako taki, minimalny zestaw rozsądnych metod oparty jest na godzinie, minutach, sekundach i nanosekundach. Decyzja o ustanowieniu bazy nanosekundowej była jedną z pierwotnych decyzji projektu i zdecydowanie uważam ją za słuszną.
Dodanie metody dla milisów nakładałoby się na metodę nanosekundową, co jest nieoczywistym sposobem. Użytkownicy musieliby zastanowić się, czy na przykład nanotechnologia była nanosekundowa, czy nanomiliowa. Dodanie mylącej dodatkowej metody nie jest pożądane, więc metodę tę pominięto. Jak wskazano, alternatywa
get(MILLI_OF_SECOND)
jest dostępna.FWIW, nie chciałbym dodawać tej
getMillis()
metody w przyszłości.źródło
instant.getEpochSecond * 1000 + instant.getNano / 1000000
jest uzasadnione, aby móc komunikować się ze starszymi (w tym momencie wszystkimi) interfejsami API Java, JavaScript itp.?Przed byciem częścią openJDK, threeten był na githubie, a wcześniej na sourceforge. Wtedy Stephen Colebourne, który jest liderem specyfikacji na jsr-310, przeprowadził ankietę, którą wciąż można znaleźć na stronie sourceforge .
tylko 6,23% wybrało odpowiedź nr 4, a wśród nich około 15% poprosiło o
getMillis()
, tj. mniej niż 1% ogólnej liczby głosów.Prawdopodobnie dlatego nie było go w ogóle
getMillis
i nie mogłem znaleźć niczego związanego z listą dyskusyjną openjdk, więc sprawa najwyraźniej nie była później omawiana.źródło
Klasy reprezentujące jednoznaczne czasy UTC (są to Instant, OffsetDateTime, ZonedDateTime) mają dwie metody pomocnicze w celu uzyskania dostępu do bezwzględnego przesunięcia w stosunku do epoki Java, tj. To, co nazywamy „czasem milisekundowym” w java.util.Date, którego można użyć dostać się w milisekundach
Niektóre powody, dla których wybrano to zamiast,
long getEpochMillis()
zostały omówione na liście mailingowej jsr 310 , niektóre z nich wyodrębniłem dla wygody:Mam wrażenie, że innym powodem było celowe utrudnienie konwersji z java.util.Date na klasy JSR310, mając nadzieję, że programiści spróbują zrozumieć różnice między poszczególnymi opcjami, a nie tylko ślepo (źle) użyją nowych klas.
Co do tego, dlaczego
LocalDateTime
klasa nie ma tych metod - prawdopodobnie nie mogą tam istnieć, ponieważLocalDateTime
nie są powiązane z osią czasu UTC, dopóki nie zdecydujesz, w której strefie jesteś lub jakie jest przesunięcie UTC, w którym momencie maszOffsetDateTime
lubZonedDateTime
(oba mają potrzebne metody).Alternatywnie, możesz zdefiniować własną
LOCAL_EPOCH
stałą,1970-01-01T00:00:00
a następnie zrobić,MILLIS.between(LOCAL_EPOCH, localTime)
aby uzyskać pewien czas trwania w milisekundach. Ta wartość nie będzie jednak zgodna z żadną wartością zwróconą przezSystem.currentTimeMilliseconds()
lubjava.util.Date.getTime()
, chyba że zdefiniujesz czas lokalny jako czas UTC; ale w tym przypadku równie dobrze możesz użyć Instant bezpośrednio lub OffsetDateTime z ZoneOffset.UTC.źródło
getMillis
metodę, która w zasadzie powróciłabygetNanos()/1e6
- fakt, że nie jest to chwila, nie uniemożliwia milisekundy składnik.getMillis()
jak w getMillis-of-second; mówisz o „millis od epoki”. Ten pierwszy jest nieobecny, jak wyjaśniono w zaakceptowanej odpowiedzi. Ten ostatni jest już dostępny jakoInstant.toEpochMillis()
. Więc, na przykładLocalDateTime
, poszedłbyś:ldt.toInstant(offset).toEpochMillis()