-
-
Notifications
You must be signed in to change notification settings - Fork 317
fix: use local timezone for date grouping instead of UTC #414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The date formatters were using UTC timezone which caused usage data to be grouped incorrectly. For example, usage at 20:00 local time would appear on the next day if the local timezone was behind UTC. This regression was introduced in PR #409 (commit f7c5251) which added explicit UTC timezone to the Intl.DateTimeFormat configuration. The fix removes the hardcoded 'timeZone: UTC' option, allowing the formatters to respect the system's local timezone or the TZ environment variable if set. Changes: - Remove 'timeZone: UTC' from dateFormatter - Remove 'timeZone: UTC' from datePartsFormatter - Update comment to reflect local timezone usage This ensures usage data is grouped by the user's local date boundaries rather than UTC date boundaries.
WalkthroughThe change removes the explicit 'UTC' timezone setting from two Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DataLoader
participant Intl.DateTimeFormat
User->>DataLoader: Request data
DataLoader->>Intl.DateTimeFormat: Format date (local timezone)
Intl.DateTimeFormat-->>DataLoader: Formatted date string (local timezone)
DataLoader-->>User: Return data with local-formatted dates
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~2 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changesNo out-of-scope changes found. Possibly related PRs
Suggested reviewers
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate 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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @ben-vargas, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
I've addressed an issue where usage data was being grouped incorrectly based on UTC time, rather than the user's local timezone. This was causing data to appear on the wrong dates for users, especially those in timezones behind UTC. My solution involved removing the explicit timeZone: 'UTC' setting from the Intl.DateTimeFormat instances in data-loader.ts, which now allows the system to default to the user's local timezone for date grouping. This change significantly improves the accuracy and user-friendliness of the usage reports.
Highlights
- Incorrect Date Grouping: Usage data was being incorrectly grouped by UTC date boundaries instead of the user's local timezone, leading to confusing and inaccurate reports where usage appeared on the wrong day.
- Timezone Configuration Change: The hardcoded
timeZone: 'UTC'configuration was removed fromIntl.DateTimeFormatinstances withindata-loader.ts. - Improved User Experience: This change ensures that usage data is now grouped according to the user's local date boundaries, providing a more intuitive and accurate representation of their activity.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request correctly addresses an issue where usage data was grouped by UTC dates instead of the user's local timezone. By removing the hardcoded timeZone: 'UTC' from the Intl.DateTimeFormat instances, the date formatting now correctly defaults to the system's local timezone. The changes are simple, targeted, and effectively resolve the problem described, making the usage reports more intuitive for users in different timezones. The approach is sound and I see no issues with the implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/data-loader.ts (1)
542-546: Mirror the comment abovedatePartsFormatterFor consistency with the first formatter’s docblock, update the comment here to mention that the system’s local timezone (or
$TZ) is used. Purely cosmetic but avoids confusion for future readers.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/data-loader.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*.{js,jsx,ts,tsx}: Lint code using ESLint MCP server (available via Claude Code tools)
Format code with ESLint (writes changes) usingbun run format
No console.log allowed except where explicitly disabled with eslint-disable
Do not use console.log. Use logger.ts instead.
Files:
src/data-loader.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Type check with TypeScript using
bun typecheck
Files:
src/data-loader.ts
**/*.ts
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*.ts: File paths always use Node.js path utilities for cross-platform compatibility
Use.tsextensions for local file imports (e.g.,import { foo } from './utils.ts')
Prefer @praha/byethrow Result type over traditional try-catch for functional error handling
UseResult.try()for wrapping operations that may throw (JSON parsing, etc.)
UseResult.isFailure()for checking errors (more readable than!Result.isSuccess())
Use early return pattern (if (Result.isFailure(result)) continue;) instead of ternary operators
For async operations: create wrapper function withResult.try()then call it
Keep traditional try-catch only for: file I/O with complex error handling, legacy code that's hard to refactor
Always useResult.isFailure()andResult.isSuccess()type guards for better code clarity
Variables: start with lowercase (camelCase) - e.g.,usageDataSchema,modelBreakdownSchema
Types: start with uppercase (PascalCase) - e.g.,UsageData,ModelBreakdown
Constants: can use UPPER_SNAKE_CASE - e.g.,DEFAULT_CLAUDE_CODE_PATH
Only export constants, functions, and types that are actually used by other modules
Internal/private constants that are only used within the same file should NOT be exported
Always check if a constant is used elsewhere before making itexport constvs justconst
All test files must use current Claude 4 models, not outdated Claude 3 models
Test coverage should include both Sonnet and Opus models for comprehensive validation
Model names in tests must exactly match LiteLLM's pricing database entries
When adding new model tests, verify the model exists in LiteLLM before implementation
Tests depend on real pricing data from LiteLLM - failures may indicate model availability issues
Dynamic imports usingawait import()should only be used within test blocks to avoid tree-shaking issues
Mock data is created usingfs-fixturewithcreateFixture()for Claude data directory simulation
In-source testing pattern: Tests are written...
Files:
src/data-loader.ts
🔇 Additional comments (1)
src/data-loader.ts (1)
520-526: Local-TZ dateFormatter works, but verify midnight-edge casesDropping the
timeZone: 'UTC'flag meansnew Date('2024-01-01T00:00:00Z')will now be rendered as the previous day for users west of UTC (e.g.America/Los_Angeles).
That’s the intended behavioural change, but a couple of unit tests (Lines 1381-1385) still assert'2024-01-01'for that exact timestamp. They will now fail on CI runners whose$TZis not UTC.Please:
- expect(formatDate('2024-01-01T00:00:00Z')).toBe('2024-01-01'); + // At UTC midnight the local calendar day may shift. Assert relative result. + expect(['2023-12-31', '2024-01-01']).toContain(formatDate('2024-01-01T00:00:00Z'));(or use a noon timestamp like elsewhere).
This keeps the tests hermetic across time-zones while retaining the desired production behaviour.
ryoppippi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Summary
This PR fixes an issue where usage data was being grouped by UTC date boundaries instead of the user's local timezone, causing data to appear on incorrect dates.
Fixes #413
Caused by #409
Problem
When using ccusage, usage data was being grouped incorrectly based on UTC time rather than the user's local timezone. This caused confusing results where:
Example
A user in MDT (UTC-6) using Claude Code at 8:00 PM on August 3rd would see that usage reported as August 4th, because 8:00 PM MDT is 2:00 AM UTC the next day.
Solution
Removed the hardcoded
timeZone: 'UTC'configuration from theIntl.DateTimeFormatinstances indata-loader.ts. This allows the date formatters to:TZenvironment variable if users want to override itChanges
timeZone: 'UTC'fromdateFormattertimeZone: 'UTC'fromdatePartsFormatterTesting
TZenvironment variable can still override timezone if neededBackward Compatibility
This change makes the date grouping more intuitive and correct for users. The data itself is unchanged - only the grouping/display is affected. Users who need UTC grouping can still achieve it by setting
TZ=UTC.Summary by CodeRabbit