From 73525d4a2dfe3f545b53dbac70b7bf6a9d9f4c30 Mon Sep 17 00:00:00 2001 From: Ken Partlow Date: Sun, 28 Jan 2024 19:35:27 -0500 Subject: [PATCH] Fixed Strings without local time --- .../com/cedarsoftware/util/DateUtilities.java | 12 +++++--- .../util/convert/StringConversions.java | 2 +- .../util/convert/ConverterTest.java | 30 +++++++++++++++++-- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/cedarsoftware/util/DateUtilities.java b/src/main/java/com/cedarsoftware/util/DateUtilities.java index 08f6bdb1..1a5ee10a 100644 --- a/src/main/java/com/cedarsoftware/util/DateUtilities.java +++ b/src/main/java/com/cedarsoftware/util/DateUtilities.java @@ -193,7 +193,7 @@ public static TemporalAccessor parseDate(String dateStr, ZoneId defaultZoneId, b dateStr = dateStr.trim(); if (allDigits.matcher(dateStr).matches()) { - return Instant.ofEpochMilli(Long.parseLong(dateStr)).atZone(ZoneId.of("UTC")); + return Instant.ofEpochMilli(Long.parseLong(dateStr)).atZone(defaultZoneId); } String year, day, remains, tz = null; @@ -274,7 +274,7 @@ public static TemporalAccessor parseDate(String dateStr, ZoneId defaultZoneId, b verifyNoGarbageLeft(remnant); } - ZoneId zoneId = StringUtilities.isEmpty(tz) ? null : getTimeZone(tz); + ZoneId zoneId = StringUtilities.isEmpty(tz) ? defaultZoneId : getTimeZone(tz); TemporalAccessor dateTime = getDate(dateStr, zoneId, year, month, day, hour, min, sec, fracSec); return dateTime; } @@ -299,8 +299,12 @@ private static TemporalAccessor getDate(String dateStr, throw new IllegalArgumentException("Day must be between 1 and 31 inclusive, date: " + dateStr); } - if (hour == null) { // no [valid] time portion - return LocalDateTime.of(y, month, d, 0, 0, 0); + if (hour == null) { // no [valid] time portion + if (zoneId == null) { + return LocalDateTime.of(y, month, d, 0, 0, 0); + } else { + return ZonedDateTime.of(y, month, d, 0, 0, 0, 0, zoneId); + } } else { // Regex prevents these from ever failing to parse. int h = Integer.parseInt(hour); diff --git a/src/main/java/com/cedarsoftware/util/convert/StringConversions.java b/src/main/java/com/cedarsoftware/util/convert/StringConversions.java index 81abaa0c..b035c7d6 100644 --- a/src/main/java/com/cedarsoftware/util/convert/StringConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/StringConversions.java @@ -367,7 +367,7 @@ private static Instant getInstant(String from, ConverterOptions options) { Instant instant; if (dateTime instanceof LocalDateTime) { LocalDateTime localDateTime = LocalDateTime.from(dateTime); - instant = localDateTime.atZone(options.getZoneId()).toInstant(); + instant = localDateTime.atZone(options.getSourceZoneIdForLocalDates()).toInstant(); } else { instant = Instant.from(dateTime); } diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java index 7d669ddb..cd849859 100644 --- a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java +++ b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java @@ -692,6 +692,18 @@ void testToBoolean_falseCases(Object input) { } + private static Stream dateStringNoZoneOffset() { + return Stream.of( + Arguments.of("2000-01-01T13:59:59", TOKYO), + Arguments.of("2000-01-01T05:59:59", PARIS), + Arguments.of("2000-01-01T04:59:59", GMT), + Arguments.of("1999-12-31T23:59:59", NEW_YORK), + Arguments.of("1999-12-31T22:59:59", CHICAGO), + Arguments.of("1999-12-31T20:59:59", LOS_ANGELES) + ); + } + + private static Stream dateStringInIsoOffsetDateTime() { return Stream.of( Arguments.of("2000-01-01T13:59:59+09:00"), @@ -726,6 +738,22 @@ private static Stream dateStringInIsoZoneDateTime() { } + @ParameterizedTest + @MethodSource("dateStringNoZoneOffset") + void testStringDateWithNoTimeZoneInformation(String date, ZoneId zoneId) { + // source is TOKYO, bu should be ignored when zone is provided on string. + LocalDateTime localDateTime = this.converter.convert(date, LocalDateTime.class, createCustomZones(zoneId, NEW_YORK)); + + assertThat(localDateTime) + .hasYear(1999) + .hasMonthValue(12) + .hasDayOfMonth(31) + .hasHour(23) + .hasMinute(59) + .hasSecond(59); + } + + @ParameterizedTest @MethodSource("dateStringInIsoOffsetDateTime") void testStringDateWithTimeZoneToLocalDateTime(String date) { @@ -800,8 +828,6 @@ void testCalendarToLocalDateTime(long epochMilli, ZoneId zoneId, LocalDateTime e Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(epochMilli); - System.out.println(Instant.ofEpochMilli(epochMilli).atZone(zoneId).toString()); - LocalDateTime localDateTime = this.converter.convert(calendar, LocalDateTime.class, createCustomZones(zoneId, zoneId)); assertThat(localDateTime).isEqualTo(expected);