Chuyển đổi java.time.LocalDate thành loại java.util.Date


372

Tôi muốn chuyển đổi java.time.LocalDatethành java.util.Dateloại. Bởi vì tôi muốn đặt ngày vào JDateChooser. Hoặc có bất kỳ trình chọn java.timengày hỗ trợ ngày?



2
LGoodDatePicker natively sử dụng gói java.time (aka Java 8 lần, hoặc JSR-310 Cụ thể, LGoodDatePicker sử dụng một "java.time.LocalDate" để lưu trữ các giá trị ngày Ảnh chụp màn hình và một bản demo đang ở.. Trang chủ Dự án .
BlakeTNC

Câu trả lời:


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

Giả sử trình chọn ngày của bạn sử dụng múi giờ mặc định của hệ thống để chuyển đổi ngày thành chuỗi.


JB Nizet có lẽ Java 8 đang ở giai đoạn đầu phát triển / phát hành và @ user3509494 đã thử nghiệm nó bằng cách nào đó.
russellhoff

2
Có thể tránh atStartOfDay(), vì nó thay đổi giá trị của ngày, như tôi hiểu.
yegor256

1
@JBNizet câu trả lời của bạn không có ý nghĩa nhiều với tôi đó là lý do tại sao tôi quyết định làm rõ. Tại sao bạn không làm rõ nó thay vì đưa ra những bình luận vô ích?
yegor256

12
Bởi vì tôi không thấy làm thế nào và tại sao nó cần bất kỳ sự làm rõ nào. 232 người nêu lên câu trả lời này, do đó tìm thấy nó rõ ràng. Bạn nói tạiStartOfDay thay đổi giá trị của ngày. Điều đó không có ý nghĩa. atStartOfDay thực hiện những gì javadoc nói: nó biến đổi LocalDate thành LocalDateTime, vào cùng ngày và vào đầu ngày.
JB Nizet

2
@cornz Bạn có chắc rằng kết quả của bạn không chính xác? Nếu bạn đang ở Đức, thì có thể phải làm gì đó với trục trặc 6 phút 32 giây ở Đức vào tháng 4 năm 1893. Xem timeanddate.com/time/zone/germany/berlin?syear=1850 để biết thêm chi tiết .
Dawood ibn Kareem

104

Đây là một lớp tiện ích tôi sử dụng để chuyển đổi các java.timelớp mới hơn thành java.util.Datecác đối tượng và ngược lại:

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

Được chỉnh sửa dựa trên bình luận @Oliv.


Không sử dụng ZoneId.systemDefault()có vấn đề vì múi giờ thay đổi so với năm ngoái. Vì vậy, nếu vào ngày 01 tháng 1, tôi ở múi giờ -05: 00 (trung tâm), nhưng vào ngày 01 tháng 7, tôi ở múi giờ -06: 00 (ánh sáng ban ngày trung tâm) sẽ không gây ra kết quả không chính xác vì tiết kiệm ánh sáng ban ngày thời gian?
jhilden

94

Bạn có thể sử dụng java.sql.Date.valueOf()phương pháp như:

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

Không cần thêm thông tin múi giờ và múi giờ ở đây vì chúng được thực hiện ngầm.
Xem LocalDate sang java.util.Date và ngược lại chuyển đổi đơn giản nhất?


Điều này là hoàn hảo đối với tôi, vì điều tôi cần là chuyển LocalDate vào SQL. Tuy nhiên, nếu trình định dạng Ngày của bạn sẽ làm gì đó về thay đổi múi giờ trước khi định dạng ngày, bạn có thể nhận được một ngày quá sớm tùy thuộc vào múi giờ địa phương, trong trường hợp đó bạn sẽ muốn một trong các tùy chọn trên thay thế.
Tom Dibble

7
java.sql.Datecó nghĩa là cho lớp cơ sở dữ liệu, JDBC, JPA. Lớp web (hoặc bất kỳ ứng dụng khách nào) hoàn toàn không có bất kỳ sự phụ thuộc nào java.sql.*.
Tiny

2
@Tiny java.sql.Date nằm trong rt.jar. Không có bất kỳ phụ thuộc bên ngoài. Bạn chỉ cần sử dụng các tính năng ngôn ngữ.
George

2
java.sql.Datechỉ java.util.Datevới thời gian được đặt thành 00:00:00nhưng điểm trong phối cảnh thiết kế java.sql.*là không dành cho lớp trước mà các máy khách tương tác với nhau như Servlets / JSP. java.util.Datetrong phía Java và java.sql.Timestamphoặc bất cứ điều gì có thể áp dụng từ java.sql.*phía JDBC .
Tiny

5
Đây là một "hack khủng khiếp" theo java.time. * Tác giả: stackoverflow.com/questions/33066904/ . Trong Java 9 java.sql.*lớp sẽ là một phụ thuộc riêng.
Dherik

16

java.time có giao diện Temporal mà bạn có thể sử dụng để tạo các đối tượng Instant từ hầu hết các lớp thời gian. Instant biểu thị mili giây trên dòng thời gian trong Epoch - tham chiếu cơ bản cho tất cả các ngày và thời gian khác.

Chúng tôi cần chuyển đổi Ngày thành ZiatedDateTime, với Thời gian và Vùng, để thực hiện chuyển đổi:

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

12

Để tạo java.util.Date từ java.time.LocalDate , bạn phải

  • thêm thời gian vào LocalDate
  • diễn giải ngày và giờ trong múi giờ
  • lấy số giây / mili giây kể từ epoch
  • tạo java.util.Date

Mã có thể trông như sau:

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

1
Typo trong vùng id (Vùng If)
assylias

localDate.atStartOfDay () tạo ra một ZiatedDateTime, nhưng không có phương thức toEpochSecond () cho ZiatedDateTime.
Kevin Sadler

@KevinSadler: Phương pháp toEpochSecondđược kế thừa từ java.time.chrono.ChronoZonedDateTime. Xem docs.oracle.com/javase/8/docs/api/java/time/ synco / Giả
nosid

@nosid Cảm ơn bạn đã sửa chữa. Khi tôi sử dụng hoàn thành mã trong Eclipse, nó (và toInstance) không xuất hiện dưới dạng tùy chọn. Nhưng nếu tôi gõ nó đầy đủ, nó dường như được chấp nhận. Tôi đã kết luận sai rằng đó không phải là một phương thức vì thực tế này và tôi đã không thấy nó trên Javadoc cho ZencedDateTime, vì nó được liệt kê như một phương thức được kế thừa, như bạn nói. Xin lỗi, xin vui lòng chấp nhận một upclick :)
Kevin Sadler

