![whence](https://cdn.slatesource.com/b/c/0/bc050038-bfc2-434e-856d-9f50e7e8de4e.webp)

# whence

- [Made in Slatesource](https://slatesource.com/@steph/whence)
- By [Steph](https://slatesource.com/@steph)
- Created on Aug 5, 2026

## whencewhence

It parsesparses the datesdates peoplepeople actuallyactually typetype. "nextnext tuesdaytuesday". "in 3 weeksweeks". "endend of the monthmonth". "18/03" with no yearyear, from a useruser whosewhose localelocale you are only guessingguessing at. SevenSeven yearsyears of gettinggetting that wrongwrong in publicpublic, writtenwritten downdown in orderorder, becausebecause the interestinginteresting partpart of a datedate librarylibrary is nevernever the parsingparsing. It is the correctionscorrections.

## Why This PagePage Is A TimelineTimeline

MostMost of what you needneed to knowknow about a datedate librarylibrary is historicalhistorical. WhichWhich versionversion silentlysilently changedchanged how it resolvesresolves an ambiguousambiguous dayday. WhichWhich oneone brokebroke acrossacross a DSTDST boundaryboundary and only in the southernsouthern hemispherehemisphere. WhichWhich oneone you are pinnedpinned to and why somebodysomebody on your teamteam wrotewrote "do not upgradeupgrade" nextnext to it in 20232023. FeatureFeature listslists cannotcannot telltell you that. A listlist of dateddated mistakesmistakes 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 TwoTwo That ActuallyActually CostCost SomethingSomething

EverythingEverything aboveabove was embarrassingembarrassing. The twotwo entriesentries belowbelow were worseworse than that, becausebecause they reachedreached peoplepeople who were not developersdevelopers and had no ideaidea a librarylibrary was involvedinvolved. BothBoth are describeddescribed herehere at moremore lengthlength than is comfortablecomfortable. A changelogchangelog that quietlyquietly dropsdrops its worstworst dayday is a changelogchangelog that has learnedlearned nothingnothing and is teachingteaching nobodynobody.

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.

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 ChangedChanged In How We WorkWork

NoneNone of the fixesfixes aboveabove were the realreal fixfix. The realreal fixesfixes were structuralstructural and therethere are threethree: localelocale is a requiredrequired argumentargument ratherrather than a guessguess, the testtest suitesuite runsruns in fourteenfourteen timezonestimezones on everyevery commitcommit ratherrather than in the maintainer'smaintainer's ownown, and ambiguousambiguous inputinput returnsreturns a rangerange insteadinstead of a confidentconfident wrongwrong answeranswer. EveryEvery oneone of those was forcedforced by a bugbug that had alreadyalready shippedshipped.

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

[Issue 402, the best bug report this project has had](https://github.com/whence-dev/whence/issues/402?utm_source=slatesource)

[whence on npm](https://www.npmjs.com/package/whence?utm_source=slatesource)