From 1851780565b19d08d7b47cc1111afc473993c02e Mon Sep 17 00:00:00 2001 From: Mehul Jariwala Date: Sat, 5 Sep 2026 17:36:17 +0530 Subject: [PATCH 1/2] Fix parse position for hour-only timezone offsets --- .../gson/internal/bind/util/ISO8601Utils.java | 2 +- .../internal/bind/util/ISO8601UtilsTest.java | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/gson/src/main/java/com/google/gson/internal/bind/util/ISO8601Utils.java b/gson/src/main/java/com/google/gson/internal/bind/util/ISO8601Utils.java index 606d6c7146..2bf1aa84a1 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/util/ISO8601Utils.java +++ b/gson/src/main/java/com/google/gson/internal/bind/util/ISO8601Utils.java @@ -239,12 +239,12 @@ public static Date parse(String date, ParsePosition pos) throws ParseException { offset += 1; } else if (timezoneIndicator == '+' || timezoneIndicator == '-') { String timezoneOffset = date.substring(offset); + offset += timezoneOffset.length(); // When timezone has no minutes, we should append it, valid timezones are, for example: // +00:00, +0000 and +00 timezoneOffset = timezoneOffset.length() >= 5 ? timezoneOffset : timezoneOffset + "00"; - offset += timezoneOffset.length(); // 18-Jun-2015, tatu: Minor simplification, skip offset of "+0000"/"+00:00" if (timezoneOffset.equals("+0000") || timezoneOffset.equals("+00:00")) { timezone = TIMEZONE_UTC; diff --git a/gson/src/test/java/com/google/gson/internal/bind/util/ISO8601UtilsTest.java b/gson/src/test/java/com/google/gson/internal/bind/util/ISO8601UtilsTest.java index 1c2d254dec..c24333382a 100644 --- a/gson/src/test/java/com/google/gson/internal/bind/util/ISO8601UtilsTest.java +++ b/gson/src/test/java/com/google/gson/internal/bind/util/ISO8601UtilsTest.java @@ -107,6 +107,29 @@ public void testDateParseWithTimezone() throws ParseException { assertThat(date).isEqualTo(expectedDate); } + @Test + public void testDateParseShortTimezonePosition() throws ParseException { + for (String timezone : new String[] {"+00", "+01", "-02", "+01:30", "+0130"}) { + String dateStr = "2018-06-25T00:00:00" + timezone; + ParsePosition position = new ParsePosition(0); + Date date = ISO8601Utils.parse(dateStr, position); + assertThat(position.getIndex()).isEqualTo(dateStr.length()); + + String fullTimezone = timezone.length() == 3 ? timezone + ":00" : timezone; + Date expected = + ISO8601Utils.parse("2018-06-25T00:00:00" + fullTimezone, new ParsePosition(0)); + assertThat(date.getTime()).isEqualTo(expected.getTime()); + } + } + + @Test + public void testDateParseShortTimezoneFromNonzeroPosition() throws ParseException { + String dateStr = "prefix 2018-06-25T00:00:00+01"; + ParsePosition position = new ParsePosition("prefix ".length()); + ISO8601Utils.parse(dateStr, position); + assertThat(position.getIndex()).isEqualTo(dateStr.length()); + } + @Test @SuppressWarnings("UndefinedEquals") public void testDateParseSpecialTimezone() throws ParseException { From e51a6cbd99ff9fe1cb2af845d16126dfe87d3aad Mon Sep 17 00:00:00 2001 From: Mehul Jariwala Date: Sat, 5 Sep 2026 18:23:30 +0530 Subject: [PATCH 2/2] Scope the legacy Date lint suppression to the timezone test --- .../com/google/gson/internal/bind/util/ISO8601UtilsTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/gson/src/test/java/com/google/gson/internal/bind/util/ISO8601UtilsTest.java b/gson/src/test/java/com/google/gson/internal/bind/util/ISO8601UtilsTest.java index c24333382a..f2d11b5ef0 100644 --- a/gson/src/test/java/com/google/gson/internal/bind/util/ISO8601UtilsTest.java +++ b/gson/src/test/java/com/google/gson/internal/bind/util/ISO8601UtilsTest.java @@ -108,6 +108,7 @@ public void testDateParseWithTimezone() throws ParseException { } @Test + @SuppressWarnings("JavaUtilDate") public void testDateParseShortTimezonePosition() throws ParseException { for (String timezone : new String[] {"+00", "+01", "-02", "+01:30", "+0130"}) { String dateStr = "2018-06-25T00:00:00" + timezone;