Java:将字符串转换为不同的时区

Bus*_*ter 1 java

我已经尝试使用不同的 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

Arv*_*ash 6

java.time

日期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

  • @Buster,您是否遵循评论“如果此日期时间为 UTC,则将 ZoneId.systemDefault() 替换为 ZoneOffset.UTC”? (3认同)