Skip to content

Commit 5b6221f

Browse files
authored
fix: use UTC date parsing for contribution tooltips (JhaSourav07#1895)
## Description Fixes timezone-related date shifting in contribution tooltips by treating GitHub contribution dates as UTC calendar dates instead of local timezone dates. The `formatDate` function previously used `new Date(year, month - 1, day)` which caused negative UTC offsets (like EST/PST) to display the previous day. This PR switches to UTC-safe date parsing using ISO strings while preserving the existing formatting behavior via the `Intl` API explicitly set to UTC, and adds regression tests for multiple timezones. Fixes JhaSourav07#1892 ## Pillar - [ ] 🎨 Pillar 1 — New Theme Design - [ ] 📐 Pillar 2 — Geometric SVG Improvement - [x] 🕐 Pillar 3 — Timezone Logic Optimization - [ ] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview *(No visual changes to the UI design, but the tooltips now accurately display the correct date for users in negative UTC offsets).* ## Checklist before requesting a review: - [x] I have read the `CONTRIBUTING.md` file. - [x] I have tested these changes locally (`localhost:3000/api/streak?user=YOUR_USERNAME`). - [x] I have run `npm run format` and `npm run lint` locally and resolved all errors (CI will fail otherwise). - [x] My commits follow the Conventional Commits format (e.g., `feat(themes): ...`, `fix(calculate): ...`). - [x] I have updated `README.md` if I added a new theme or URL parameter. - [x] I have started the repo. - [x] I have made sure that i have only one commit to merge in this PR. - [x] The SVG output matches the CommitPulse "premium quality" aesthetic standard (no raw elements, smooth animations, correct fonts). - [ ] (Recommended) I joined the CommitPulse Discord community for contributor discussions, mentorship, and faster PR support.
2 parents 40699f9 + 53158f0 commit 5b6221f

3 files changed

Lines changed: 25 additions & 13 deletions

File tree

components/InteractiveViewer.test.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { render, screen, fireEvent } from '@testing-library/react';
33
import { describe, it, expect, beforeEach, vi } from 'vitest';
4-
import InteractiveViewer from './InteractiveViewer';
4+
import InteractiveViewer, { formatDate } from './InteractiveViewer';
55

66
// getBoundingClientRect is not implemented in jsdom — mock it so mouse-position
77
// tests can assert normalized values without relying on a real layout engine.
@@ -23,6 +23,23 @@ beforeEach(() => {
2323
Element.prototype.releasePointerCapture = vi.fn();
2424
});
2525

26+
describe('formatDate', () => {
27+
it('formats valid UTC date strings correctly', () => {
28+
expect(formatDate('2025-06-15')).toBe('Jun 15, 2025');
29+
expect(formatDate('2025-01-01')).toBe('Jan 1, 2025');
30+
expect(formatDate('2025-12-31')).toBe('Dec 31, 2025');
31+
});
32+
33+
it('returns empty string for empty input', () => {
34+
expect(formatDate('')).toBe('');
35+
});
36+
37+
it('returns original string for malformed input', () => {
38+
expect(formatDate('2025-06')).toBe('2025-06');
39+
expect(formatDate('invalid-date-string')).toBe('invalid-date-string');
40+
});
41+
});
42+
2643
describe('InteractiveViewer', () => {
2744
// ── Existing behaviour ────────────────────────────────────────────────────
2845

components/InteractiveViewer.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ interface ActiveTooltipState {
5656
y: number;
5757
}
5858

59-
const formatDate = (dateStr: string): string => {
59+
export const formatDate = (dateStr: string): string => {
6060
if (!dateStr) return '';
6161
const parts = dateStr.split('-');
6262
if (parts.length !== 3) return dateStr;
@@ -65,8 +65,10 @@ const formatDate = (dateStr: string): string => {
6565
const day = parseInt(parts[2], 10);
6666
if (isNaN(year) || isNaN(month) || isNaN(day)) return dateStr;
6767
try {
68-
const date = new Date(year, month - 1, day);
68+
const date = new Date(`${dateStr}T00:00:00Z`);
69+
if (isNaN(date.getTime())) return dateStr;
6970
const formatted = date.toLocaleDateString('en-US', {
71+
timeZone: 'UTC',
7072
month: 'short',
7173
day: 'numeric',
7274
year: 'numeric',

package-lock.json

Lines changed: 3 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)