Ubah java.time.LocalDate menjadi tipe java.util.Date

372

Saya ingin mengonversi java.time.LocalDatemenjadi java.util.Datetipe. Karena saya ingin mengatur tanggal JDateChooser. Atau adakah pemilih tanggal yang mendukung java.timetanggal?

Kavinda Gehan
sumber
1
Sudahkah Anda membaca stackoverflow.com/questions/21242110/… ?
Daksh Shah
2
LGoodDatePicker asli menggunakan paket java.time (alias Java 8 waktu, atau JSR-310 . Secara khusus, LGoodDatePicker menggunakan "java.time.LocalDate" untuk menyimpan nilai tanggal. Screenshot dan demo ada di Project Homepage .
BlakeTNC

Jawaban:

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

Itu mengasumsikan pemilih tanggal Anda menggunakan zona waktu default sistem untuk mengubah tanggal menjadi string.

JB Nizet
sumber
JB Nizet mungkin Java 8 berada pada tahap awal pengembangan / rilis dan @ user3509494 entah bagaimana mengujinya.
russellhoff
2
Apakah mungkin untuk menghindari atStartOfDay(), karena itu mengubah nilai tanggal, seperti yang saya mengerti.
yegor256
1
@JBNizet jawaban Anda tidak masuk akal bagi saya itu sebabnya saya memutuskan untuk mengklarifikasi. Mengapa Anda tidak menjelaskannya daripada membuat komentar yang tidak berguna?
yegor256
12
Karena saya tidak melihat bagaimana dan mengapa itu perlu klarifikasi. 232 orang meninggikan jawaban ini, dengan demikian merasa jelas. Anda mengatakan diStartOfDay mengubah nilai tanggal. Itu tidak masuk akal. atStartOfDay melakukan apa yang dikatakan javadoc: ia mengubah LocalDate menjadi LocalDateTime, pada tanggal yang sama, dan pada awal hari.
JB Nizet
2
@ cornz Apakah Anda yakin hasil Anda salah? Jika Anda berada di Jerman, maka mungkin ada hubungannya dengan kesalahan 6 menit 32 detik dalam waktu di Jerman, pada bulan April 1893. Lihat timeanddate.com/time/zone/germany/berlin?syear=1850 untuk beberapa detail .
Dawood ibn Kareem
104

Ini kelas utilitas yang saya gunakan untuk mengonversi java.timekelas yang lebih baru ke java.util.Dateobjek dan sebaliknya:

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();
  }
}

Diedit berdasarkan pada komentar @Oliv.

Brice Roncace
sumber
Tidak menggunakan ZoneId.systemDefault()bermasalah karena zona waktu berubah berdasarkan corse tahun ini. Jadi jika pada 01-Jan saya berada di zona waktu -05: 00 (tengah), tetapi kemudian pada 01-Juli saya berada di zona waktu -06: 00 (tengah hari) tidak akan menyebabkan hasil yang tidak akurat karena penghematan siang hari waktu?
jhilden
95

Anda dapat menggunakan java.sql.Date.valueOf()metode sebagai:

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

Tidak perlu menambahkan waktu dan info zona waktu di sini karena mereka diambil secara implisit.
Lihat LocalDate ke java.util.Date dan sebaliknya konversi paling sederhana?

George
sumber
Ini sempurna bagi saya, karena yang saya butuhkan adalah untuk melewatkan LocalDate ke SQL. Namun, jika pemformat Tanggal Anda akan melakukan sesuatu tentang pergeseran zona waktu sebelum memformat tanggal, Anda mungkin mendapatkan satu hari terlalu dini tergantung pada zona waktu setempat, dalam hal ini Anda akan menginginkan salah satu opsi di atas.
Tom Dibble
7
java.sql.Datedimaksudkan untuk lapisan basis data, JDBC, JPA. Lapisan web (atau aplikasi klien apa pun) harus benar-benar bebas dari ketergantungan apa pun java.sql.*.
Tiny
2
@Tiny java.sql.Date berada di rt.jar. Tidak ada ketergantungan eksternal. Anda cukup menggunakan fitur bahasa.
George
2
java.sql.Datehanya java.util.Datedengan waktu yang ditentukan 00:00:00tetapi titik dalam perspektif desain adalah yang java.sql.*tidak dimaksudkan untuk lapisan depan yang berinteraksi dengan klien seperti Servlets / JSP. java.util.Datedi sisi Jawa dan java.sql.Timestampatau apa pun yang berlaku dari java.sql.*di sisi JDBC .
Tiny
5
Ini adalah "peretasan yang mengerikan" sesuai dengan java.time. * Penulis: stackoverflow.com/questions/33066904/… . Di Java 9 java.sql.*kelas akan menjadi ketergantungan yang terpisah.
Dherik
16

