Fix #274: Use millisecond timestamps for date filtering to fix timezone issue#276
Fix #274: Use millisecond timestamps for date filtering to fix timezone issue#276
Conversation
…sue, close #274 Previously, date filters were passed as local time strings (e.g., "2025-12-06T00:00") which caused timezone inconsistencies between the browser and server: - Browser interpreted dates in its local timezone - Server interpreted the same strings in its configured timezone (TZ env) - This caused queries to return wrong results when browser/server timezones differed Changes: - Frontend now converts selected dates to millisecond timestamps (Unix epoch) - Backend converts timestamps to ISO strings for PostgreSQL comparison - URL parameters changed from startDate/endDate to startTime/endTime (ms) - Removed unused getEnvConfig import from usage-logs repository This approach eliminates timezone ambiguity by using absolute time points. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Summary of ChangesHello @ding113, 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! This pull request addresses a critical timezone inconsistency bug in the usage logs date filtering mechanism. Previously, date filters were passed as local time strings, leading to misinterpretations across different timezones. The solution involves a comprehensive refactor to use millisecond Unix epoch timestamps for all date-related data transfer, ensuring consistent and accurate filtering regardless of the user's or server's timezone. Highlights
Using Gemini Code AssistThe 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 by creating a comment using either
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 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. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. 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
|
There was a problem hiding this comment.
Code Review
This pull request effectively resolves a timezone inconsistency issue by switching from local time strings to millisecond timestamps for date filtering. The changes across the frontend components and the backend repository are well-implemented and correctly address the root cause. My review includes a couple of suggestions in usage-logs-filters.tsx to improve code maintainability by reducing magic numbers and code duplication when handling dates, recommending more extensive use of the date-fns library.
| }, [localFilters.endDateLocal]); | ||
| if (!localFilters.endTime) return undefined; | ||
| // endTime is next day 00:00, so subtract 1 day to get actual end date | ||
| const actualEndDate = new Date(localFilters.endTime - 24 * 60 * 60 * 1000); |
There was a problem hiding this comment.
Using a magic number for the number of milliseconds in a day (24 * 60 * 60 * 1000) can be fragile, as it doesn't account for edge cases like Daylight Saving Time transitions. It's safer and more readable to use a function from your date library. Since you're already using date-fns, you can use subDays for this. You'll need to import subDays from date-fns.
| const actualEndDate = new Date(localFilters.endTime - 24 * 60 * 60 * 1000); | |
| const actualEndDate = subDays(new Date(localFilters.endTime), 1); |
| const endTimestamp = new Date( | ||
| nextDay.getFullYear(), | ||
| nextDay.getMonth(), | ||
| nextDay.getDate(), | ||
| 0, | ||
| 0, | ||
| 0, | ||
| 0 | ||
| ).getTime(); |
There was a problem hiding this comment.
This block of code manually constructs a Date object to get the start of the day. This logic is already encapsulated in your dateStringToTimestamp helper function. Reusing the helper will make the code more concise and less prone to duplication errors.
const endTimestamp = dateStringToTimestamp(format(nextDay, "yyyy-MM-dd"));
ding113
left a comment
There was a problem hiding this comment.
Code Review Summary
No significant issues identified in this PR. The timezone fix approach is correct - using millisecond timestamps for frontend-backend communication eliminates timezone ambiguity effectively.
PR Size: S
- Lines changed: 163 (86 additions, 77 deletions)
- Files changed: 3
Issues Found
| Category | Critical | High | Medium | Low |
|---|---|---|---|---|
| Code Quality | 0 | 0 | 0 | 0 |
| Security | 0 | 0 | 0 | 0 |
| Dependencies | - | - | - | - |
| Documentation | - | - | - | - |
Review Coverage
- Code quality and correctness - Clean
- Security (OWASP Top 10) - Clean
- PR size assessment - S (appropriate size)
- Dependency changes - N/A (no dependency changes)
- Documentation changes - N/A (no docs changes)
Automated review by Claude AI
Summary
Fixes the timezone inconsistency issue in usage logs date filtering reported in #274.
Root cause: Date filters were passed as local time strings (e.g.,
"2025-12-06T00:00") which caused different interpretations between browser and server timezones.Solution: Use millisecond timestamps (Unix epoch) for frontend-backend communication, eliminating timezone ambiguity.
Changes
usage-logs-filters.tsx: Convert selected date ranges to millisecond timestampsusage-logs-view.tsx: Parse/pass timestamps via URL params (startTime/endTime)usage-logs.ts(repository): Accept timestamps and convert to ISO strings for PostgreSQLTechnical Details
Before:
After:
Test Plan
startTimeandendTimeas millisecond timestampsCloses #274
🤖 Generated with Claude Code