将日期从GMT时区转换为本地时区-使用ISO_OFFSET_DATE_TIME

时间:2018-10-15 21:30:02

标签: java date gmt java.util.date java.time

我有一个日期,假设是格林尼治标准时间,我想使用ISO_OFFSET_DATE_TIME格式将其转换为本地时区。

基本上,我想去:

2018-03-13 03:00:00.0

收件人:

2018-03-13T00:00:00-09:00

显然,这将改变,具体取决于您的本地时区。

关于如何做到这一点的任何想法?

2 个答案:

答案 0 :(得分:1)

您可以利用ZonedDateTime来做到这一点。您只需要将日期读为UTC并根据需要进行转换即可。您可能会得到像这样的东西:

String readPattern = "yyyy-MM-dd HH:mm:ss.S";
DateTimeFormatter readDateTimeFormatter = DateTimeFormatter.ofPattern(readPattern).withZone(ZoneOffset.UTC);
LocalDateTime utcLocalDateTime = LocalDateTime.parse("2018-03-13 03:00:00.0", readDateTimeFormatter);
ZonedDateTime localZonedDateTime = utcLocalDateTime.atOffset(ZoneOffset.UTC).atZoneSameInstant(ZoneId.systemDefault());
String writePattern = "yyyy-MM-dd HH:mm:ssXXX";
DateTimeFormatter writeDateTimeFormatter = DateTimeFormatter.ofPattern(writePattern);
System.out.println(writeDateTimeFormatter.format(localZonedDateTime));

有关更多信息,请参见:

答案 1 :(得分:1)

将日期时间字符串解析为LocalDateTime

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s.S", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse("2018-03-13 03:00:00.0", dtf);

将其与 UTC 偏移量相结合以创建 OffsetDateTime

OffsetDateTime odtUtc = ldt.atOffset(ZoneOffset.UTC);

创建它的副本,偏移量设置为 -09:00,同时保持时刻不变:

OffsetDateTime odtUtcMinus9 = odtUtc.withOffsetSameInstant(ZoneOffset.of("+09:00"));

演示:

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s.S", Locale.ENGLISH);
        LocalDateTime ldt = LocalDateTime.parse("2018-03-13 03:00:00.0", dtf);
        System.out.println(ldt); // 2018-03-13T03:00

        OffsetDateTime odtUtc = ldt.atOffset(ZoneOffset.UTC);
        System.out.println(odtUtc); // 2018-03-13T03:00Z

        OffsetDateTime odtUtcMinus9 = odtUtc.withOffsetSameInstant(ZoneOffset.of("+09:00"));
        System.out.println(odtUtcMinus9); // 2018-03-13T12:00+09:00
    }
}

请注意,时区偏移是固定的,即它独立于 DST。如果您要根据 DST 自动调整时区偏移,请使用 ZonedDateTime。这些方法与我们在上一个演示中使用的方法非常相似。

演示:

import java.time.LocalDateTime;
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) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s.S", Locale.ENGLISH);
        LocalDateTime ldt = LocalDateTime.parse("2018-03-13 03:00:00.0", dtf);
        System.out.println(ldt); // 2018-03-13T03:00

        ZonedDateTime zdtUtc = ldt.atZone(ZoneId.of("Etc/UTC"));
        System.out.println(zdtUtc); // 2018-03-13T03:00Z[Etc/UTC]

        ZonedDateTime zdtAmericaAdak = zdtUtc.withZoneSameInstant(ZoneId.of("America/Adak"));
        System.out.println(zdtAmericaAdak); // 2018-03-12T18:00-09:00[America/Adak]

        // A custom format
        DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSXXX", Locale.ENGLISH);
        String formatted = dtfOutput.format(zdtAmericaAdak);
        System.out.println(formatted); // 2018-03-12 18:00:00.000-09:00
    }
}   

modern date-time API 中详细了解 java.timeTrail: Date Time*


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project