Skip to content

fix(bigquery-jdbc): preserve pre-1582 and pre-standard-time DATE/DATETIME digits - #14787

Open
keshavdandeva wants to merge 1 commit into
mainfrom
jdbc/pre-julian-calendar-temporal-fix
Open

keshavdandeva wants to merge 1 commit into
mainfrom
jdbc/pre-julian-calendar-temporal-fix

Conversation

@keshavdandeva

Copy link
Copy Markdown
Contributor

b/570669354

Summary

Historic DATE/DATETIME values were read back with shifted digits, and some TIMESTAMP local views were shifted the same way:

  • DATE '0001-01-01' → 0001-01-03 (all JVM zones)
  • DATE '1850-06-01' → 1850-05-31 (e.g. JVM in America/Los_Angeles or Asia/Kolkata)
  • getObject(ts, LocalDateTime.class) on TIMESTAMP '0001-01-01 UTC' → 0001-01-03T00:00

Root cause

Civil values were converted to java.sql objects with java.time rules (proleptic calendar, local mean time) but read back with java.sql rules (Julian calendar before 1582, standard zone offsets). The two disagree for old dates.

Fix

  • DATE/DATETIME → java.sql.Date/Timestamp now uses java.sql's own calendar: Date.valueOf/Timestamp.valueOf, or GregorianCalendar fields when a Calendar is given.
  • getString and java.time getters on DATE/DATETIME convert from the raw value, as TIME already did.
  • TIMESTAMP local views (LocalDateTime/LocalDate/LocalTime/getDate/getTime) are derived from the instant using java.time.

TIMESTAMP instant semantics are unchanged, and modern dates behave as before.

Known limitations

java.sql.Date/Timestamp cannot represent year 0 or 1582-10-05..14. getString and the java.time getters return the correct value for these.

Tests

  • BigQueryTemporalUtilityTest, BigQueryTypeRegistryTest: historic values across JVM zones.
  • ITTimestampTimeZoneTest: year 1, 1582 gap day and 1850 values for DATE/DATETIME/TIMESTAMP, with and without Calendar, in 4 JVM zones.

@keshavdandeva
keshavdandeva requested review from a team as code owners October 27, 2026 13:14

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request improves the handling of historic temporal values (pre-1582 dates and pre-standard-time digits) in the BigQuery JDBC driver by bypassing standard java.sql limitations and using java.time types directly. It introduces GregorianCalendar-based boxing and unboxing utility methods to preserve digits accurately across timezones. The review feedback highlights critical issues where the timezone parameter is ignored during Timestamp conversions in the modern fast-paths of BigQueryTypeRegistry, and points out a bug in handling BC years when boxing LocalDateTime into a Timestamp.

This branch has not been deployed

No deployments
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