11

Điều này làm việc cho tôi:

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
điều này khá không hiệu quả
AndresQ

1
Chuyển đổi sang Instant có thể dài dòng, nhưng xây dựng và phân tích Chuỗi giống như đi từ New York đến Thành phố Mexico qua Tokyo ...
ehecatl

1
Vâng, không hiệu quả lắm, nhưng hầu hết các giải pháp đều rất dài dòng. Đây chỉ là dài dòng và dễ đọc và dễ hiểu hơn.
ceklock

2
@ehecatl Hãy coi chừng ... trong tương lai NY -> Tokyo -> Thành phố Mexico có thể được thực hiện trong vòng vài giờ;)
Stephan

3

Giải pháp của Kotlin:

1) Dán chức năng mở rộng này ở đâu đó.

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

2) Sử dụng nó, và không bao giờ google cái này một lần nữa.

val myDate = myLocalDate.toDate()

11
Làm thế nào là "chuyển sang Kotlin" đơn giản? Đây là một câu hỏi Java.
ehecatl

1
Chuyển đổi Java LocalDate thành ngày là một vấn đề phổ biến, gây khó chịu cho bất kỳ nhà phát triển JVM nào. Đây là một giải pháp cho các nhà phát triển Kotlin.
quay

-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
Hãy giải thích giải pháp của bạn.
Martin Zabel

-2

Đơn giản

public Date convertFrom(LocalDate date) {
    return java.sql.Timestamp.valueOf(date.atStartOfDay());
}

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

Câu trả lời của bạn khác với câu trả lời sau 4 năm như thế nào? Sao chép-dán để đạt được danh tiếng tăng?
stinger
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.