![](/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.