[英]Convert ZonedDateTime to java.util.Date
How do i convert ZonedDateTime to java.util.Date without changing the timezone.如何在不更改时区的情况下将 ZonedDateTime 转换为 java.util.Date。
In my below method when i call Date.from(datetime.toInstant())
it convert it to local time zone in my case SGT.在我下面的方法中,当我调用
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");
}
Output
输出
---> 2019-03-13_08:46:26.593
Wed Mar 13 16:46:26 SGT 2019
You can add offset millis by yourself.您可以自己添加偏移毫秒。 See the example using
java.util.Date
:请参阅使用
java.util.Date
的示例:
long offsetMillis = ZoneOffset.from(dateTime).getTotalSeconds() * 1000;
long isoMillis = dateTime.toInstant().toEpochMilli();
Date date = new Date(isoMillis + offsetMillis);
The java.util
Date-Time API and their formatting API, SimpleDateFormat
are outdated and error-prone. java.util
Date-Time API 及其格式化 API SimpleDateFormat
已过时且容易出错。 It is recommended to stop using them completely and switch to the modern Date-Time API * .建议完全停止使用它们并切换到现代 Date-Time API * 。 However, for any reason, if you want to change
java.time.ZonedDateTime
to java.util.Date
, I recommend you avoid any kind of manual calculations when you already have an inbuilt API to meet the requirement.但是,无论出于何种原因,如果您想将
java.time.ZonedDateTime
更改为java.util.Date
,我建议您在已经拥有满足要求的内置 API 时避免任何类型的手动计算。
All you need to do is to add the offset to the input datetime
which you can do by using ZonedDateTime#plusSeconds
as shown below:您需要做的就是将偏移量添加到输入
datetime
,您可以使用ZonedDateTime#plusSeconds
,如下所示:
datetime = datetime.plusSeconds(datetime.getOffset().getTotalSeconds());
Date date = Date.from(datetime.toInstant());
Demo:演示:
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));
}
}
Output:输出:
2021-10-03T05:11:57
Learn more about the modern Date-Time API * from Trail: Date Time .从Trail: Date Time 中了解有关现代日期时间 API * 的更多信息。
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project . * 出于任何原因,如果您必须坚持使用 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 。
I would do as ETO states on his answer with the exception of using TimeUnit for getting the seconds converted into milliseconds:除了使用 TimeUnit 将秒转换为毫秒之外,我会按照 ETO 在他的回答中的说明进行操作:
long offsetMillis = TimeUnit.SECONDS.toMillis(ZoneOffset.from(dateTime).getTotalSeconds());
long isoMillis = dateTime.toInstant().toEpochMilli();
Date date = new Date(isoMillis + offsetMillis);
or the other option would be:或者另一种选择是:
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));
To preserve the time zone simply preserve your ZonedDateTime
.要保留时区,只需保留您的
ZonedDateTime
。 It can be formatted directly to the output your require.它可以直接格式化为您需要的输出。 Don't involve the outdated and poorly designed
Date
class.不要涉及过时且设计不佳的
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");
}
Try it out:试试看:
ZonedDateTime zdt = ZonedDateTime.of(
2019, 3, 13, 8, 46, 26, 593_000_000, ZoneId.of("Etc/UTC"));
printDate(zdt);
Output:输出:
---> 2019-03-13_08:46:26.593 Wed Mar 13 08:46:26 UTC 2019
A Date
falsely pretends to have a time zone. Date
错误地假装有一个时区。 It hasn't got any.它没有任何。 So there is no change of time zone going on.
所以时区没有变化。
toInstant()
discards the time zone because an Instant
hasn't got a time zone either. toInstant()
丢弃时区,因为Instant
也没有时区。 Date.from()
performs the conversion withut any regard to time zone. Date.from()
执行转换而不考虑时区。 System.out.println()
implicitly calls Date.toString()
. System.out.println()
隐式调用Date.toString()
。 The toString()
method uses the JVM's default time zone for rendering the string. toString()
方法使用JVM 的默认时区来呈现字符串。 It's pretty confusing alright.这很混乱好吧。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.