TL;DR 2026 is a 53 week year (ISO 8601). If anything in your stack assumes a year has 52 weeks a % 52, a fixed length array, a chart axis, a weekly aggregation it has a latent bug that this year will trigger. Don't hard code 52. Here's how to spot it and fix it.
Quick gut check before you read on: how many weeks are in a year?
If you answered 52, you're right about 80% of the time. The other 20% of the time there are 53, and the code that assumed 52 does something quietly wrong drops a week of data, wraps a counter, throws an index error, or labels two different weeks with the same number. 2026 is one of those years, which makes this a good moment to go find that bug before it finds you.
Wait, how can a year have 53 weeks?
ISO 8601 weeks start on Monday, and a week belongs to whichever year holds its Thursday. Stack 52 of those and you get 364 days one short of a normal year, two short of a leap year. That leftover day accumulates, and every so often the calendar pays off its debt with a 53rd week.
Mechanically, a year gets 53 ISO weeks when January 1st falls on a Thursday, or on a Wednesday in a leap year. That works out to roughly once every five or six years:
... 2015, 2020, 2026, 2032, 2037 ...
2026 qualifies because January 1st, 2026 is a Thursday. So this year runs Monday weeks 1 through 53, and the calendar genuinely has a covers it if you want the full mechanics.)
Detecting a 53-week year in code
You don't need a lookup table. There's one date that is always in the final ISO week of its year: December 28th. So the week number of December 28th tells you how many weeks the year has:
function isoWeek(date) {
const d = new Date(date);
d.setHours(0, 0, 0, 0);
// jump to the Thursday of this ISO week
d.setDate(d.getDate() + 3 - ((d.getDay() + 6) % 7));
const week1 = new Date(d.getFullYear(), 0, 4);
return 1 + Math.round(
((d - week1) / 86400000 - 3 + ((week1.getDay() + 6) % 7)) / 7
);
}
function weeksInYear(year) {
return isoWeek(new Date(year, 11, 28)); // Dec 28 -> last week of the year
}
weeksInYear(2025); // 52
weeksInYear(2026); // 53
weeksInYear(2027); // 52
Most date libraries ship this too reach for their getISOWeeksInYear-style helper rather than rolling your own, and pull the week-numbering year from the library instead of the plain calendar year.
Fixing it without playing whack-a-mole
The fix is the same idea everywhere: stop treating 52 as a constant. Concretely:
- Size structures dynamically:
new Array(weeksInYear(year)), notnew Array(52). - Drop the
% 52. If you're bucketing by week, key on the{isoYear, isoWeek}pair so week 53 and the next year's week 1 can never collide. - For YoY comparisons, align on the ISO week label, and decide explicitly what to do with the orphan 53rd week (carry it, or compare W53 against the prior year's W52 - just make it a deliberate choice).
- Add a test that runs your week logic against a known 53-week year. 2026 and 2020 are free test fixtures.
test("handles 53-week years", () => {
expect(weeksInYear(2026)).toBe(53);
expect(bucketsFor(2026)).toHaveLength(53); // not 52
});
If you want a CI canary, a one-line guard that logs when the current year has 53 weeks is a cheap way to get a heads-up the next time this rolls around (2032).
When you'd rather not own the logic at all
For a lot of cases - a status badge, a Slack reminder, a report header, a cron that needs "is this a long year?" - shipping date arithmetic is more risk than it's worth. There's a free, no-key JSON API that returns the week info for any date, and it hands you the 53-week answer as a plain boolean so you don't have to derive it:
const res = await fetch("https://weekisit.com/api/week");
const data = await res.json();
data.iso_week; // 22
data.total_weeks_in_year; // 53
data.is_53_week_year; // true <-- the whole problem, as one field
That is_53_week_year flag is doing exactly the job of the weeksInYear function above, minus the maintenance. The is worth a read before you hard-code anything.
Takeaways
- 2026 has 53 ISO weeks. The previous one was 2020; the next is 2032.
- A year has 53 weeks when Jan 1 is a Thursday (or a Wednesday in a leap year).
- Never treat 52 as a constant: no
% 52, no fixed 52-length structures, no naive YoY alignment. - Bucket by the
{isoYear, isoWeek}pair so week 53 never collides with anyone's week 1. - Test against 2026 and 2020, or offload the question entirely with a single
is_53_week_yearboolean.
Week numbers feel like the most boring possible part of date handling, right up until a 53-week year turns a one-character assumption into a year-end incident. Spend ten minutes grepping your codebase for 52 this week. Future-you, sometime around late December, will be grateful.
SOCIAL SHARE CARD GENERATOR