Skip to content

Commit

Permalink
8272473: Parsing epoch seconds at a DST transition with a non-UTC par…
Browse files Browse the repository at this point in the history
…ser is wrong

Backport-of: fe7d70886cc9985478c5810eff0790648a9aae41
  • Loading branch information
ChrisHegarty committed Sep 9, 2021
1 parent ea6e678 commit 0ced2aa
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 6 deletions.
9 changes: 5 additions & 4 deletions src/java.base/share/classes/java/time/format/Parsed.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -354,10 +354,11 @@ private void resolveInstantFields() {
}

private void resolveInstantFields0(ZoneId selectedZone) {
Instant instant = Instant.ofEpochSecond(fieldValues.remove(INSTANT_SECONDS));
Instant instant = Instant.ofEpochSecond(fieldValues.get(INSTANT_SECONDS));
ChronoZonedDateTime<?> zdt = chrono.zonedDateTime(instant, selectedZone);
updateCheckConflict(zdt.toLocalDate());
updateCheckConflict(INSTANT_SECONDS, SECOND_OF_DAY, (long) zdt.toLocalTime().toSecondOfDay());
updateCheckConflict(INSTANT_SECONDS, OFFSET_SECONDS, (long) zdt.getOffset().getTotalSeconds());
}

//-----------------------------------------------------------------------
Expand Down Expand Up @@ -641,9 +642,9 @@ private void resolveFractional() {
}

private void resolveInstant() {
// add instant seconds if we have date, time and zone
// add instant seconds (if not present) if we have date, time and zone
// Offset (if present) will be given priority over the zone.
if (date != null && time != null) {
if (!fieldValues.containsKey(INSTANT_SECONDS) && date != null && time != null) {
Long offsetSecs = fieldValues.get(OFFSET_SECONDS);
if (offsetSecs != null) {
ZoneOffset offset = ZoneOffset.ofTotalSeconds(offsetSecs.intValue());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -88,11 +88,12 @@
/**
* @test
* @summary Test parsing of edge cases.
* @bug 8223773
* @bug 8223773 8272473
*/
public class TestDateTimeParsing {

private static final ZoneId PARIS = ZoneId.of("Europe/Paris");
private static final ZoneId NEW_YORK = ZoneId.of("America/New_York");
private static final ZoneOffset OFFSET_0230 = ZoneOffset.ofHoursMinutes(2, 30);

private static final DateTimeFormatter LOCALFIELDS = new DateTimeFormatterBuilder()
Expand All @@ -107,6 +108,7 @@ public class TestDateTimeParsing {
.appendInstant().toFormatter();
private static final DateTimeFormatter INSTANT_WITH_PARIS = INSTANT.withZone(PARIS);
private static final DateTimeFormatter INSTANT_WITH_0230 = INSTANT.withZone(OFFSET_0230);
private static final DateTimeFormatter INSTANT_WITH_NEW_YORK = INSTANT.withZone(NEW_YORK);
private static final DateTimeFormatter INSTANT_OFFSETID = new DateTimeFormatterBuilder()
.appendInstant().appendLiteral(' ').appendOffsetId().toFormatter();
private static final DateTimeFormatter INSTANT_OFFSETSECONDS = new DateTimeFormatterBuilder()
Expand All @@ -119,6 +121,7 @@ public class TestDateTimeParsing {
private static final DateTimeFormatter INSTANTSECONDS_NOS_WITH_PARIS = INSTANTSECONDS_NOS.withZone(PARIS);
private static final DateTimeFormatter INSTANTSECONDS_OFFSETSECONDS = new DateTimeFormatterBuilder()
.appendValue(INSTANT_SECONDS).appendLiteral(' ').appendValue(OFFSET_SECONDS).toFormatter();
private static final DateTimeFormatter INSTANTSECONDS_WITH_NEW_YORK = INSTANTSECONDS.withZone(NEW_YORK);

private static final String DTPE_MESSAGE =
"Invalid value for HourOfAmPm (valid values 0 - 11): 12";
Expand All @@ -133,11 +136,15 @@ Object[][] data_instantZones() {
{LOCALFIELDS_WITH_0230, "2014-06-30 01:02:03", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, OFFSET_0230)},
{INSTANT_WITH_PARIS, "2014-06-30T01:02:03Z", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, ZoneOffset.UTC).withZoneSameInstant(PARIS)},
{INSTANT_WITH_0230, "2014-06-30T01:02:03Z", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, ZoneOffset.UTC).withZoneSameInstant(OFFSET_0230)},
{INSTANT_WITH_NEW_YORK, "2020-11-01T05:00:00Z", ZonedDateTime.of(2020, 11, 1, 5, 0, 0, 0, ZoneOffset.UTC).withZoneSameInstant(NEW_YORK)},
{INSTANT_WITH_NEW_YORK, "2020-11-01T06:00:00Z", ZonedDateTime.of(2020, 11, 1, 6, 0, 0, 0, ZoneOffset.UTC).withZoneSameInstant(NEW_YORK)},
{INSTANT_OFFSETID, "2014-06-30T01:02:03Z +02:30", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, ZoneOffset.UTC).withZoneSameInstant(OFFSET_0230)},
{INSTANT_OFFSETSECONDS, "2014-06-30T01:02:03Z 9000", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, ZoneOffset.UTC).withZoneSameInstant(OFFSET_0230)},
{INSTANTSECONDS_WITH_PARIS, "86402", Instant.ofEpochSecond(86402).atZone(PARIS)},
{INSTANTSECONDS_NOS_WITH_PARIS, "86402.123456789", Instant.ofEpochSecond(86402, 123456789).atZone(PARIS)},
{INSTANTSECONDS_OFFSETSECONDS, "86402 9000", Instant.ofEpochSecond(86402).atZone(OFFSET_0230)},
{INSTANTSECONDS_WITH_NEW_YORK, "1604206800", Instant.ofEpochSecond(1604206800).atZone(NEW_YORK)}, // 2020-11-01T05:00:00 UTC
{INSTANTSECONDS_WITH_NEW_YORK, "1604210400", Instant.ofEpochSecond(1604210400).atZone(NEW_YORK)}, // 2020-11-01T06:00:00 UTC
};
}

Expand Down

1 comment on commit 0ced2aa

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.