在Java中将ZoneId应用于Date对象

时间:2017-11-30 09:28:17

标签: java datetime java-time timezone-offset

我有以下日期对象Wed Nov 01 00:00:00 GMT 2017。这显然是在格林尼治标准时间,但是,我想将其视为在不同的时区。

例如,我想在以下时区US/Mountain中考虑上述日期,然后我想将其转换为UTC,从而产生Wed Nov 01 07:00:00 UTC。< / p>

我试图找到一种方法来改变日期的时区,同时保留时间,但失败了。

由于

2 个答案:

答案 0 :(得分:1)

使用java time API,您可以:

  1. 将字符串解析为ZonedDateTime
  2. 使用zonedDateTime.withZoneSameLocalzonedDateTime.withZoneSameInstant转换结果
  3. 这样的事情:

    DateTimeFormatter fmt = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu");
    
    ZonedDateTime gmt = ZonedDateTime.parse("Wed Nov 01 00:00:00 GMT 2017", fmt);
    ZonedDateTime mountain = gmt.withZoneSameLocal(ZoneId.of("US/Mountain"));
    ZonedDateTime utc = mountain.withZoneSameInstant(ZoneOffset.UTC);
    
    System.out.println(utc.format(fmt));
    
    顺便提一下,

    输出:Wed Nov 01 06:00:00 Z 2017(DST将于11月3日生效)。

答案 1 :(得分:1)

我从您那里了解到您有java.util.Date个实例。它打印为(例如)Wed Nov 01 00:00:00 GMT 2017。这是它的toString方法产生的。 Date中没有时区。通常Date.toString()抓取JVM的时区设置并在此时区中呈现日期。所以看来你正在运行GMT时区?您可以在this popular blog entry: All about java.util.Date中阅读更多内容。

如果可以,请避免使用DateThe modern Java date and time API known as java.time or JSR-310使用起来非常好,无论是一般情况还是非时间情况都与你的一样。然后使用assylias’ answer

对于这个答案,我假设您从某些遗留API获得了Date,您无法更改(或者现在无法承担更改)。我仍然推荐现代API,以满足您的需求。以下代码片段的输出我在代码中作为注释提供。

    System.out.println(oldFashionedDateObject); // Wed Nov 01 00:00:00 GMT 2017
    // first thing, convert the Date to an instance of a modern class, Instant
    Instant pointInTime = oldFashionedDateObject.toInstant();
    // convert to same hour and minute in US/Mountain and then back into UTC
    ZonedDateTime convertedDateTime = pointInTime.atOffset(ZoneOffset.UTC)
            .atZoneSimilarLocal(ZoneId.of("US/Mountain"))
            .withZoneSameInstant(ZoneOffset.UTC);
    System.out.println(convertedDateTime); // 2017-11-01T06:00Z

    // only assuming you absolutely and indispensably need an old-fashioned Date object back
    oldFashionedDateObject = Date.from(convertedDateTime.toInstant());
    System.out.println(oldFashionedDateObject); // Wed Nov 01 06:00:00 GMT 2017

作为assylias,我得到Wed Nov 01 06:00:00。根据{{​​3}}夏令时(DST)于今年11月5日结束。