Skip to content

Date column renders one day early in server mode due to local‑midnight serialization #3106

@BerendMosch

Description

@BerendMosch

This bug report has been written with the help of GTP-5.2

Bug Report

Summary

In server mode (perspective‑python + perspective‑viewer), date values can render one day earlier in the datagrid for non‑UTC timezones (e.g. Europe/Amsterdam). The server’s JSON serialization of date uses local‑time midnight (mktime), while the datagrid formats date as UTC. That mismatch shifts the calendar day backward.

Steps to Reproduce:

Using the uv package manager:
TZ=Europe/Amsterdam uv run --with perspective-python python - <<'PY'
from datetime import datetime, timezone
import perspective as psp

client = psp.Server().new_local_client()
Table = client.table

tbl = Table({"d": "date"})
tbl.update({"d": ["2024-01-01"]})

value = tbl.view().to_columns()["d"][0]
utc_date = datetime.fromtimestamp(value / 1000, tz=timezone.utc).date()
local_date = datetime.fromtimestamp(value / 1000).date()

print("value_ms", value)
print("utc_date", utc_date)
print("local_date", local_date)
PY

Output:
value_ms 1704063600000
utc_date 2023-12-31
local_date 2024-01-01

Expected Result:

'date' values should be timezone‑agnostic. The datagrid should display 2024‑01‑01 regardless of local TZ.

Actual Result:

In server mode, date values display one day earlier in the datagrid for non‑UTC timezones (e.g. 2023‑12‑31 instead of 2024‑01‑01).

Root Cause (code)

  • Server JSON serialization uses local midnight:
    • rust/perspective-server/cpp/perspective/src/cpp/view.cppwrite_scalarDTYPE_DATE uses mktime(&t) (local time).
  • Datagrid formats dates in UTC:
    • packages/viewer-datagrid/src/js/data_listener/formatter_cache.jscreate_date_formatter sets timeZone: "utc".

This yields local‑midnight ms interpreted as UTC, shifting the day in UTC+ timezones.

Suggested Fix

Serialize DTYPE_DATE to epoch ms using UTC midnight (or days‑since‑epoch) instead of mktime local time. That keeps date values stable across timezones while preserving the viewer’s UTC date formatting.

Notes

This repro shows the mismatch using to_columns() (which uses the same JSON serialization path as the viewer in server mode).

Environment

  • Ubuntu 22.04.5 LTS on Windows 10 x86_
  • python version == 3.12.8. perspective-server version == 4.0.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions