Adrian Daniel Culea
Adrian Daniel Culea

Reputation: 181

Apply ZoneId to Date object in Java

I have the following date object Wed Nov 01 00:00:00 GMT 2017. This obviously is in GMT, however, I'd like to consider it to be in a different timezone.

As an example, I'd like to consider the above date in the following timezone US/Mountain and I'd like to then convert it to UTC, resulting in Wed Nov 01 07:00:00 UTC.

I've tried to find a way to change the timezone of a date, while preserving the time, but failed.

Thanks

Upvotes: 1

Views: 6039

Answers (2)

Anonymous
Anonymous

Reputation: 86280

I understand from you comment that you have got a java.util.Date instance. It prints as (for example) Wed Nov 01 00:00:00 GMT 2017. This is what its toString method produces. The Date doesn’t have a time zone in it. Usually Date.toString() grabs the JVM’s time zone setting and renders the date in this time zone. So it appears you are running GMT time zone? You can read more in this popular blog entry: All about java.util.Date.

If you can, avoid having a Date. The modern Java date and time API known as java.time or JSR-310 is so much nicer to work with, both in general and not least for time zone magic like yours. Then use assylias’ answer.

For this answer I am assuming that you got a Date from some legacy API that you cannot change (or cannot afford to change just now). I still recommend the modern API for the change you desire. The output from the following snippet I give as comments in the code.

    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

As assylias, I got Wed Nov 01 06:00:00. According to Current Local Time in Denver, Colorado, USA summer time (DST) ended on November 5 this year.

Upvotes: 2

assylias
assylias

Reputation: 328608

With the java time API, you can:

  1. Parse the string as a ZonedDateTime
  2. Use the zonedDateTime.withZoneSameLocal and zonedDateTime.withZoneSameInstant to convert the result

Something like this:

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));

which, by the way, outputs: Wed Nov 01 06:00:00 Z 2017 (the DST will be in effect on November 3rd only).

Upvotes: 1

Related Questions