Skip to content

fix: timezone inconsistency in date type parsing #1084

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 0 commits into from

Conversation

simplenotezy
Copy link

Problem

The date type handler has inconsistent timezone handling between serialization and parsing, causing incorrect date values when the system timezone differs from UTC.

Root Cause:

  • Serialization: toISOString() always outputs UTC format
  • Parsing: new Date(x) interprets strings without timezone info as local time

This asymmetry creates a double timezone conversion bug affecting PostgreSQL operations like AT TIME ZONE, DATE_TRUNC(), and any timestamp operations in non-UTC system timezones.

Example Bug:

// System timezone: Europe/Copenhagen (UTC+2)
// Database timezone: UTC

const result = await sql`
  SELECT '2025-04-01 00:00:00'::timestamp AT TIME ZONE 'UTC' as timestamp_utc
`

// Expected: 2025-04-01T00:00:00.000Z
// Actual:   2025-03-31T22:00:00.000Z  (2-hour shift)

Solution

Modified the parse function in the date type handler to treat strings without timezone information as UTC, matching the serialization behavior:

parse: x => {
  if (typeof x === 'number') {
    return new Date(x)
  }
  // Fix timezone bug: ensure strings without timezone info are treated as UTC
  // to match serialization behavior (toISOString() always outputs UTC)
  if (
    typeof x === 'string' &&
    !x.includes('Z') &&
    !x.includes('+') &&
    !x.includes('-', 10)  // Avoid matching date part
  ) {
    // PostgreSQL format: "2025-04-01 00:00:00" -> ISO format: "2025-04-01T00:00:00Z"
    return new Date(x.replace(' ', 'T') + 'Z')
  }
  return new Date(x)
}

This ensures:

  • timestamp columns are parsed as UTC to match serialization
  • timestamptz columns with timezone info remain unchanged
  • Round-trip consistency across different system timezones
  • Backward compatibility for properly formatted timestamps

Testing

Added comprehensive test cases covering:

  • Round-trip serialization/parsing consistency
  • PostgreSQL timestamp format parsing
  • AT TIME ZONE operation correctness

Related Issues

Fixes:

Impact: Resolves timezone inconsistencies for applications running in non-UTC timezones and ensures consistent behavior across different system locales.

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.

1 participant