Chuyển đổi LocalDateTime thành LocalDateTime trong UTC.
LocalDateTime convertToUtc(LocalDateTime date) {
//do conversion
}
Tôi đã tìm kiếm trên mạng. Nhưng không nhận được một giải pháp
Chuyển đổi LocalDateTime thành LocalDateTime trong UTC.
LocalDateTime convertToUtc(LocalDateTime date) {
//do conversion
}
Tôi đã tìm kiếm trên mạng. Nhưng không nhận được một giải pháp
Câu trả lời:
Có một cách đơn giản hơn
LocalDateTime.now(Clock.systemUTC())
LocalDateTime không chứa thông tin Vùng. ZonedDatetime không.
Nếu bạn muốn chuyển LocalDateTime sang UTC, bạn cần phải bọc bởi nắm đấm ZonedDateTime.
Bạn có thể chuyển đổi như bên dưới.
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt.toLocalTime());
ZonedDateTime ldtZoned = ldt.atZone(ZoneId.systemDefault());
ZonedDateTime utcZoned = ldtZoned.withZoneSameInstant(ZoneId.of("UTC"));
System.out.println(utcZoned.toLocalTime());
ldt.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("UTC"))
trong khi ngắn gọn vẫn truyền tải đủ ý nghĩa để không cần đến biến cá thể được khoanh vùng.
ZoneOffset.UTC
là một sự thay thế tốt đẹp choZoneId.of("UTC")
OffsetDateTime
thích hợp hơn ZonedDateTime
. Sử dụng: OffsetDateTime.now( ZoneOffset.UTC )
hoặcmyInstant.atOffset( ZoneOffset.UTC )
Sử dụng bên dưới. Nó lấy ngày giờ địa phương và chuyển đổi nó thành UTC bằng cách sử dụng múi giờ. Bạn không cần tạo chức năng của nó.
ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);
System.out.println(nowUTC.toString());
Nếu bạn cần lấy phần LocalDateTime của ZonedDateTime thì bạn có thể sử dụng phần sau.
nowUTC.toLocalDateTime();
Đây là một phương pháp tĩnh mà tôi sử dụng trong ứng dụng của mình để chèn thời gian UTC trong mysql vì tôi không thể thêm giá trị mặc định UTC_TIMESTAMP vào cột ngày giờ.
public static LocalDateTime getLocalDateTimeInUTC(){
ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);
return nowUTC.toLocalDateTime();
}
Đây là một lớp tiện ích nhỏ đơn giản mà bạn có thể sử dụng để chuyển đổi ngày giờ cục bộ từ vùng này sang vùng khác, bao gồm một phương thức tiện ích trực tiếp để chuyển đổi ngày giờ cục bộ từ vùng hiện tại sang UTC (với phương thức chính để bạn có thể chạy nó và xem kết quả của một bài kiểm tra đơn giản):
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
public final class DateTimeUtil {
private DateTimeUtil() {
super();
}
public static void main(final String... args) {
final LocalDateTime now = LocalDateTime.now();
final LocalDateTime utc = DateTimeUtil.toUtc(now);
System.out.println("Now: " + now);
System.out.println("UTC: " + utc);
}
public static LocalDateTime toZone(final LocalDateTime time, final ZoneId fromZone, final ZoneId toZone) {
final ZonedDateTime zonedtime = time.atZone(fromZone);
final ZonedDateTime converted = zonedtime.withZoneSameInstant(toZone);
return converted.toLocalDateTime();
}
public static LocalDateTime toZone(final LocalDateTime time, final ZoneId toZone) {
return DateTimeUtil.toZone(time, ZoneId.systemDefault(), toZone);
}
public static LocalDateTime toUtc(final LocalDateTime time, final ZoneId fromZone) {
return DateTimeUtil.toZone(time, fromZone, ZoneOffset.UTC);
}
public static LocalDateTime toUtc(final LocalDateTime time) {
return DateTimeUtil.toUtc(time, ZoneId.systemDefault());
}
}
Nhìn vào câu trả lời và câu hỏi, có vẻ như câu hỏi đã được sửa đổi đáng kể. Vì vậy, để trả lời câu hỏi hiện tại:
Chuyển đổi LocalDateTime thành LocalDateTime trong UTC.
LocalDateTime
không lưu trữ bất kỳ thông tin nào về múi giờ, về cơ bản nó chỉ giữ các giá trị của năm, tháng, ngày, giờ, phút, giây và các đơn vị nhỏ hơn. Vì vậy, một câu hỏi quan trọng là: Múi giờ của bản gốc là LocalDateTime
gì? Nó cũng có thể là UTC rồi, do đó không cần phải chuyển đổi.
Cân nhắc rằng bạn đã đặt câu hỏi dù sao, có thể bạn muốn nói rằng giờ gốc nằm trong múi giờ mặc định của hệ thống và bạn muốn chuyển đổi nó thành UTC. Bởi vì thường một LocalDateTime
đối tượng được tạo bằng cách sử dụng LocalDateTime.now()
nó trả về thời gian hiện tại trong múi giờ mặc định của hệ thống. Trong trường hợp này, chuyển đổi sẽ như sau:
LocalDateTime convertToUtc(LocalDateTime time) {
return time.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}
Một ví dụ về quá trình chuyển đổi:
2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+1 // [atZone] converted to ZonedDateTime (system timezone is Madrid)
2019-02-25 10:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 10:39 // [toLocalDateTime] losing the timezone information
Trong bất kỳ trường hợp nào khác, khi bạn chỉ định rõ ràng múi giờ của thời gian để chuyển đổi, chuyển đổi sẽ như sau:
LocalDateTime convertToUtc(LocalDateTime time, ZoneId zone) {
return time.atZone(zone).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}
Một ví dụ về quá trình chuyển đổi:
2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+2 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2019-02-25 09:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 09:39 // [toLocalDateTime] losing the timezone information
atZone()
Phương phápKết quả của atZone()
phương pháp phụ thuộc vào thời gian đã qua làm đối số của nó, vì nó xem xét tất cả các quy tắc của múi giờ, bao gồm Giờ tiết kiệm ánh sáng ban ngày (DST). Trong các ví dụ, thời gian là ngày 25 tháng 2, ở Châu Âu, điều này có nghĩa là giờ mùa đông (không có DST).
Nếu chúng tôi sử dụng một ngày khác, giả sử ngày 25 tháng 8 so với năm ngoái, kết quả sẽ khác, xem xét DST:
2018-08-25 11:39 // [time] original LocalDateTime without a timezone
2018-08-25 11:39 GMT+3 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2018-08-25 08:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2018-08-25 08:39 // [toLocalDateTime] losing the timezone information
Giờ GMT không thay đổi. Do đó, hiệu số trong các múi giờ khác được điều chỉnh. Trong ví dụ này, giờ mùa hè của Estonia là GMT + 3 và giờ mùa đông là GMT + 2.
Ngoài ra, nếu bạn chỉ định thời gian trong quá trình chuyển đổi đồng hồ lùi lại một giờ. Ví dụ: ngày 28 tháng 10 năm 2018 03:30 đối với Estonia, điều này có nghĩa là hai thời điểm khác nhau:
2018-10-28 03:30 GMT+3 // summer time [UTC 2018-10-28 00:30]
2018-10-28 04:00 GMT+3 // clocks are turned back 1 hour [UTC 2018-10-28 01:00]
2018-10-28 03:00 GMT+2 // same as above [UTC 2018-10-28 01:00]
2018-10-28 03:30 GMT+2 // winter time [UTC 2018-10-28 01:30]
Nếu không chỉ định chênh lệch theo cách thủ công (GMT + 2 hoặc GMT + 3), thời gian 03:30
cho múi giờ Europe/Tallinn
có thể có nghĩa là hai thời gian UTC khác nhau và hai hiệu số khác nhau.
Như bạn có thể thấy, kết quả cuối cùng phụ thuộc vào múi giờ của thời gian đã qua làm đối số. Vì không thể trích xuất múi giờ từ LocalDateTime
đối tượng, bạn phải tự biết múi giờ đó đến từ múi giờ nào để chuyển đổi nó sang UTC.
LocalDateTime does not store any information about the time-zone, it just basically holds the values of year, month, day, hour, minute, second, and smaller units.
tldr: đơn giản là không có cách nào để làm điều đó; nếu bạn đang cố gắng làm điều đó, bạn nhận được LocalDateTime sai.
Lý do là LocalDateTime không ghi lại Múi giờ sau khi các phiên bản được tạo. Bạn không thể chuyển đổi một ngày giờ không có múi giờ thành một ngày giờ khác dựa trên một múi giờ cụ thể.
Trên thực tế, LocalDateTime.now () không bao giờ được gọi trong mã sản xuất trừ khi mục đích của bạn là nhận được kết quả ngẫu nhiên. Khi bạn tạo một phiên bản LocalDateTime như vậy, phiên bản này CHỈ chứa ngày giờ dựa trên múi giờ của máy chủ hiện tại, có nghĩa là đoạn mã này sẽ tạo ra kết quả khác nếu nó đang chạy một máy chủ có cấu hình múi giờ khác.
LocalDateTime có thể đơn giản hóa việc tính toán ngày tháng. Nếu bạn muốn có thời gian dữ liệu thực sự có thể sử dụng được trên toàn cầu, hãy sử dụng ZonedDateTime hoặc OffsetDateTime: https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html .
bạn có thể triển khai một người trợ giúp làm những việc như vậy:
public static LocalDateTime convertUTCFRtoUTCZ(LocalDateTime dateTime) {
ZoneId fr = ZoneId.of("Europe/Paris");
ZoneId utcZ = ZoneId.of("Z");
ZonedDateTime frZonedTime = ZonedDateTime.of(dateTime, fr);
ZonedDateTime utcZonedTime = frZonedTime.withZoneSameInstant(utcZ);
return utcZonedTime.toLocalDateTime();
}
public static String convertFromGmtToLocal(String gmtDtStr, String dtFormat, TimeZone lclTimeZone) throws Exception{
if (gmtDtStr == null || gmtDtStr.trim().equals("")) return null;
SimpleDateFormat format = new SimpleDateFormat(dtFormat);
format.setTimeZone(getGMTTimeZone());
Date dt = format.parse(gmtDtStr);
format.setTimeZone(lclTimeZone);
return
format.format (dt); }
SimpleDateFormat
lớp học đã lỗi thời và khét tiếng phiền phức . Ít nhất không phải là tùy chọn đầu tiên. Và không phải không có bất kỳ đặt trước. Hôm nay chúng ta có rất nhiều thứ tốt hơn java.time
, API ngày giờ hiện đại của Java và nó DateTimeFormatter
.