Repository navigation
Conversation
Issue and due dates are stored as UTC midnight. Formatting them with local getters shifts them by a day when the server runs in a timezone west of UTC. Use UTC getters for the PDF, the UBL/Factur-X/FatturaPA exports and the overdue check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The invoice page read the UTC-midnight issue/due dates in the browser's local time, showing the previous day west of UTC. Add a shared formatDate() helper that reads date-only values in UTC and honours the Date Format setting, and use it on the invoice page. The overdue badge gets the same UTC treatment; history timestamps stay in local time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#149) Both views hard-coded toLocaleDateString() with a short month name, ignoring Settings > Localization > Date Format, and were affected by the same off-by-one. Use the shared formatDate() helper instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
toISOString() returns the UTC date, which is already tomorrow in the evening for users west of UTC. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix invoice issue date shown one day early and inconsistent date format
Closes #149
Problem
The issue reports two bugs:
Root cause
Off-by-one: issue and due dates are date-only values, but the backend stores them as UTC midnight:
new Date("2026-10-09")→2026-10-09T00:00:00.000Z. The frontend then read that timestamp with local getters (getDate(),toLocaleDateString()). In any timezone west of UTC (e.g. the Americas), UTC midnight is still the previous evening, so the date showed as Oct 8.The PDF looked right only because it's rendered on the server, which runs in UTC in Docker. Any server timezone west of UTC would have shifted it as well.
Format: the invoice page and the PDF already followed Settings → Localization → Date Format. The invoice list and the dashboard hard-coded
toLocaleDateString(locale, { month: "short", … })(e.g.Oct 9, 2026) and ignored the setting.Changes
1. Read invoice dates in UTC on the backend
UTC getters for date-only values in:
utils/pdf.ts: PDF issue/due datesutils/ubl.ts,utils/facturx.ts,utils/fatturapa.ts: e-invoice XML exportscontrollers/invoices.ts: overdue checkOutput now stays the same whatever timezone the server runs in.
2. Show the correct issue date on the invoice page
frontend/src/lib/utils/date.ts:formatDate(date, format, utc = true).YYYY-MM-DD/DD.MM.YYYY).utc = falsefor real timestamps.date.test.ts.3. Use the Date Format setting in the invoice list and dashboard
The issue date in both views, and "last updated" in the list, now use
formatDate(), so all dates follow the setting.4. Default new invoices to today's local date
The editor defaulted to
new Date().toISOString().slice(0, 10), which is the UTC date. In the evening west of UTC that's already tomorrow. It now uses the local date.Before / after (browser in
America/New_York, issue date 2026-10-09)YYYY-MM-DD)DD.MM.YYYY)Not in scope
YYYY-MM-DD,DD.MM.YYYY) is now simply applied everywhere.Testing
bun test→ 17/17 pass (4 new forformatDate)svelte-check→ 0 errorsTZ=America/New_York: old code gives2026-10-08, new code gives2026-10-09DD.MM.YYYYand check that all of the views above follow it🤖 Generated with Claude Code