-
Notifications
You must be signed in to change notification settings - Fork 27
Show year in tournament dates when different from current year #4057
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
Updated tournament timeline components to display the year in dates when the tournament dates differ from the current year. Previously, years were only shown when start and end dates were in different years, which meant past tournaments didn't show the year. Fixes #4054 Co-authored-by: Sylvain <[email protected]>
📝 WalkthroughWalkthroughThe changes modify date formatting logic in tournament timeline components. They extract year values from various timestamp fields and use composite year comparisons to determine whether dates display with or without the year. When all relevant years match the current year, dates use short format "MMM dd"; otherwise they include the year "MMM dd yyyy". Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@front_end/src/app/`(main)/(tournaments)/tournament/components/active_tournament_timeline.tsx:
- Around line 44-50: The year comparison relies on getYear(new Date()) which
uses the server's local timezone; make the intent explicit by computing years in
UTC (or a specific timezone) instead: replace getYear(new Date()), getYear(new
Date(tournament.start_date)), and getYear(new
Date(latestScheduledCloseTimestamp)) with UTC-based year extraction (e.g., new
Date(...).getUTCFullYear()) or, if you need a particular zone, convert dates
with date-fns-tz (utcToZonedTime) and then extract the year; update the
currentYear, startYear, closeYear and consequently formatString logic to use
these UTC/zone-aware year values.
♻️ Duplicate comments (1)
front_end/src/app/(main)/(tournaments)/tournament/components/closed_tournament_timeline.tsx (1)
42-57: Same timezone sensitivity as noted in active timeline.
ThecurrentYearcomparison here is also based on server time. If the product requirement is “current year in the user’s locale/time zone,” please ensure the year is derived consistently with the displayed dates.date-fns getYear timezone behavior (local vs UTC) and recommended approach for SSR date formatting next-intl server time zone access for formatting dates in the user’s time zone
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
front_end/src/app/(main)/(tournaments)/tournament/components/active_tournament_timeline.tsxfront_end/src/app/(main)/(tournaments)/tournament/components/closed_tournament_timeline.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Build Docker Image / Build Docker Image
- GitHub Check: Frontend Checks
- GitHub Check: Backend Checks
- GitHub Check: integration-tests
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| const currentYear = getYear(new Date()); | ||
| const startYear = getYear(new Date(tournament.start_date)); | ||
| const closeYear = getYear(new Date(latestScheduledCloseTimestamp)); | ||
| const formatString = | ||
| getYear(new Date(latestScheduledCloseTimestamp)) === | ||
| getYear(new Date(tournament.start_date)) | ||
| startYear === currentYear && closeYear === currentYear | ||
| ? "MMM dd" | ||
| : "MMM dd yyyy"; |
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.
🧩 Analysis chain
🏁 Script executed:
cat -n front_end/src/app/\(main\)/\(tournaments\)/tournament/components/active_tournament_timeline.tsx | head -60Repository: Metaculus/metaculus
Length of output: 2623
🏁 Script executed:
cat -n front_end/src/app/\(main\)/\(tournaments\)/tournament/components/active_tournament_timeline.tsx | sed -n '51-100p'Repository: Metaculus/metaculus
Length of output: 114
🏁 Script executed:
# Check how formatDate utility works
cat front_end/src/utils/formatters/date.tsRepository: Metaculus/metaculus
Length of output: 4243
🏁 Script executed:
# Search for how tournament.start_date is handled elsewhere
rg "tournament.start_date" front_end/src --type ts --type tsx -B2 -A2 | head -50Repository: Metaculus/metaculus
Length of output: 90
🏁 Script executed:
rg "tournament.start_date" front_end/src -B2 -A2 | head -80Repository: Metaculus/metaculus
Length of output: 6729
🏁 Script executed:
# Check how the dates are formatted and used in the component
sed -n '44,80p' front_end/src/app/\(main\)/\(tournaments\)/tournament/components/active_tournament_timeline.tsxRepository: Metaculus/metaculus
Length of output: 1419
🏁 Script executed:
# Check if there are any timezone conversions or locale handling
rg "getYear|format\(" front_end/src/app/\(main\)/\(tournaments\)/tournament/components/active_tournament_timeline.tsx -B1 -A1Repository: Metaculus/metaculus
Length of output: 920
🏁 Script executed:
sed -n '44,100p' front_end/src/app/\(main\)/\(tournaments\)/tournament/components/active_tournament_timeline.tsxRepository: Metaculus/metaculus
Length of output: 2359
🏁 Script executed:
# Check the complete file to see how formatString is used
sed -n '75,120p' front_end/src/app/\(main\)/\(tournaments\)/tournament/components/active_tournament_timeline.tsxRepository: Metaculus/metaculus
Length of output: 1904
🏁 Script executed:
# Check if there's any UTC or timezone conversion happening
rg "UTC|timezone|toISOString|utc" front_end/src/app/\(main\)/\(tournaments\)/tournament/components/active_tournament_timeline.tsxRepository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# Search for how timestamps are created/stored in the backend
rg "latestScheduledCloseTimestamp|start_date" front_end/src/types --type ts -B1 -A1 | head -30Repository: Metaculus/metaculus
Length of output: 397
🏁 Script executed:
# Check if there are any other similar year comparisons in the codebase
rg "getYear.*new Date" front_end/src --type ts --type tsx | head -20Repository: Metaculus/metaculus
Length of output: 90
🏁 Script executed:
# Check if dates are ever handled with UTC explicitly
rg "Date\.UTC\|utc\|toUTC\|getUTC" front_end/src --type ts --type tsx | head -20Repository: Metaculus/metaculus
Length of output: 90
🏁 Script executed:
# Verify if this is truly a server component by checking imports and component signature
head -25 front_end/src/app/\(main\)/\(tournaments\)/tournament/components/active_tournament_timeline.tsxRepository: Metaculus/metaculus
Length of output: 943
🏁 Script executed:
rg "format.*new Date\|getYear" front_end/src/utils/formatters --type ts -B2 -A2Repository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# Check backend to understand what timezone the dates/timestamps use
find backend -name "*.py" -type f | head -5Repository: Metaculus/metaculus
Length of output: 105
🏁 Script executed:
# Search for any documentation about date handling
rg "timezone\|UTC\|server.*time" . --type md | head -20Repository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# Check how formatDate is used in other server components
rg "formatDate.*locale" front_end/src/app --type ts -B1 -A1 | head -30Repository: Metaculus/metaculus
Length of output: 3048
🏁 Script executed:
# Check if there's a "use client" directive in the file
head -30 front_end/src/app/\(main\)/\(tournaments\)/tournament/components/active_tournament_timeline.tsx | grep -i "use client"Repository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# Check if dates passed to the component are ISO strings (UTC) or local strings
rg "Tournament\|latestScheduledCloseTimestamp" front_end/src/types/projects.ts -B3 -A3Repository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# Search for documentation or comments about date handling/timezone
rg "timezone|UTC|local.*time" front_end/src --type ts | head -20Repository: Metaculus/metaculus
Length of output: 2311
🏁 Script executed:
# Check how the component is called to understand the data flow
rg "ActiveTournamentTimeline" front_end/src --type ts -B2 -A2 | head -40Repository: Metaculus/metaculus
Length of output: 2251
🏁 Script executed:
# Check the Tournament type more completely
rg "type Tournament|interface Tournament" front_end/src/types --type ts -A 20 | head -50Repository: Metaculus/metaculus
Length of output: 2971
🏁 Script executed:
# Check how dates come from the API/backend
rg "latestScheduledCloseTimestamp" front_end/src --type ts -B3 -A3 | head -40Repository: Metaculus/metaculus
Length of output: 4688
🏁 Script executed:
# Verify date-fns getYear behavior with a quick test
node <<'EOF'
const { getYear } = require('date-fns');
// Test 1: ISO string UTC
const date1 = new Date('2024-12-31T23:00:00Z');
console.log('ISO string 2024-12-31T23:00Z:', getYear(date1));
// Test 2: ISO string UTC (next day)
const date2 = new Date('2025-01-01T04:00:00Z');
console.log('ISO string 2025-01-01T04:00Z:', getYear(date2));
// Show what a Date object represents
console.log('Date object for 2024-12-31T23:00:00Z:', date1.toString());
console.log('Date object for 2025-01-01T04:00:00Z:', date2.toString());
EOFRepository: Metaculus/metaculus
Length of output: 901
🏁 Script executed:
# Find getTimestampFromDateString to understand date format/timezone
rg "getTimestampFromDateString" front_end/src --type ts -B2 -A5 | head -40Repository: Metaculus/metaculus
Length of output: 4343
🏁 Script executed:
# Check if there's any server timezone configuration
rg "process.env\|TZ\|timezone" front_end/src --type ts | grep -i "tz\|timezone\|env" | head -20Repository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# See how dates are parsed and what format they're in
rg "new Date\(" front_end/src/app/\(main\)/\(tournaments\)/tournament/components/tournament_timeline.tsx -B1 -A1 | head -30Repository: Metaculus/metaculus
Length of output: 182
🏁 Script executed:
# Check how other components handle year comparisons or date formatting
rg "getYear" front_end/src --type ts -B2 -A2 | grep -v "node_modules"Repository: Metaculus/metaculus
Length of output: 4494
🏁 Script executed:
# Verify if dates come from backend as ISO strings (which would be timezone-agnostic)
rg "start_date\|close_date" front_end/src/types/projects.ts -B1 -A1Repository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# Check if there's any date-fns timezone handling library in use (like date-fns-tz)
cat front_end/package.json | grep -i "date\|tz" | head -20Repository: Metaculus/metaculus
Length of output: 117
🏁 Script executed:
# Check if date-fns-tz is actually being used in the codebase
rg "date-fns-tz\|formatInTimeZone\|toDate.*zone" front_end/src --type ts -B1 -A1 | head -30Repository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# Check how backend dates are formatted (with or without timezone indicator)
rg "start_date\|close_date.*string" front_end/src/types/projects.ts -B2 -A2Repository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# See if there's a pattern of UTC handling elsewhere
rg "UTC\|Z\"" front_end/src --type ts | head -20Repository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# Check what format the API returns dates in - look for examples in tests or documentation
find front_end -name "*.json" -o -name "*.md" | xargs grep -l "start_date\|close_date" 2>/dev/null | head -5Repository: Metaculus/metaculus
Length of output: 200
🏁 Script executed:
# See if there's any explicit UTC parsing or timezone handling elsewhere
rg "toUTC\|UTC\|Z\'" front_end/src --type ts | head -10Repository: Metaculus/metaculus
Length of output: 157
🏁 Script executed:
# Check if similar date comparison patterns exist and if they're addressed anywhere
rg "currentYear.*getYear\|getYear.*new Date\(\)" front_end/src --type ts -B1 -A3Repository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# Look at closed_tournament_timeline to see if it has the same pattern
sed -n '1,80p' front_end/src/app/\(main\)/\(tournaments\)/tournament/components/closed_tournament_timeline.tsxRepository: Metaculus/metaculus
Length of output: 2862
🏁 Script executed:
# Check what timezone the server runs in or if there's any documentation
find . -name "*.md" -o -name "*.env*" -o -name "next.config.*" | xargs grep -i "tz\|timezone" 2>/dev/null | head -10Repository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# Verify if dates from backend are indeed ISO strings (which are timezone-independent)
rg "2024\|2025" front_end/messages --type json | head -5Repository: Metaculus/metaculus
Length of output: 45
🌐 Web query:
date-fns getYear timezone behavior UTC local time
💡 Result:
date-fns/getYear(date) returns the calendar year in the runtime’s local (system) time zone, because date-fns operates on plain JavaScript Date objects and (effectively) uses Date.prototype.getFullYear() semantics (year “according to local time”). [1], [2]
What this means in practice
- A JS
Daterepresents an instant in time, butgetFullYear()interprets that instant in the machine’s local time zone. So if your instant is near midnight UTC, converting to local time can push it into the previous/next day/year, changing the year returned bygetYear. [2] - If you want the UTC year, use
Date.prototype.getUTCFullYear()(or the equivalent in your stack), notgetYear. [3]
If you need a specific (non-system) time zone
- With date-fns-tz, you convert between UTC instants and a target zone before extracting/formatting fields; this exists because
date-fnsreturns plainDates that “implicitly has the current system’s time zone”. [4] - In date-fns v4+, you can provide a time-zone “context” using
tz(...)from@date-fns/tzso date-fns functions compute in that zone instead of the system zone. [5]
Sources: [1] [2] [3] [4] [5]
🏁 Script executed:
# Check if there are any comments or TODOs about timezone handling
rg "TODO\|FIXME\|timezone\|utc" front_end/src/app/\(main\)/\(tournaments\)/tournament/components/ --type tsRepository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# Look at how the component is actually used and if user timezone info is available
rg "next-intl.*timezone\|useTimeZone\|getTimeZone" front_end/src --type ts | head -10Repository: Metaculus/metaculus
Length of output: 45
🏁 Script executed:
# Check if dates in the backend are consistently UTC (look for patterns)
rg "datetime\|timestamp" front_end/src/types/projects.ts -B1 -A1 | head -30Repository: Metaculus/metaculus
Length of output: 45
Year comparison uses server's local timezone; clarify intended reference for consistency.
getYear(new Date()) interprets dates according to the server's local timezone (not UTC). While all dates in this component are processed consistently, the year comparison result depends on the server's deployment timezone. If dates should be compared in UTC or a specific locale, use getUTCFullYear() or date-fns-tz (already installed) to ensure the formatting logic is timezone-explicit and independent of server configuration.
🤖 Prompt for AI Agents
In
`@front_end/src/app/`(main)/(tournaments)/tournament/components/active_tournament_timeline.tsx
around lines 44 - 50, The year comparison relies on getYear(new Date()) which
uses the server's local timezone; make the intent explicit by computing years in
UTC (or a specific timezone) instead: replace getYear(new Date()), getYear(new
Date(tournament.start_date)), and getYear(new
Date(latestScheduledCloseTimestamp)) with UTC-based year extraction (e.g., new
Date(...).getUTCFullYear()) or, if you need a particular zone, convert dates
with date-fns-tz (utcToZonedTime) and then extract the year; update the
currentYear, startYear, closeYear and consequently formatString logic to use
these UTC/zone-aware year values.
🧹 Preview Environment Cleaned UpThe preview environment for this PR has been destroyed.
Cleanup triggered by PR close at 2026-01-23T14:47:27Z |
Summary
Updated tournament timeline components to display the year in dates when the tournament dates differ from the current year.
Previously, years were only shown when start and end dates were in different years, which meant past tournaments didn't show the year.
Fixes #4054
Generated with Claude Code
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.