Skip to content

docs(sql): add a Dates and time zones section for timestamp UTC decoding - #39881

Open
robobun wants to merge 4 commits into
mainfrom
farm/3a50f029/docs-pg-timestamp-utc
Open

docs(sql): add a Dates and time zones section for timestamp UTC decoding#39881
robobun wants to merge 4 commits into
mainfrom
farm/3a50f029/docs-pg-timestamp-utc

Conversation

@robobun

@robobun robobun commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Fixes #39879.

Problem

  • Bun.SQL decodes a PostgreSQL timestamp (without time zone, OID 1114) as UTC (src/sql_jsc/postgres/types/date.rs:39). node-postgres, postgres.js, and PGlite decode it as local time, so a migration shifts values on a non-UTC host.
  • The docs state this only in a trailing clause of the MySQL type note (docs/runtime/sql.mdx:1370).

Fix

Background

Notes

Results on bun 1.4.0 with TZ=Etc/GMT+7 (same results with TZ=Asia/Kolkata):

extended ts      = 2024-01-15T12:00:00.000Z
extended ts_arr  = [ "2024-01-15T19:00:00.000Z" ]   <- local time, see #35505
extended date    = 2024-01-15T00:00:00.000Z
extended tstz    = 2024-01-15T12:00:00.000Z
simple   ts      = 2024-01-15T12:00:00.000Z
simple   ts_arr  = [ "2024-01-15T19:00:00.000Z" ]
simple   date    = 2024-01-15T00:00:00.000Z
prepare=true  timestamp   round-trip: EXACT
prepare=true  timestamptz round-trip: EXACT
prepare=false timestamp   bind error: time zone "gmt-0700" not recognized
mysql text   dt = 2024-01-15T12:00:00.000Z | d = 2024-01-15T00:00:00.000Z
mysql binary dt = 2024-01-15T12:00:00.000Z | d = 2024-01-15T00:00:00.000Z
mysql .simple() dt = 2024-01-15T12:00:00.000Z
mysql round-trip dt: EXACT
  • postgres-date@1.0.7 (used by pg) builds timestamp and date values with the local-time Date constructor. postgres@3.3.5 parses OIDs 1082, 1114, and 1184 with new Date(text): the timestamp text shape parses as local time, the date shape as UTC. PGlite output is in the issue.
  • The #dates-and-time-zones anchor matches the heading. The page already uses the `sql.simple()` `` code span form in prose (lines 315, 331, 423, 1089).
  • History: the first draft added a #### subsection under "PostgreSQL-Specific Features" plus a "Not yet implemented" heading. Self-review found that heading level is not in the table of contents and that the text duplicated the MySQL note. Commit 9ed16c5 moved the text to a shared section and restored that part of the page to match main.

no test proof · iteration 0 · docs-only change; test-proof not applicable

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Your included review limit has been reached.

You’re in a promotional period — use the checkbox below to run this review for free:

  • Run review for free

On-demand reviews are free for the next 30 days. After that, they cost $0.25 per reviewed file.

How can I continue?

Run this review now using the option above, or comment @coderabbitai review --use-credits.

You can also wait for the limit to reset (next review available in 18 minutes), then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b6c5343e-84b0-4b6e-bb90-1e0669d923b4

📥 Commits

Reviewing files that changed from the base of the PR and between 72ec6e2 and 9ed16c5.

📒 Files selected for processing (1)
  • docs/runtime/sql.mdx

Comment @coderabbitai help to get the list of available commands.

@robobun

robobun commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 11:24 AM PT - Aug 21st, 2026

@robobun, your commit 9ed16c5b65c368eae7f29f9752a00c716aac3f58 passed in Build #102756! 🎉


🧪   To try this PR locally:

bunx bun-pr 39881

That installs a local version of the PR into your bun-39881 executable, so you can run:

bun-39881 --bun

@claude claude 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.

LGTM — docs-only addition documenting Postgres timestamp UTC decoding, with one grammar nit inline.

Extended reasoning...

Overview

This PR adds a "Timestamps and time zones" subsection under the PostgreSQL-Specific Features section of docs/runtime/sql.mdx, documenting that Bun decodes Postgres timestamp (without time zone) as UTC and that this diverges from node-postgres/postgres.js. It also wraps the pre-existing unimplemented-features list under a "Not yet implemented" heading and rewires the trailing Postgres clause in the MySQL type-table note to link to the new subsection instead of restating it inline. Single file, +15/-1, docs-only.