java.time memiliki antarmuka Temporal yang dapat Anda gunakan untuk membuat objek Instan dari sebagian besar kelas waktu. Instan mewakili milidetik pada garis waktu di Zaman - referensi dasar untuk semua tanggal dan waktu lainnya.

Kita perlu mengonversi Tanggal menjadi ZonedDateTime, dengan Waktu dan Zona, untuk melakukan konversi:

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

Untuk membuat java.util.Date dari java.time.LocalDate , Anda harus melakukannya

  • tambahkan waktu ke LocalDate
  • menginterpretasikan tanggal dan waktu dalam zona waktu
  • dapatkan jumlah detik / milidetik sejak zaman
  • buat java.util.Date

Kode tersebut mungkin terlihat sebagai berikut:

LocalDate localDate = LocalDate.now();
Date date = new Date(localDate.atStartOfDay(ZoneId.of("America/New_York")).toEpochSecond() * 1000);
tidak ada
sumber
1
Typo in zone id (ZoneIf)
assylias
localDate.atStartOfDay () membuat ZonedDateTime, tetapi tidak ada metode toEpochSecond () untuk ZonedDateTime.
Kevin Sadler
@KevinSadler: Metode toEpochSecondini diwarisi dari java.time.chrono.ChronoZonedDateTime. Lihat docs.oracle.com/javase/8/docs/api/java/time/chrono/…
nosid
@nosid Terima kasih atas koreksi Anda. Ketika saya menggunakan penyelesaian kode di Eclipse, itu (dan toInstance) tidak hadir sebagai opsi. Tetapi jika saya mengetiknya secara penuh, sepertinya itu akan diterima. Saya salah menyimpulkan bahwa itu bukan metode karena fakta ini dan bahwa saya tidak melihatnya di Javadoc untuk ZonedDateTime, karena terdaftar sebagai metode warisan, seperti yang Anda katakan. Maaf, silakan terima klik up :)
Kevin Sadler
11

Ini bekerja untuk saya:

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--

ceklock
sumber
6
ini cukup tidak efisien
AndresQ
1
Konversi ke Instan mungkin bertele-tele, tetapi membangun dan mengurai String seperti pergi dari New York ke Mexico City melalui Tokyo ...
ehecatl
1
Ya, tidak begitu efisien, tetapi sebagian besar solusi sangat bertele-tele. Ini hanya verbose dan lebih mudah dibaca dan dimengerti.
ceklock
2
@ehecatl Hati-hati ... di masa depan NY -> Tokyo -> Mexico City dapat dilakukan dalam beberapa jam;)
Stephan
3

Solusi Kotlin:

1) Tempel fungsi ekstensi ini di suatu tempat.

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

2) Gunakan, dan jangan pernah google ini lagi.

val myDate = myLocalDate.toDate()
gyoder
sumber
11
Bagaimana "beralih ke Kotlin" sederhana? Ini adalah pertanyaan Java.
ehecatl
1
Mengubah Java LocalDate to Date adalah masalah umum yang menjengkelkan bagi setiap pengembang JVM. Ini adalah solusi untuk pengembang 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());
} 
William Nguyen
sumber
2
Tolong jelaskan solusi Anda.
Martin Zabel
-2

Sederhana

public Date convertFrom(LocalDate date) {
    return java.sql.Timestamp.valueOf(date.atStartOfDay());
}
Artur Luiz Oliveira
sumber
-3
java.util.Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
Mahendra Sri
sumber
bagaimana jawaban Anda berbeda dari yang diterima setelah 4 tahun? Copy-paste untuk mencapai peningkatan reputasi?
stinger