ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Etc/GMT+1"));
value of this when debugging shows 2019-07-02T14:23:57.463-01:00[Etc/GMT+1]
it should be 16:23, what am i missing .. the clock is 2 hours slow for some reason?
tl;dr
Use a time zone rather than a mere offset.
ZonedDateTime.now(
ZoneId.of( "Europe/Dublin" )
)
Details
In modern protocols, the number of hours-minutes-seconds in an offset are considered as positive numbers being ahead of the baseline (GMT/UTC), and negative numbers as being behind the baseline. Some older protocols are the reverse. Your Etc/GMT+1
seems to be of the reverse style.
The best solution is to use time zones rather than a mere offset. An offset is simply a number of hours-minutes-seconds. A time zone is much more. A time zone is a history of past, present, and future changes to the offset used by the people of a particular region.
A time zone has a name in the format of Continent/Region
. For example, America/Montreal
, Europe/Paris
, and Pacific/Auckland
.
ZoneId z = ZoneId.of( "Europe/Dublin" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
Generate a string in standard ISO 8601 format extended wisely to append the name of the zone in square brackets.
String output = zdt.toString() ;
Most of your business logic, logging, and data change should be in UTC. To adjust into UTC, extract an Instant
from your ZonedDateTime
. Same moment, same point on the timeline, but a different wall-clock time.
Instant instant = zdt.toInstant() ;
Generate a string in standard ISO 8601 format.
String output = instant.toString() ;
Your example
So now we can go back to examine your particular situation.
Let's parse your given string with [Etc/GMT+1]
as the zone name.
String input = "2019-07-02T14:23:57.463-01:00[Etc/GMT+1]" ;
ZonedDateTime zdtInput = ZonedDateTime.parse ( input );
Then adjust to UTC.
Instant instant = zdtInput.toInstant ();
Adjust again into Europe/Dublin
.
ZoneId zDublin = ZoneId.of( "Europe/Dublin");
ZonedDateTime zdtDublin = zdtInput.withZoneSameInstant ( zDublin );
Dump to console.
System.out.println ("zdtInput: " + zdtInput );
System.out.println ("instant: " + instant );
System.out.println ("zdtDublin: " + zdtDublin );
See this code run live at IdeOne.com.
zdtInput: 2019-07-02T14:23:57.463-01:00[Etc/GMT+1]
instant: 2019-07-02T15:23:57.463Z
zdtDublin: 2019-07-02T16:23:57.463+01:00[Europe/Dublin]
Hour 14
Sure enough, we see the day-of-time with [Etc/GMT+1]
being an hour behind UTC (the old reversed meaning of the hours offset) with an hour of 14
.
Hour 15
UTC (an offset of zero hours-minutes-seconds) has an hour of 15
.
Hour 16
The Dublin time zone is using Irish Standard Time (IST), UTC +1 rather than Daylight Saving Time (DST) at that moment. So we see its hour at 16
, an hour ahead of UTC’s 15
hour.
Crucial: Understand that all three of these represent the same moment, the very same single point on the timeline. Their wall-clock time differs: three ways to view the same moment in time.
By the way, when you want to work with offsets specifically instead of time zones, use the OffsetDateTime
& ZoneOffset
classes. The ZonedDateTime
& ZoneId
classes are for time zones.