to summarize my question, I have 2 different ZonedDateTime objects with GMT and BST but same local time. They become the same Instant values after toInstant conversion. I am expecting after conversion, they should be different values because although they are both 'Tue Feb 23 18:00:46 2021', the strings are representing time for different time zones. I am not sure whether this is a bug of library itself or I am doing something wrong.
I have 2 different ZonedDateTime generated from this piece of Scala code:
import ...
import java.util.{Set => JavaSet}
val string2 = "Tue Feb 23 18:00:46 BST 2021"
val string1 = "Tue Feb 23 18:00:46 GMT 2021"
val timestampFormat: DateTimeFormatter = new DateTimeFormatterBuilder()
.appendOptional(DateTimeFormatter.ISO_DATE_TIME)
.appendOptional(DateTimeFormatter.ISO_INSTANT)
.appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
.appendOptional(DateTimeFormatter.ISO_ZONED_DATE_TIME)
.appendOptional(DateTimeFormatter.RFC_1123_DATE_TIME)
.appendPattern("EEE MMM ppd HH:mm:ss ")
.appendZoneText(TextStyle.SHORT, JavaSet.of(ZoneId.of("Europe/London")))
.appendPattern(" yyyy")
.toFormatter(Locale.US)
val parsedZdt2: ZonedDateTime = ZonedDateTime.parse(string2, timestampFormat)
val parsedZdt1: ZonedDateTime = ZonedDateTime.parse(string1, timestampFormat)
println(parsedZdt1 == parsedZdt2)
println("parsedZdt1.toString: " + parsedZdt1.toString)
println("parsedZdt2.toString: " + parsedZdt2.toString)
This prints out:
false
parsedZdt1.toString: 2021-02-23T18:00:46Z[GMT]
parsedZdt2.toString: 2021-02-23T18:00:46Z[Europe/London]
However when I convert them to instant:
println(parsedZdt1.toInstant == parsedZdt2.toInstant)
println("parsedZdt1.toInstant.toString: " + parsedZdt1.toInstant.toString)
println("parsedZdt2.toInstant.toString: " + parsedZdt2.toInstant.toString)
I got this printed out:
true
parsedZdt1.toInstant.toString: 2021-02-23T18:00:46Z
parsedZdt2.toInstant.toString: 2021-02-23T18:00:46Z
My questions are
Thank you!
You said:
the strings are representing time for different time zones
Different time zones, yes, but the time zones happen to share the same offset on that particular date. Many time zones share the same offset, coincidentally, on particular dates.
London time is GMT/UTC time, sometimes, when not observing Daylight Saving Time (DST).
If by BST
, you mean the time zone Europe/London
, that zone had an offset of zero hours from UTC/GMT on that date of 2021-02-23.
👉 So 6 PM on February 23rd in London time was also 6 PM in GMT.
Later in the year, from March 28, 2021 to October 31, 2021, the UK observes DST. During those months their offset is one hour ahead of UTC.
See Time Change 2021 in England, United Kingdom on TimeAndDate.com.
Let’s compare two moments using Instant#equals
.
LocalDate ld = LocalDate.of( 2021 , Month.FEBRUARY , 23 ) ;
LocalTime lt = LocalTime.of( 18 , 0 , 0 ) ;
boolean sameMoment =
ZonedDateTime.of( ld , lt , ZoneId.of( "Europe/London" ) ).toInstant()
.equals(
OffsetDateTime.of( ld , lt , ZoneOffset.UTC ).toInstant()
) ;
See this code run live at Ideone.com.
true
Change the month to June, during Daylight Saving Time observance.
LocalDate ld = LocalDate.of( 2021 , Month.JUNE , 23 ) ;
LocalTime lt = LocalTime.of( 18 , 0 , 0 ) ;
boolean sameMoment =
ZonedDateTime.of( ld , lt , ZoneId.of( "Europe/London" ) ).toInstant()
.equals(
OffsetDateTime.of( ld , lt , ZoneOffset.UTC ).toInstant()
) ;
false
ZoneOffset
Also, you can directly interrogate for the offset of a moment, in both ZonedDateTime
and OffsetDateTime
objects. Call getOffset
to get a ZoneOffset
object.
LocalDate ld = LocalDate.of( 2021 , Month.FEBRUARY , 23 );
LocalTime lt = LocalTime.of( 18 , 0 , 0 );
ZonedDateTime zdtLondon = ZonedDateTime.of( ld , lt , ZoneId.of( "Europe/London" ) );
OffsetDateTime odtUtc = OffsetDateTime.of( ld , lt , ZoneOffset.UTC );
ZoneOffset offsetLondon = zdtLondon.getOffset();
ZoneOffset offsetUtc = odtUtc.getOffset();
System.out.println( zdtLondon + " has an offset of: " + offsetLondon );
System.out.println( odtUtc + " has an offset of: " + offsetUtc );
We see both have an offset of zero hours-minutes-seconds from UTC, indicated by a Z
, pronounced “Zulu”.
2021-02-23T18:00Z[Europe/London] has an offset of: Z
2021-02-23T18:00Z has an offset of: Z
Change the month to June, and we get different offsets. London time shows an hour ahead of UTC.
2021-06-23T18:00+01:00[Europe/London] has an offset of: +01:00
2021-06-23T18:00Z has an offset of: Z