Konwertuj java.time.LocalDate na java.util.Date


372

Chcę przekonwertować java.time.LocalDatena java.util.Datetyp. Ponieważ chcę ustawić datę na JDateChooser. A może jest jakiś wybór daty, który obsługuje java.timedaty?



2
LGoodDatePicker natywnie używa pakietu java.time (inaczej Java 8 time lub JSR-310 . W szczególności LGoodDatePicker używa „java.time.LocalDate” do przechowywania wartości dat. Zrzuty ekranu i wersja demo znajdują się na stronie głównej projektu .
BlakeTNC

Odpowiedzi:


560
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());

Zakłada się, że wybieracz dat używa domyślnej systemowej strefy czasowej do przekształcania dat w ciągi znaków.


JB Nizet być może Java 8 była na wczesnym etapie rozwoju / wydania, a @ user3509494 w jakiś sposób ją testował.
russellhoff

2
Czy można tego uniknąć atStartOfDay(), ponieważ zmienia wartość daty, tak jak ją rozumiem.
yegor256

1
@JBNizet Twoja odpowiedź nie ma dla mnie większego sensu, dlatego postanowiłem wyjaśnić. Dlaczego nie wyjaśnisz tego, zamiast robić bezużyteczne komentarze?
yegor256

12
Ponieważ nie rozumiem, jak i dlaczego wymagałoby to wyjaśnienia. 232 osoby głosowały za odpowiedzią, co było dla niej jasne. Mówisz, że atStartOfDay zmienia wartość daty. To nie ma sensu. atStartOfDay robi to, co mówi javadoc: przekształca LocalDate w LocalDateTime, tego samego dnia i na początku dnia.
JB Nizet,

2
@cornz Czy na pewno Twoje wyniki są nieprawidłowe? Jeśli jesteś w Niemczech, to może być coś zrobić z 6 minut 32 drugiego usterki w tym czasie w Niemczech, w kwietniu 1893. Zobacz timeanddate.com/time/zone/germany/berlin?syear=1850 dla niektórych szczegółów .
Dawood ibn Kareem

104

Oto klasa narzędziowa, której używam do konwertowania nowszych java.timeklas na java.util.Dateobiekty i odwrotnie:

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

public class DateUtils {

  public static Date asDate(LocalDate localDate) {
    return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
  }

  public static Date asDate(LocalDateTime localDateTime) {
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
  }

  public static LocalDate asLocalDate(Date date) {
    return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
  }

  public static LocalDateTime asLocalDateTime(Date date) {
    return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
  }
}

Edytowane na podstawie komentarza @Oliv.


Nie jest ZoneId.systemDefault()problematyczne, ponieważ strefy czasowe zmieniają się w ciągu roku. Więc jeśli w dniu 01 stycznia będę w strefie czasowej -05: 00 (centralnie), ale następnie w dniu 1 lipca będę w strefie czasowej -06: 00 (centralne światło dzienne), czy nie spowoduje to niedokładnych wyników z powodu oszczędności w świetle dziennym czas?
jhilden

94

Możesz użyć java.sql.Date.valueOf()metody jako:

Date date = java.sql.Date.valueOf(localDate);

Nie musisz tutaj dodawać informacji o czasie i strefie czasowej, ponieważ są one pobierane niejawnie.
Zobacz LocalDate na java.util.Date i odwrotnie, najprostsza konwersja?


To było dla mnie idealne, ponieważ potrzebowałem przekazać LocalDate do SQL. Jeśli jednak formatyzator daty zamierza coś zrobić z przesunięciem strefy czasowej przed sformatowaniem daty, może być o jeden dzień za wcześnie, w zależności od lokalnej strefy czasowej, w którym to przypadku zamiast tego będziesz potrzebować jednej z powyższych opcji.
Tom Dibble,

7
java.sql.Datejest przeznaczony dla warstwy bazy danych, JDBC, JPA. Warstwa internetowa (lub dowolna aplikacja kliencka) powinna być absolutnie wolna od jakichkolwiek zależności java.sql.*.
Tiny

2
@ Tiny java.sql.Date znajduje się w pliku rt.jar. Nie ma żadnych zewnętrznych zależności. Po prostu korzystasz z funkcji językowych.
George

