我已经尝试使用不同的 Java 格式化程序进行各种不同的转换,但我仍然对看似简单的东西没有任何运气。
我有一个字符串,它是 UTC 格式的日期/时间。我正在尝试将其转换为另一个时区。有人能告诉我为什么下面的方法不起作用吗?时区正在改变,但改变的方式不正确。
更新:(虽然我似乎没有正确地将时区设置为 UTC,因为转换也不正确)。
String dateInput = "2021-02-16 20:57:43";
SimpleDateFormat mdyUtc = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
mdyUtc.setTimeZone(TimeZone.getTimeZone("UTC");
Date utcOutput = mdyUtc.parse(dateInput);
SimpleDateFormat mdyOffset = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
mdyOffset.setTimeZone(TimeZone.getTimeZone("GMT-10:00");
Date localOutput = mdyOffset.parse(dateInput);
System.out.print("UTC date = " + utcOutput);
System.out.print("Changed date = " + localOutput);
Run Code Online (Sandbox Code Playgroud)
输出:
UTC 日期 = 2021 年美国东部时间 2 月 16 日星期二 15:57:43
更改日期 = 2021 年东部标准时间 2 月 17 日星期三 01:57:43
日期java.util时间 API 及其格式化 APISimpleDateFormat已经过时且容易出错。建议完全停止使用它们并切换到现代日期时间 API *。
使用现代日期时间 API:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String dateInput = "2021-02-16 20:57:43";
// Replace ZoneId.systemDefault() with ZoneOffset.UTC if this date-time is in UTC
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH)
.withZone(ZoneId.systemDefault());
ZonedDateTime zdt = ZonedDateTime.parse(dateInput, dtf);
ZonedDateTime result = zdt.withZoneSameInstant(ZoneId.of("GMT-10:00"));
System.out.println(result);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
2021-02-16T10:57:43-10:00[GMT-10:00]
Run Code Online (Sandbox Code Playgroud)
从Trail: Date Time中了解有关现代日期时间 API 的更多信息。
java.util.Date从出发ZonedDateTime吗?如果您确实需要使用java.util.Date,可以 ZonedDateTime按如下方式转换为:
Date date = Date.from(result.toInstant());
Run Code Online (Sandbox Code Playgroud)
请注意,该对象不是像现代日期时间类型java.util.Date那样的真正的日期时间对象;相反,它表示自称为“纪元”的标准基准时间(或 UTC)以来的毫秒数。当您打印 的对象时,其方法会返回 JVM 时区中的日期时间(根据该毫秒值计算得出)。如果您需要打印不同时区的日期时间,则需要将时区设置为并从中获取格式化字符串。January 1, 1970, 00:00:00 GMTjava.util.DatetoStringSimpleDateFormat
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用ThreeTen-Backport,它将大多数java.time功能向后移植到 Java 6 和 7。如果您正在处理 Android 项目和 Android API level 仍然不符合 Java-8,请检查通过脱糖可用的 Java 8+ API以及如何在 Android 项目中使用 ThreeTenABP。