如何在不改变时间的情况下改变时区?

时间:2018-02-13 21:58:19

标签: java date datetime simpledateformat

我的时间戳为2018-01-01 18:20:23.11,采用UTC格式。我需要以不同的格式打印它,但保留UTC时区。但是,如果我使用SimpleDateFormat(" dd MMM YYYY yyyy kk:mm z"),它需要我当前的时区并给我01 2018年1月18日18:20美国东部时间。我想要打印01 Jan 2018 18:20 UTC。执行Timezone.getTimeZone(" UTC")将此时间转换为UTC(执行+4到小时),这不是所需的结果。

1 个答案:

答案 0 :(得分:3)

    DateTimeFormatter originalFormatter
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SS");
    DateTimeFormatter newFormatter
            = DateTimeFormatter.ofPattern("dd MMM uuuu HH:mm z", Locale.ENGLISH);
    String originalTimestamp = "2018-01-01 18:20:23.11";
    String differentFormat = LocalDateTime.parse(originalTimestamp, originalFormatter)
            .atZone(ZoneId.of("Etc/UTC"))
            .format(newFormatter);
    System.out.println(differentFormat);

打印

01 Jan 2018 18:20 UTC

ZoneId.of("Etc/UTC")ZoneOffset.UTC

可能是书呆子编辑:我首先在转换中写了.atZone(ZoneOffset.UTC)。我通常使用ZoneOffset.UTC来表示UTC,并认为这是指定它的好的和惯用的方式。但是,对于您的代码,这会导致在您要求Z的输出中将区域设为UTC。使用ZoneId.of("Etc/UTC")代替您提供您想要的内容。我找不到其他方法来确保区域格式为UTC(在格式模式字符串中保存硬编码UTC,但那将是一个丑陋的黑客攻击。)

BTW ZoneId.of("Etc/UTC").normalized()返回ZoneOffset.UTC(至少在我的Java 10上,但我希望它总是如此)。

SimpleDateFormat与java.time

SimpleDateFormat不仅已经过时了,而且也是出了名的麻烦。我建议你避免它。正如您所观察到的,它是正确的,它使用您的JVM的默认时区。有一种方法可以说服它做不同的事情,但我不会打扰。

java.time是现代Java日期和时间API。它于2014年问世,取代了旧的和设计不佳的日期和时间类。恕我直言,它的使用效果非常好。

链接: Oracle tutorial: Date Time解释如何使用java.time