2
java.sql.Datejest po prostu java.util.Dateustawiony na czas, 00:00:00ale punkt widzenia w perspektywie projektowej jest taki, że java.sql.*nie jest on przeznaczony dla przedniej warstwy, z którą klienci wchodzą w interakcje, jak serwlety / JSP. java.util.Datepo stronie Java i / java.sql.Timestamplub cokolwiek ma zastosowanie java.sql.*po stronie JDBC .
Tiny

5
Jest to „okropny hack” zgodnie z java.time * autor:. Stackoverflow.com/questions/33066904/... . W Javie 9 java.sql.*klasy będą osobną zależnością.
Dherik,

16

java.time ma interfejs Temporal, którego można używać do tworzenia obiektów Instant z większości klas czasu. Natychmiastowa reprezentuje milisekundy na osi czasu w Epoce - podstawowe odniesienie dla wszystkich innych dat i godzin.

Musimy przekonwertować datę na ZonedDateTime, z czasem i strefą, aby wykonać konwersję:

LocalDate ldate = ...;
Instant instant = Instant.from(ldate.atStartOfDay(ZoneId.of("GMT")));
Date date = Date.from(instant);

12

Aby utworzyć java.util.Date z java.time.LocalDate , musisz

  • dodaj czas do LocalDate
  • interpretować datę i godzinę w strefie czasowej
  • uzyskać liczbę sekund / milisekund od epoki
  • utwórz java.util.Date

Kod może wyglądać następująco:

LocalDate localDate = LocalDate.now();
Date date = new Date(localDate.atStartOfDay(ZoneId.of("America/New_York")).toEpochSecond() * 1000);

1
Literówka w identyfikatorze strefy (ZoneIf)
assylias

localDate.atStartOfDay () tworzy ZonedDateTime, ale nie ma metody toEpochSecond () dla ZonedDateTime.
Kevin Sadler,

@KevinSadler: Metoda toEpochSecondjest dziedziczona java.time.chrono.ChronoZonedDateTime. Zobacz docs.oracle.com/javase/8/docs/api/java/time/chrono/…
nosid

@nosid Dziękujemy za poprawkę. Kiedy używam uzupełniania kodu w Eclipse, to (i toInstance) nie występuje jako opcja. Ale jeśli napiszę to w całości, wydaje się to akceptowane. Niesłusznie doszedłem do wniosku, że nie była to metoda z tego powodu i że nie widziałem jej w Javadoc dla ZonedDateTime, ponieważ, jak mówisz, jest wymieniona jako metoda dziedziczona. Przepraszamy, proszę zaakceptować upclick :)
Kevin Sadler

11

To działa dla mnie:

java.util.Date d = new SimpleDateFormat("yyyy-MM-dd").parse(localDate.toString());

https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html#toString--


6
jest to dość nieefektywne
AndresQ

1
Konwersja na Instant może być pełna, ale budowanie i parsowanie
Łańcucha

1
Tak, nie tak wydajne, ale większość rozwiązań jest bardzo szczegółowa. To jest tylko pełne i łatwiejsze do odczytania i zrozumienia.
Ceklock,

2
@ehecatl Uważaj ... w przyszłości NY -> Tokio -> Mexico City może się odbyć w ciągu godziny (godzin);)
Stephan

3

Rozwiązanie Kotlin:

1) Wklej gdzieś tę funkcję rozszerzenia.

fun LocalDate.toDate(): Date = Date.from(this.atStartOfDay(ZoneId.systemDefault()).toInstant())

2) Użyj go i nigdy więcej google.

val myDate = myLocalDate.toDate()

11
Jak proste jest przejście na Kotlin? To jest pytanie Java.
ehecatl

1
Konwersja daty lokalnej Local Java jest powszechnym, irytującym problemem dla każdego programisty JVM. To rozwiązanie dla programistów Kotlin.
gyoder

-1
public static Date convertToTimeZone(Date date, String tzFrom, String tzTo) {
    return Date.from(LocalDateTime.ofInstant(date.toInstant(), ZoneId.of(tzTo)).atZone(ZoneId.of(tzFrom)).toInstant());
} 

2
Proszę wyjaśnić swoje rozwiązanie.
Martin Zabel


-3
java.util.Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());

czym twoja odpowiedź różni się od zaakceptowanej po 4 latach? Kopiuj-wklej, aby osiągnąć wzrost reputacji?
żądło
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.