chrisphan.com

Happy ISO Week-Date New Year!

An analog clock reading 2:202024-12-30 / 2025-W01-1T14:20:00-06:00 / 0x67730070

Categories: computers, fun, programming

Happy New Year!

Of course, under the Gregorian calendar, the year doesn't start until Wednesday. But under the ISO week date calendar, today is the first day of 2025.

In our familiar Gregorian calendar, a year either has 365 or 366 days, split into 12 months, each of which has between 28 and 31 days. In the ISO week date calendar, a year is split into 52 or 53 weeks, each of which starts on Monday and has seven days.

Today's date in the ISO week date calendar is 2025-W01-1, i.e., the first day (Monday) of the first week of 2025.

Here are some other example dates in the ISO week date calendar:

Typical American rendering ISO Gregorian ISO week date
Monday, December 30, 2024 2024-12-30 2025-W01-1
Tuesday, December 29, 1998 1998-12-29 1998-W53-2
Wednesday, October 21, 2015 2015-10-21 2015-W43-3
Thursday, February 3, 1983 1983-02-03 1983-W05-4
Friday, April 22, 2005 2005-04-22 2005-W16-5
Saturday, July 11, 2020 2020-07-11 2020-W28-6
Sunday, January 3, 2010 2010-01-03 2009-W53-7

In the ISO week date calendar, every week (starting on Monday and ending on Sunday) is in the same year. For most weeks, the entire week is in the same Gregorian year, so it is assigned to that year in the ISO week date calendar. However, any week containing both December 31 and January 1 (such as the current week) will be split between two Gregorian years. These weeks are assigned to the year with the most days in that week. For example, our current week has two days in 2024 (Monday and Tuesday), and five days in 2025 (Wednesday through Sunday), so in the ISO week date calendar, this is the first week of 2025. (Equivalently, each week is assigned to the same ISO week date year as the Gregorian year of its Thursday.)

Today is an example of a day whose ISO week date year is ahead of its Gregorian year. On the other hand, on the table above, we see that January 3, 2010 is assigned to 2009.

There are many ways to get the current ISO week date, or convert between Gregorian and week date. For example, at any Unix or Unix-like shell, you can do this:

Bash
date +%G-W%V-%u
2025-W01-1

For most interfaces that understand strptime/strftime codes, like the version of date on my Mac, %G is the ISO week date year, %V is the ISO week date week, and %u is the day of the week. For example, in Python:

Python (REPL)
from datetime import date
date.strftime(date.today(), "%G-W%V-%u")
'2025-W01-1'

Python's datetime.date objects have methods to convert between Gregorian and ISO week date:

Python (REPL)
from datetime import date
date(1983, 2, 3).isocalendar()
datetime.IsoCalendarDate(year=1983, week=5, weekday=4)
date.fromisocalendar(2025, 23, 7)
datetime.date(2025, 6, 8)

The Unix command ncal can be used to print a calendar with week numbers:

Bash
ncal -w 5 2025
    May 2025
Mo     5 12 19 26
Tu     6 13 20 27
We     7 14 21 28
Th  1  8 15 22 29
Fr  2  9 16 23 30
Sa  3 10 17 24 31
Su  4 11 18 25
   18 19 20 21 22

And I wrote a Python program that prints nice year calendars with ISO week numbers:

Bash
isocal -y 2025

                                     2025
                            ISO week-date calendar
Wk Mo Tu We Th Fr Sa Su   │Wk Mo Tu We Th Fr Sa Su   │Wk Mo Tu We Th Fr Sa Su
01 30 31│ 1  2  3  4  5   │   ────────┘              │37  8  9 10 11 12 13 14
   ─────┘                 │19  5  6  7  8  9 10 11   │38 15 16 17 18 19 20 21 S
02  6  7  8  9 10 11 12   │20 12 13 14 15 16 17 18 M │39 22 23 24 25 26 27 28
03 13 14 15 16 17 18 19 J │21 19 20 21 22 23 24 25   │        ┌───────────────
04 20 21 22 23 24 25 26   │                    ┌───  │40 29 30│ 1  2  3  4  5
                 ┌──────  │22 26 27 28 29 30 31│ 1   │   ─────┘
05 27 28 29 30 31│ 1  2   │   ─────────────────┘     │41  6  7  8  9 10 11 12
   ──────────────┘        │23  2  3  4  5  6  7  8   │42 13 14 15 16 17 18 19 O
06  3  4  5  6  7  8  9   │24  9 10 11 12 13 14 15 J │43 20 21 22 23 24 25 26
07 10 11 12 13 14 15 16 F │25 16 17 18 19 20 21 22   │                 ┌──────
08 17 18 19 20 21 22 23   │26 23 24 25 26 27 28 29   │44 27 28 29 30 31│ 1  2
                 ┌──────  │     ┌──────────────────  │   ──────────────┘
09 24 25 26 27 28│ 1  2   │27 30│ 1  2  3  4  5  6   │45  3  4  5  6  7  8  9
   ──────────────┘        │   ──┘                    │46 10 11 12 13 14 15 16 N
10  3  4  5  6  7  8  9   │28  7  8  9 10 11 12 13   │47 17 18 19 20 21 22 23
11 10 11 12 13 14 15 16 M │29 14 15 16 17 18 19 20 J │48 24 25 26 27 28 29 30
12 17 18 19 20 21 22 23   │30 21 22 23 24 25 26 27   │   ─────────────────────
13 24 25 26 27 28 29 30   │              ┌─────────  │49  1  2  3  4  5  6  7
     ┌──────────────────  │31 28 29 30 31│ 1  2  3   │50  8  9 10 11 12 13 14
14 31│ 1  2  3  4  5  6   │   ───────────┘           │51 15 16 17 18 19 20 21 D
   ──┘                    │32  4  5  6  7  8  9 10   │52 22 23 24 25 26 27 28
15  7  8  9 10 11 12 13   │33 11 12 13 14 15 16 17 A │           ┌────────────
16 14 15 16 17 18 19 20 A │34 18 19 20 21 22 23 24   │01 29 30 31│ 1  2  3  4
17 21 22 23 24 25 26 27   │35 25 26 27 28 29 30 31   │   ────────┘
           ┌────────────  │   ─────────────────────  │
18 28 29 30│ 1  2  3  4   │36  1  2  3  4  5  6  7   │
Wk Mo Tu We Th Fr Sa Su   │Wk Mo Tu We Th Fr Sa Su   │Wk Mo Tu We Th Fr Sa Su

I really should release the source code for this.

Happy New Year!