whence

By Steph11
Scroll to open

whence

It parses the dates people actually type. "next tuesday". "in 3 weeks". "end of the month". "18/03" with no year, from a user whose locale you are only guessing at. Seven years of getting that wrong in public, written down in order, because the interesting part of a date library is never the parsing. It is the corrections.

Why This Page Is A Timeline

Most of what you need to know about a date library is historical. Which version silently changed how it resolves an ambiguous day. Which one broke across a DST boundary and only in the southern hemisphere. Which one you are pinned to and why somebody on your team wrote "do not upgrade" next to it in 2023. Feature lists cannot tell you that. A list of dated mistakes can.

The first three years01.04.2019 – 01.10.2021
01.04.2019v0.1.0. Parsed six English phrases. Written for one internal form. Published mostly by accident.
01.04.2019
01.11.2019v0.6.0. First bug report from a stranger. "next friday" on a Friday returned today. It still divides people.
01.11.2019
01.02.2020v0.9.0. Locale support added badly. Day-first and month-first were decided by a regex on the string.
01.02.2020
01.07.2020v1.0.0. That regex was removed. Locale became a required argument. First breaking change and the right one.
01.07.2020
01.03.2021v1.4.0. "end of the month" landed on the 30th in February. Live for 11 days. Nobody noticed until March.
01.03.2021
01.10.2021v1.6.0. Timezone handling moved off the host clock. Three years of latent bugs closed in one release.
01.10.2021

The Two That Actually Cost Something

Everything above was embarrassing. The two entries below were worse than that, because they reached people who were not developers and had no idea a library was involved. Both are described here at more length than is comfortable. A changelog that quietly drops its worst day is a changelog that has learned nothing and is teaching nobody.

The two that cost something27.03.2022 – 17.09.2023
27.03.2022v2.1.0. DST. "tomorrow at 9" resolved to 08:00 across a spring-forward boundary in Europe.
27.03.2022
27.03.2022Live for 5 days. A booking product shipped it on the Friday. Monday was a lot of missed appointments.
27.03.2022
01.04.2022v2.1.1. Fixed by holding wall-clock intent and resolving the zone last. The rule the library should always have had.
01.04.2022
14.09.2023v2.6.0. Southern hemisphere DST inverted. Same class of bug, opposite sign, missed by every test we had.
14.09.2023
16.09.2023Found by a user in Auckland who wrote the clearest bug report this project has ever received.
16.09.2023
17.09.2023v2.6.1. Test suite now runs in 14 timezones on every commit. That is the actual fix.
17.09.2023

Releases

61

Releases that changed behaviour without saying so

3

Longest a known bug stayed live

11 days

Timezones in CI

14

Distinct people who have reported a real bug

88

"

Your tests pass because they all run north of the equator. Mine is the half of the world where the clock goes the other way.

"

from the Auckland bug report on issue 402

Since then01.01.2024 – 01.02.2026
01.01.2024v3.0.0. Breaking. Ambiguous input now returns a range rather than a guess. The most requested and most argued change.
01.01.2024
01.08.2024v3.2.0. "in 3 weeks" now respects the caller's week start. Reported by a Danish team in 2020.
01.08.2024
01.05.2025v3.5.0. Nothing broke. 14 months without a behaviour regression is the current record.
01.05.2025
01.02.2026v3.7.0. Deprecated the last function that reads the host clock implicitly. Removal scheduled for v4.
01.02.2026

What Changed In How We Work

None of the fixes above were the real fix. The real fixes were structural and there are three: locale is a required argument rather than a guess, the test suite runs in fourteen timezones on every commit rather than in the maintainer's own, and ambiguous input returns a range instead of a confident wrong answer. Every one of those was forced by a bug that had already shipped.

If you are upgrading

0%

Read the entry for every version between yours and the target. All of them

Pin exactly. Caret ranges on a date library are how the 2022 DST bug spread

If you are on v2, the v3 range return is the only breaking change that matters

Run your own suite in at least two timezones before you believe any of this

If you find something, the Auckland report is the template. It is linked below