Security risks

None. Pure prose change to an .mdx file; no code, config, or test changes.

Level of scrutiny

Low. This is user-facing documentation with no runtime impact. I verified the technical claim against src/sql_jsc/postgres/types/date.rs:39-53, which confirms the text-path timestamp decoder parses as UTC to agree with the binary path. The new anchor #timestamps-and-time-zones follows the same lowercase-kebab slug convention used elsewhere in docs/ (e.g., #wal-sidecar-file-cleanup, #one-or-many), so the cross-reference from the MySQL note will resolve. The "Not yet implemented" heading is a mechanical restructure that preserves the existing list content verbatim.

Other factors

CI (Build #102353) is green. No prior human or bot reviews with substantive feedback. The one finding is a grammar nit (comma splice in the cross-reference sentence) — a one-character fix that does not affect correctness or rendering and does not warrant blocking a docs PR.

Comment thread docs/runtime/sql.mdx Outdated

@claude claude 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.

LGTM — docs-only addition; the earlier comma-splice nit is fixed in ba08b73.

What was reviewed:

  • Verified the UTC-decoding claim against src/sql_jsc/postgres/types/date.rs (both binary and text paths decode timestamp as UTC; from_js writes UTC components).
  • Checked the new #timestamps-and-time-zones anchor matches the added #### heading.
  • Confirmed the MySQL note now ends with a period before the link, resolving the prior review comment.
Extended reasoning...

Overview

This PR adds a "Timestamps and time zones" subsection under the PostgreSQL-Specific Features section of docs/runtime/sql.mdx, documenting that Bun decodes Postgres timestamp (without time zone) as UTC and that this diverges from node-postgres/postgres.js. It also moves the pre-existing unimplemented-features list under a "Not yet implemented" heading and rewrites the trailing Postgres clause in the MySQL type-table note to link to the new section instead of restating it. Single file, docs only, no code or test changes.

Security risks

None. This is prose in a .mdx documentation file with no executable content, no config, and no user-controlled input.

Level of scrutiny

Low. The change is documentation for existing behavior, not a behavior change. I verified the technical accuracy against the implementation: src/sql_jsc/postgres/types/date.rs shows from_binary computing milliseconds from the UTC Postgres epoch, timestamp_text_to_ms_utc explicitly decoding text-format timestamp as UTC so it agrees with the binary path, and from_js writing a bound Date's Unix timestamp (UTC). The claim about round-tripping and the divergence from pg/postgres.js (which parse local time) is accurate.

Other factors

The one prior review comment (my comma-splice nit) was addressed in commit ba08b73 — the sentence now reads "…behaves the same way. See Timestamps and time zones." The anchor slug matches the new heading. The "Not yet implemented" heading keeps the section structured now that it has real content above the bullet list. CI passed. No CODEOWNERS entry covers docs/. Prettier was run per the PR description.

…timestamp section

Co-authored-by: deepshekhardas <deepshekharadas1234@gmail.com>

@claude claude 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.

LGTM — docs-only addition documenting Postgres timestamp UTC decoding; the earlier comma-splice nit was fixed in ba08b73.

Checked that the UTC-decoding claim matches src/sql_jsc/postgres/types/date.rs:39 and that a bound Date writes UTC components (date.rs:67/:87). Verified the #timestamps-and-time-zones anchor matches the new #### heading and that the sql``.simple() backtick pattern follows existing usage in this file. The "Not yet implemented" heading is a pure regroup — no content was dropped.

Extended reasoning...

Overview

This PR adds a "Timestamps and time zones" subsection under the PostgreSQL-Specific Features section of docs/runtime/sql.mdx, documenting that Bun decodes Postgres timestamp (without time zone, OID 1114) as UTC — a divergence from node-postgres, postgres.js, and PGlite which decode as local time. It also moves the pre-existing unimplemented-features list under a new "Not yet implemented" heading and replaces the trailing Postgres clause in the MySQL type-table note with a cross-link to the new subsection. Docs-only; no source or test files touched.

Security risks

None. This is prose in an .mdx documentation file with no executable code paths, no configuration, and no build-system changes.

Level of scrutiny

Low. Docs-only changes to a runtime guide. The main things to verify are technical accuracy against source and that MDX rendering isn't broken. I confirmed the UTC-decoding behavior against src/sql_jsc/postgres/types/date.rs:39 (timestamp_text_to_ms_utc) and the write-side claim against date.rs:67-88 (uses get_unix_timestamp() → UTC components). The anchor slug #timestamps-and-time-zones matches the #### Timestamps and time zones heading per standard MDX slugging, and the sql``.simple() double-backtick idiom is already used throughout this file (.values(), .raw()), so no new rendering pattern is introduced.

Other factors

An earlier automated pass flagged a comma splice in the MySQL note's cross-reference sentence; that thread is resolved and the current diff shows the fix (". See [Timestamps and time zones]"). CI (Build #102664) passed on the head commit. Prettier was run per the PR description. The "Not yet implemented" heading insertion is a pure structural regroup — the COPY/GSSAPI/SCRAM-SHA-256-PLUS/PostGIS list is unchanged. No CODEOWNERS implications for docs. Nothing outstanding.

… section

The section is a top-level heading, so it appears in the page table of
contents. It states the UTC rule once for PostgreSQL timestamp and MySQL
DATETIME and TIMESTAMP, covers date and timestamp[] values, and scopes
the encode statement to prepared statements. The MySQL type note links
to it. The PostgreSQL-Specific Features section is unchanged from main.
@robobun robobun changed the title docs(sql): document Postgres timestamp UTC decoding in the PostgreSQL section docs(sql): add a Dates and time zones section for timestamp UTC decoding Aug 21, 2026

@claude claude 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.

LGTM — docs-only addition of a shared "Dates and time zones" section.

What was reviewed:

  • Verified the UTC-decoding claims against src/sql_jsc/postgres/types/date.rs and DataCell.rs — scalar timestamp goes through timestamp_text_to_ms_utc/binary UTC path; timestamp[] elements still go through parse_date (local), matching the caveat in the new prose.
  • Checked the #dates-and-time-zones anchor matches the new ## heading slug, and that the prior comma-splice nit was resolved (now ". See […]").
  • Confirmed the date → UTC-midnight claim via the Date.parse path comment at DataCell.rs:849.
Extended reasoning...

Overview

This PR adds a top-level ## Dates and time zones section to docs/runtime/sql.mdx documenting that Bun decodes Postgres timestamp (OID 1114) and MySQL DATETIME/TIMESTAMP as UTC, contrasts with node-postgres/postgres.js/PGlite (local time), notes the timestamp[] array exception, and recommends timestamptz. It also shortens the existing MySQL type-table note to a one-line cross-reference to the new section. Net +18/-1 lines, single file, docs only.

The PR description describes an earlier iteration (subsection under "PostgreSQL-Specific Features" with a "Not yet implemented" heading move); commit 9ed16c5 simplified this to a shared top-level section, so the final diff is smaller than described and does not touch the PostgreSQL-Specific Features heading structure.

Security risks

None. Pure documentation prose in an .mdx file — no code, config, or dependency changes.

Level of scrutiny

Low. Docs-only, and the technical claims are verifiable against source. I checked each factual assertion:

  • timestamp decoded as UTC: confirmed by src/sql_jsc/postgres/types/date.rs:39-46 (text path) and from_binary (binary path uses the Postgres epoch as UTC ms).
  • .simple() and parameterized queries agree: confirmed by the same file's comment ("text/simple-query path agrees with the binary path").
  • timestamp[] array elements decoded as local time: confirmed at DataCell.rs:213-222, where timestamp_array elements go through parse_date (JS Date.parse on a space-separated timestamp string → local), not timestamp_text_to_ms_utc.
  • date → UTC midnight: confirmed by DataCell.rs:848-851 (date-only ISO strings through Date.parse are UTC per ECMA-262).
  • Anchor #dates-and-time-zones matches the ## Dates and time zones heading slug.

Other factors

  • The one prior review finding (comma splice in the MySQL cross-reference) was fixed in ba08b73 and further reworked in 9ed16c5; the current line reads "…as UTC. See Dates and time zones." — resolved.
  • CI (Build #102756) is green.
  • The `sql.simple()` `` code-span form matches existing usage elsewhere on the same page.
  • No CODEOWNERS on docs/; no outstanding human review comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: timestamp without time zone decoding as UTC isn't documented in the PostgreSQL section

1 participant