when-am-i / files / src / utils / eras.ts
eras.ts
a71096e6 2026-06-18 Pavel Safronov | 1 | // Era matching: which eras cover a given date. |
| 2 | ||
| 3 | import type { Era, HistoricalDate } from '../types'; | |
| 4 | import { gregorianToJulianDay, parseGregorianDate } from './julianDay'; | |
| 5 | ||
| 6 | /** | |
| 7 | * All eras whose date range covers `date`, using the half-open interval | |
| 8 | * [start, end): a null start is the open past, a null end is the open present. | |
| 9 | * | |
| 10 | * Eras MAY overlap in time (parallel calendars coexisting at the same place and | |
| 11 | * time), so this returns every match, not the first one (see plan.md, Q4). | |
| 12 | */ | |
| 13 | export function findEras(date: HistoricalDate, eras: Era[]): Era[] { | |
| 14 | const t = gregorianToJulianDay(date); | |
| 15 | return eras.filter((era) => { | |
| 16 | const afterStart = era.start === null || gregorianToJulianDay(parseGregorianDate(era.start)) <= t; | |
| 17 | const beforeEnd = era.end === null || t < gregorianToJulianDay(parseGregorianDate(era.end)); | |
| 18 | return afterStart && beforeEnd; | |
| 19 | }); | |
| 20 | } |