Konwersja pomiędzy Javą.czas.LocalDateTime i java.util.Data

Java 8 ma zupełnie nowe API dla daty i czasu. Jedną z najbardziej użytecznych klas w tym API jest LocalDateTime, do przechowywania niezależnej od strefy czasowej daty z wartością czasu.

Prawdopodobnie są miliony linii kodu używających do tego celu klasy legacy java.util.Date. W związku z tym, podczas łączenia Starego i nowego kodu będzie konieczna konwersja między nimi. Ponieważ wydaje się, że nie ma bezpośrednich metod, aby to osiągnąć, jak można to zrobić?

Author: JodaStephen, 2013-10-17

7 answers

Krótka odpowiedź:

Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());

Wyjaśnienie: (na podstawie tego pytania o LocalDate)

Pomimo swojej nazwy, java.util.Date reprezentuje moment w linii czasowej, a nie "datę". Rzeczywiste dane przechowywane w obiekcie to long liczba milisekund od 1970-01-01T00: 00Z (północ na początku 1970 GMT/UTC).

W JSR-310 klasa równoważna

Jest Instant, więc istnieją wygodne metody zapewniające konwersję do i z powrotem:

Date input = new Date();
Instant instant = input.toInstant();
Date output = Date.from(instant);

A java.util.Date instancja nie ma pojęcia strefy czasowej. Może to wydawać się dziwne, jeśli zadzwonisz {[10] } na java.util.Date, ponieważ {[12] } jest względem strefy czasowej. Jednak ta metoda faktycznie używa domyślnej strefy czasowej Javy w locie, aby zapewnić ciąg znaków. Strefa czasowa nie jest częścią rzeczywistego stanu java.util.Date.

An Instant również nie zawiera żadnych informacji o strefie czasowej. Tak więc, aby konwertować z Instant na lokalną datę-czas, konieczne jest określenie strefy czasowej. To może być strefa domyślna - ZoneId.systemDefault() - lub może to być Strefa czasowa, którą kontroluje aplikacja, na przykład strefa czasowa z preferencji użytkownika. Ma wygodną metodę fabryczną, która zajmuje zarówno strefę natychmiastową, jak i czasową:]}

Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());

W odwrotnej kolejności, LocalDateTime Strefa czasowa jest określona przez wywołanie metody atZone(ZoneId). W ten sposób można przekształcić je bezpośrednio na Instant:

LocalDateTime ldt = ...
ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
Date output = Date.from(zdt.toInstant());

Zauważ, że konwersja z LocalDateTime na {[20] } może spowodować nieoczekiwane zachowanie. Dzieje się tak dlatego, że nie każdy lokalna data-czas istnieje ze względu na czas letni. Jesienią / jesienią, istnieje nakładanie się w linii czasu lokalnego, gdzie ta sama lokalna data-czas występuje dwa razy. Wiosną jest przerwa, w której godzina znika. # Patrz Javadoc atZone(ZoneId) więcej definicji tego, co zrobi konwersja.

Podsumowanie, jeśli podróżujesz w obie strony a java.util.Date do a LocalDateTime i z powrotem do a java.util.Date możesz skończyć z innym momentem ze względu na czas letni.

DODATKOWE info: jest jeszcze różnica, która wpłynie na bardzo stare daty. java.util.Date używa kalendarza, który datuje się na 15 października 1582, z datami wcześniejszymi, używając kalendarza juliańskiego zamiast gregoriańskiego. Z kolei java.time.* używa systemu kalendarza ISO (równoważnego Gregoriańskiemu) dla wszystkich czasów. W większości przypadków system kalendarza ISO jest tym, czego chcesz, ale możesz zobaczyć dziwne efekty podczas porównywania dat przed rokiem 1582.

 576
Author: JodaStephen,
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
2017-05-23 12:18:23

Oto, co wymyśliłem (i jak wszystkie zagadki związane z datą, prawdopodobnie zostanie obalone na podstawie jakiejś dziwnej regulacji strefy czasowej-leapyear-daylight :d) {]}

