![](/img/trans.png)
[英]Whats the difference between java.util.Date and Zoneddatetime?
[英]Convert ZonedDateTime to java.util.Date
如何在不更改時區的情況下將 ZonedDateTime 轉換為 java.util.Date。
在我下面的方法中,當我調用Date.from(datetime.toInstant())
,它在我的案例 SGT 中將其轉換為本地時區。
public static void printDate(ZonedDateTime datetime) {
System.out.println("---> " + datetime.format(DateTimeFormatter.ofPattern(API_TIME_STAMP_PATTERN)));
System.out.println(Date.from(datetime.toInstant()));
System.out.println("\n");
}
輸出
---> 2019-03-13_08:46:26.593
Wed Mar 13 16:46:26 SGT 2019
您可以自己添加偏移毫秒。 請參閱使用java.util.Date
的示例:
long offsetMillis = ZoneOffset.from(dateTime).getTotalSeconds() * 1000;
long isoMillis = dateTime.toInstant().toEpochMilli();
Date date = new Date(isoMillis + offsetMillis);
java.util
Date-Time API 及其格式化 API SimpleDateFormat
已過時且容易出錯。 建議完全停止使用它們並切換到現代 Date-Time API * 。 但是,無論出於何種原因,如果您想將java.time.ZonedDateTime
更改為java.util.Date
,我建議您在已經擁有滿足要求的內置 API 時避免任何類型的手動計算。
您需要做的就是將偏移量添加到輸入datetime
,您可以使用ZonedDateTime#plusSeconds
,如下所示:
datetime = datetime.plusSeconds(datetime.getOffset().getTotalSeconds());
Date date = Date.from(datetime.toInstant());
演示:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
// Test
printDate(ZonedDateTime.now(ZoneId.of("Asia/Singapore")));
}
public static void printDate(ZonedDateTime datetime) {
datetime = datetime.plusSeconds(datetime.getOffset().getTotalSeconds());
Date date = Date.from(datetime.toInstant());
// Showing date-time in Singapore timezone
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Singapore"));
System.out.println(sdf.format(date));
}
}
輸出:
2021-10-03T05:11:57
從Trail: Date Time 中了解有關現代日期時間 API * 的更多信息。
* 出於任何原因,如果您必須堅持使用 Java 6 或 Java 7,您可以使用ThreeTen-Backport,它將大部分java.time功能向后移植到 Java 6 和 7。如果您正在為 Android 項目和您的 Android API 工作級別仍然不符合 Java-8,請檢查 通過 desugaring和How to use ThreeTenABP in Android Project 可用的 Java 8+ APIs 。
除了使用 TimeUnit 將秒轉換為毫秒之外,我會按照 ETO 在他的回答中的說明進行操作:
long offsetMillis = TimeUnit.SECONDS.toMillis(ZoneOffset.from(dateTime).getTotalSeconds());
long isoMillis = dateTime.toInstant().toEpochMilli();
Date date = new Date(isoMillis + offsetMillis);
或者另一種選擇是:
var localDate = LocalDateTime.now();
final long offSetHours = ChronoUnit.HOURS.between(localDate.atZone(ZoneId.of("YOUR_TIME_ZONE_ID")),
localDate.atZone(ZoneId.of("UTC")));
return Date.from(Instant.parse(dateAsStringISO8601).plus(offSetHours, ChronoUnit.HOURS));
要保留時區,只需保留您的ZonedDateTime
。 它可以直接格式化為您需要的輸出。 不要涉及過時且設計不佳的Date
類。
private static final String API_TIME_STAMP_PATTERN = "yyyy-MM-dd_HH:mm:ss.SSS";
private static final DateTimeFormatter FORMATTER
= DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz y", Locale.ROOT);
public static void printDate(ZonedDateTime datetime) {
System.out.println("---> " + datetime.format(DateTimeFormatter.ofPattern(API_TIME_STAMP_PATTERN)));
System.out.println(datetime.format(FORMATTER));
System.out.println("\n");
}
試試看:
ZonedDateTime zdt = ZonedDateTime.of(
2019, 3, 13, 8, 46, 26, 593_000_000, ZoneId.of("Etc/UTC"));
printDate(zdt);
輸出:
---> 2019-03-13_08:46:26.593 Wed Mar 13 08:46:26 UTC 2019
Date
錯誤地假裝有一個時區。 它沒有任何。 所以時區沒有變化。 toInstant()
丟棄時區,因為Instant
也沒有時區。 Date.from()
執行轉換而不考慮時區。 System.out.println()
隱式調用Date.toString()
。 toString()
方法使用JVM 的默認時區來呈現字符串。 這很混亂好吧。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.