Skip to content

fix(deploy-web): show billing charge dates in UTC#3258

Open
renezander030 wants to merge 1 commit into
akash-network:mainfrom
renezander030:fix/billing-dates-utc
Open

fix(deploy-web): show billing charge dates in UTC#3258
renezander030 wants to merge 1 commit into
akash-network:mainfrom
renezander030:fix/billing-dates-utc

Conversation

@renezander030
Copy link
Copy Markdown

@renezander030 renezander030 commented Jun 3, 2026

Hi, and thanks for the work on Console.

Fixes #2010. The billing history table rendered the Stripe charge date with toLocaleDateString(), which formats in the viewer's local timezone. Stripe receipts use the charge's UTC date, so for users far from UTC the Console could show a day that differs from the receipt.

This renders the date with { timeZone: "UTC" } and labels the column Date (UTC) so it is unambiguous and matches the receipt regardless of where the viewer is. The created value is a Stripe Unix timestamp, so UTC is its canonical basis.

Changed BillingView.tsx (the created column) and updated its spec to match.

Note on local testing

The repo targets Node 24 / npm 11, and the committed lockfile is currently out of sync (npm ci fails on missing esbuild entries unrelated to this change), so I could not run the vitest suite locally without rewriting the lockfile. This is a one-line formatting change and the spec was updated to mirror it, so CI should cover it. Happy to tweak the column label or approach if you would prefer something else.

Summary by CodeRabbit

  • Bug Fixes
    • Updated the billing table to display all dates in UTC timezone. The "Date" column header now indicates "(UTC)" to clarify the timezone standard being used.

The billing history table rendered the Stripe charge date with
toLocaleDateString(), which uses the viewer's local timezone. Stripe
receipts use the charge's UTC date, so the two could differ by a day
for users far from UTC.

Render the date with timeZone "UTC" and label the column "Date (UTC)"
so it matches the Stripe receipt regardless of the viewer's location.
The created value is a Stripe Unix timestamp, so UTC is its canonical
basis. Updated the BillingView spec to match.

Closes akash-network#2010

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@renezander030 renezander030 requested a review from a team as a code owner June 3, 2026 06:27
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 3, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9a99e59b-c693-4cd5-a07a-34aae15cb75b

📥 Commits

Reviewing files that changed from the base of the PR and between 7dadcbc and 83b3fc0.

📒 Files selected for processing (2)
  • apps/deploy-web/src/components/billing-usage/BillingView/BillingView.spec.tsx
  • apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx

📝 Walkthrough

Walkthrough

The billing view component and its test are updated to display charge creation dates in UTC timezone instead of the user's local browser timezone. The column header is relabeled to indicate "(UTC)" and date formatting now explicitly specifies timeZone: "UTC".

Changes

Billing date timezone alignment

Layer / File(s) Summary
UTC date column rendering and validation
apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx, apps/deploy-web/src/components/billing-usage/BillingView/BillingView.spec.tsx
The created column header is relabeled to "Date (UTC)" and timestamps are formatted using toLocaleDateString with explicit { timeZone: "UTC" } parameter. Test assertions updated to validate the UTC-formatted dates and column header label.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Assessment against linked issues

Objective Addressed Explanation
Align billing UI dates with Stripe receipts by using UTC timezone [#2010]

Out-of-scope changes

No out-of-scope changes detected. All modifications directly address the timezone misalignment between the UI and Stripe receipts.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@baktun14 baktun14 left a comment

Choose a reason for hiding this comment

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

Thanks for the PR and the clear write-up! The change is clean and mechanically correct — created is a UTC epoch, and the * 1000 / timeZone: "UTC" handling is right. Also, don't worry about the npm ci failure you hit: that's a local Node 24 / npm 11 version mismatch, not lockfile drift. CI and the spec pass fine.

One thing I want to confirm before merging, because it decides whether this actually closes #2010:

Does the receipt show UTC, or the account timezone? The API created value is always UTC, but the displayed date on customer-facing receipts resolves as: customer timezone (if set) → account timezone → UTC fallback (customer emails, time zone customization). So this matches the receipt only if our Stripe account timezone is set to UTC. That's something I need to check on our side (you wouldn't have access) — I'll confirm our account setting and report back. If it's not UTC, the right fix is to render in the account timezone rather than UTC.

Second — consistency with the CSV export. That path already formats dates in the viewer's local timezone:

  • BillingContainer sends Intl.DateTimeFormat().resolvedOptions().timeZone to the API
  • the API formats each row with toLocaleString("en-CA", { timeZone }) in transformTransactionForCsv

So with this change the on-screen table shows UTC while the CSV of the same rows shows local time — they can disagree across a midnight-UTC boundary. Whatever timezone we settle on, it should apply to both surfaces so they always agree.

Suggested sequencing: let me confirm our account timezone first (that decides UTC vs account-TZ), then we align the table and the CSV export on that one timezone. I'll follow up here once I've checked. Thanks again for digging into this!

@renezander030
Copy link
Copy Markdown
Author

Hi, thanks for the careful review and for digging into the receipt resolution order, that's a good catch.

You're right that created being UTC only closes #2010 if the rendered date matches what the customer actually sees on the receipt, and that resolves as customer TZ > account TZ > UTC. So hardcoding UTC is only correct in the account-TZ-is-UTC case. Two thoughts on that:

  1. Rather than betting on the account setting (which can change later and silently desync the table from receipts again), we could render in the account's configured timezone directly: pull settings.dashboard.timezone from stripe.accounts.retrieve() once, pass it down, and format both surfaces against it. That tracks the receipt by construction regardless of what the account TZ is set to, and the column label can reflect it. Happy to go that route if you'd prefer it over a static UTC, otherwise I'll switch the label/format to whatever you confirm.

  2. Fully agree on the CSV consistency point. The table and transformTransactionForCsv disagreeing across a midnight-UTC boundary is exactly the kind of off-by-a-day this issue is about, just on a different surface. Whatever timezone we land on should drive both the created column and the CSV path (and the Intl...resolvedOptions().timeZone that BillingContainer currently sends).

I'm happy to extend this PR to cover both surfaces once you've confirmed the account timezone, just let me know UTC vs account-TZ and I'll align the table and the export on the one source. Thanks again.

Rene

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.

Billing UI dates don't match stripe receipt (different TZ)

2 participants