Round-tripping: Date > LocalDateTime

Podane: Date date = [some date]

(1) LocalDateTime InstantDate

    Instant instant = Instant.ofEpochMilli(date.getTime());
    LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

(2) Date Instant LocalDateTime

    Instant instant = ldt.toInstant(ZoneOffset.UTC);
    Date date = Date.from(instant);

Przykład:

Podane:

Date date = new Date();
System.out.println(date + " long: " + date.getTime());

(1) LocalDateTime InstantDate:

Create Instant od Date:

Instant instant = Instant.ofEpochMilli(date.getTime());
System.out.println("Instant from Date:\n" + instant);

Tworzenie Date z Instant (nie jest konieczne, ale dla ilustracji):

date = Date.from(instant);
System.out.println("Date from Instant:\n" + date + " long: " + date.getTime());

Create LocalDateTime from Instant

LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
System.out.println("LocalDateTime from Instant:\n" + ldt);

(2) Date Instant LocalDateTime

Create Instant from LocalDateTime:

instant = ldt.toInstant(ZoneOffset.UTC);
System.out.println("Instant from LocalDateTime:\n" + instant);

Create Date from Instant:

date = Date.from(instant);
System.out.println("Date from Instant:\n" + date + " long: " + date.getTime());

Wyjście To:

Fri Nov 01 07:13:04 PDT 2013 long: 1383315184574

Instant from Date:
2013-11-01T14:13:04.574Z

Date from Instant:
Fri Nov 01 07:13:04 PDT 2013 long: 1383315184574

LocalDateTime from Instant:
2013-11-01T14:13:04.574

Instant from LocalDateTime:
2013-11-01T14:13:04.574Z

Date from Instant:
Fri Nov 01 07:13:04 PDT 2013 long: 1383315184574
 114
Author: Saint Hill,
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
2014-05-28 22:02:47

O wiele wygodniejszy sposób, jeśli jesteś pewien, że potrzebujesz domyślnej strefy czasowej:

Date d = java.sql.Timestamp.valueOf( myLocalDateTime );
 16
Author: Petrychenko,
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-04-18 19:34:23

Poniższe rozwiązanie wydaje się działać podczas konwersji z nowego API LocalDateTime do Javy.util.data:

Date.from(ZonedDateTime.of({time as LocalDateTime}, ZoneId.systemDefault()).toInstant());

Odwrotna konwersja może być (miejmy nadzieję) osiągnięta w podobny sposób...

Mam nadzieję, że to pomoże...
 8
Author: dizzy,
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
2014-05-27 08:06:10

Nie jestem pewien, czy jest to najprostszy, czy najlepszy sposób, czy są jakieś pułapki, ale to działa:

static public LocalDateTime toLdt(Date date) {
    GregorianCalendar cal = new GregorianCalendar();
    cal.setTime(date);
    ZonedDateTime zdt = cal.toZonedDateTime();
    return zdt.toLocalDateTime();
}

static public Date fromLdt(LocalDateTime ldt) {
    ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
    GregorianCalendar cal = GregorianCalendar.from(zdt);
    return cal.getTime();
}
 3
Author: Knut Arne Vedaa,
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
2013-10-17 15:40:54

Wszystko jest tutaj: http://blog.progs.be/542/date-to-java-time

ODPOWIEDŹ z "round-tripping" nie jest dokładna: kiedy robisz

LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

Jeśli Strefa czasowa systemu nie jest UTC / GMT, można zmienić czas !

 3
Author: joe-mojo,
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
2014-05-07 19:03:16

Jeśli korzystasz z Androida i używasz threetenbp możesz zamiast tego użyć DateTimeUtils.

Ex:

Date date = DateTimeUtils.toDate(localDateTime.atZone(ZoneId.systemDefault()).toInstant());

Nie możesz używać Date.from, ponieważ jest on obsługiwany tylko przez api 26+

 0
Author: humazed,
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
2018-09-06 04:37:59