Skip to content

Schedule date options are built in UTC, so they can offer the wrong calendar day #99

Description

@maxlamagna

Version: v0.5.0 (c24f605)

This one is invisible if your machine runs on UTC, which is probably why it has survived.

The date dropdown is built in UTC

static/chat.js:3541 populates the schedule popover's date options with:

opt.value = d.toISOString().slice(0, 10);

toISOString() formats in UTC. Whenever the user's local calendar date differs from the UTC date at that moment, which is most of the evening for anyone east of UTC and the early morning for anyone west of it, the option labelled Today carries yesterday's or tomorrow's date.

There is nothing to see: you pick the day that reads correctly and the message lands 24 hours away from where you meant.

The server then re-resolves the same moment independently

The browser submits a date string and a time string, and the server re-parses them:

app.py:1611:

dt = _dt.datetime.strptime(f"{send_at_date} {daily_at}", "%Y-%m-%d %H:%M")
send_at = dt.timestamp()

.timestamp() resolves in the server's timezone. On a single machine both sides agree and this is harmless, but two independent places are each deciding what "today at 3pm" means, so they only agree by coincidence rather than by design. Anyone reaching the server from a browser in another timezone gets the disagreement for real.

Suggested direction

Build the date options from local calendar fields (getFullYear(), getMonth(), getDate()) rather than from a UTC string.

For the second half, the browser already knows exactly which moment the user picked, so it can resolve it and send the epoch, leaving the server with nothing to re-derive. That removes the second code path instead of trying to keep two of them in agreement.

Fixed by #95. The new field is optional and additive, and requests that omit it behave exactly as before.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions