Skip to content

Fix Rfc3339DateJsonAdapter to use UTC for date-only strings#2124

Open
amitmishra11 wants to merge 1 commit into
square:masterfrom
amitmishra11:fix/rfc3339-date-utc-when-no-timezone
Open

Fix Rfc3339DateJsonAdapter to use UTC for date-only strings#2124
amitmishra11 wants to merge 1 commit into
square:masterfrom
amitmishra11:fix/rfc3339-date-utc-when-no-timezone

Conversation

@amitmishra11

Copy link
Copy Markdown

Fixes #2046

Bug

Rfc3339DateJsonAdapter uses the host machine's default time zone when
parsing a date string that has no time or timezone component (e.g.
"2025-11-20"). The parsing code in Iso8601Utils.kt contained a
comment that directly acknowledged this:

// Note that this uses the host machine's time zone. That's a bug.
return GregorianCalendar(year, month - 1, day).time

This means two machines in different time zones would produce different
Date values from the same JSON input, which is surprising and
inconsistent with how dates that carry an explicit Z suffix are
handled.

Fix

Replace the default-timezone GregorianCalendar constructor call with
an explicit UTC calendar, matching the pattern already used for the
full datetime path. The fix mirrors what the existing code does when a
timezone is present.

Before:

return GregorianCalendar(year, month - 1, day).time

After:

val calendar: Calendar = GregorianCalendar(TIMEZONE_Z, Locale.US)
calendar.isLenient = false
calendar[Calendar.YEAR] = year
calendar[Calendar.MONTH] = month - 1
calendar[Calendar.DAY_OF_MONTH] = day
calendar[Calendar.HOUR_OF_DAY] = 0
calendar[Calendar.MINUTE] = 0
calendar[Calendar.SECOND] = 0
calendar[Calendar.MILLISECOND] = 0
return calendar.time

Test changes

  • The absentTimeZone test now asserts that "1970-01-01" produces
    the same Date as "1970-01-01Z" (midnight UTC).
  • A second assertion covers the example from the issue: "2025-11-20".
  • The newDateWithHostZone helper, which existed only to document the
    old (incorrect) behaviour, is removed.

Verification

./gradlew :moshi-adapters:test
BUILD SUCCESSFUL

When parsing a date string with no time or timezone component (e.g.
"2025-11-20"), the adapter was using the host machine's time zone via
the default GregorianCalendar constructor. The code even contained a
comment acknowledging this as a bug.

This change parses date-only strings in UTC, consistent with how
dates that carry an explicit "Z" suffix are handled. The test for
this case is updated to assert UTC behaviour, and the now-unused
newDateWithHostZone helper is removed.

Fixes square#2046

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rfc3339DateJsonAdapter puts the wrong zone on dates like "2025-11-20"

1 participant