Skip to content

Natural-language compatibility review ​

This review covers the supplied English/French examples and all eight edtfy test files, including its disabled shared-component collection examples. Selected edtfy examples are credited to Nicolas Barbotte (MIT). We use the examples to identify syntax gaps; their older EDTF outputs are not a conformance oracle.

The tables are generated by node packages/natural/scripts/generate-compatibility.cjs. The phrase expectations live in packages/natural/tests/fixtures/compatibility.json and are enforced by compatibility.test.ts. English numeric examples use en-US, French uses fr-FR, and rolling short years use January 1, 2026. All alternatives are checked, in confidence order. Separate shared fixtures and round-trip tests cover Spanish and all six regional locale presets.

Corrected patterns ​

  • A known day survives an unspecified month: 1870-XX-12 renders as 12th of unknown month, 1870, día 12 de mes desconocido, 1870, or 12 d'un mois inconnu, 1870. These phrases parse back without losing the day.
  • Dates and seasons share interval endpoints: march 1988 - spring 1990 becomes 1988-03/1990-21. This is a supported extension, excluded by the optional strict interoperability profile. Reversed intervals are rejected. Season calendar bounds remain application conventions.
  • French De … à …, articles, and apostrophe contractions work with shared date semantics. Season qualifiers work before or after the season. Century-wide qualifiers apply to both boundaries.
  • Missing-year forms, semicolon lists, short range end years, ordinal/roman centuries, selected abbreviations, and validated weekday prefixes have regression coverage. January 12 produces only XXXX-01-12; January 0012 selects the historical month/year.

Modern EDTF distinctions ​

The current LOC specification replaced u with X, combined ?~ into %, and replaced interval keywords with empty/.. endpoints. We do not accept obsolete literal spellings as modern EDTF.

Since 1970 means 1970/..; an unknown end is 1970/ and renders explicitly as unknown. 20th century means 1901/2000, whereas 19XX covers 1900–1999. January 1999 to December 1999 is an interval, not a synonym for the unspecified month 1999-XX. 2020; 2021 is an inclusive list, {2020,2021}; bare 2020,2021 is not valid EDTF. Strict event-date cutoffs use sets and exclude the cutoff unit. Fuzzy cutoff phrases remain errors.

Bare one- or two-digit years require an era marker or four-digit spelling: write 90 CE or 0090 for year 90. Write 1990 explicitly or use '90 for the rolling window. Short end years in a range inherit the start century, advancing to the next century if necessary: 1851-52 → 1851/1852. Valid literal EDTF takes precedence: 1851-12 remains December 1851.

Preferred rendering equivalents ​

These are our preferred phrases for the valid modern equivalents of the supplied rendering examples. Exact wording and capitalization may differ; tests check the meaning after parsing the preferred rendering. Storage should retain EDTF, because display options can suppress qualifiers or eras.

EDTFEnglishFrenchSpanish
1975-07-01July 1, 19751 juillet 19751 de julio de 1975
1975?1975 (uncertain)1975 (incertain)1975 (incierto)
1975-22Summer 1975été 1975verano 1975
199X1990sLes années 1990Los años 1990
19XX1900s19XX19XX
1970/19801970 to 19801970 à 19801970 a 1980
1970/..1970 to open end1970 à fin ouverte1970 a fin abierto
1970/1970 to unknown1970 à inconnu1970 a desconocido
1970~/1980~1970 (approximate) to 1980 (approximate)1970 (approximatif) à 1980 (approximatif)1970 (aproximado) a 1980 (aproximado)
1999-XXsome month in 1999un mois de 1999algún mes de 1999
{2020,2021}All of: 2020, 2021Toutes ces dates: 2020 et 2021Todas estas fechas: 2020 y 2021
1870-XX-1212th of unknown month, 187012 d'un mois inconnu, 1870día 12 de mes desconocido, 1870

Phrase-by-phrase results ​

LocaleInputEDTF candidates / decisionExplanation / source
en-USJuly 1, 19751975-07-01
en-US1975?1975?
en-USsummer 19751975-22
en-US1990s199X
en-US20th century1901/2000Numbered centuries use historical boundaries; 19XX covers 1900–1999 instead.
en-US1970 to 19801970/1980
en-USsince 19701970/..An open endpoint is distinct from the unknown endpoint in 1970/.
en-UScirca 1970 to circa 19801970~/1980~
en-USJanuary 1999 to December 19991999-01/1999-12An explicit interval is not the unspecified month 1999-XX.
en-US2020; 2021{2020,2021}An inclusive list uses braces; adjacent years compact.
en-USJanuary 12, 19401940-01-12
en-US90RejectedA bare one- or two-digit year requires an era marker or four-digit spelling.
en-US'901990
en-USJanuary 20082008-01
en-USthe year 18001800
en-US10/7/20082008-10-07; 2008-07-10US ordering ranks first; both valid interpretations survive.
en-US1860?1860?
en-US1862 (uncertain)1862?
en-UScirca Feb 18121812-02~
en-USc.18601860~
en-USca18601860~
en-USapprox 18601860~
en-USca. 1860s186X~
en-UScirca 1840s184X~
en-USca. 1860s?186X%Modern EDTF combines uncertainty and approximation as %.
en-USc1800s?18XX%; 180X%Both century-block and decade readings remain ambiguous; a qualifier does not disambiguate them.
en-USJanuary 12XXXX-01-12A month and day without a year. Write January 0012 for the historical year.
en-USJanuaryXXXX-01
en-US7/20082008-07
en-USmonth in 18721872-XX
en-USday in January 18721872-01-XX
en-USday in 18721872-XX-XX
en-USAutumn 18721872-23
en-USFall 18721872-23
en-USearlier than 1928[..1927]Strict event-date cutoff excludes 1928; it is a date-choice set.
en-USlater than 1928[1929..]Strict event-date cutoff excludes 1928.
en-USbefore January 1928[..1927-12]Strict cutoff shifts one month.
en-USafter about the 1920sRejectedA fuzzy cutoff has no exact exclusive boundary; use an exact cutoff or literal EDTF with the intended meaning.
en-US1st century0001/0100Historical century boundaries differ from 00XX.
en-US10c0901/1000
en-US19th century?1801?/1900?The qualification applies to both boundaries of the century.
en-USa day in about Spring 1849?RejectedEDTF has no day component on a season: 1849-21-XX is invalid. Use circa Spring 1849? (1849-21%) if season precision is sufficient, or specify calendar dates.
en-US1851-18521851/1852
en-US1851-1852; printed 1853-1854RejectedBibliographic event annotations are not date syntax. The parser rejects the whole input instead of discarding the printing date.
en-US1851-521851/1852
en-US1856-ca. 18651856/1865~
en-US1860s-1870s1860/1879Interval endpoints expand the decade start/end according to the existing parsing convention.
en-US1920s - early 1930s1920/1933The early-decade convention retains the explicit early modifier.
en-US1938, printed 1940s-1950sRejectedNo silent truncation of annotated prose; parse each intended event separately.
en-US12th of unknown month, 18701870-XX-12
en-USmarch 1988 - spring 19901988-03/1990-21
fr-FR1 Juillet 19751975-07-01
fr-FR1975?1975?
fr-FRété 19751975-22
fr-FRLes années 1990199X
fr-FR20e siècle1901/2000Numbered centuries are not equivalent to 19XX.
fr-FRDe 1970 à 19801970/1980
fr-FRDepuis 19701970/..Open, not unknown, end.
fr-FRDe 1970 environ à 1980 environ1970~/1980~
fr-FRDe Janvier 1999 à Décembre 19991999-01/1999-12Preserves explicit interval phrasing.
fr-FR2020; 2021{2020,2021}
en-USmar the 29 19881988-03-29edtfy test
en-USbet the 03/28/1988 and the 03/30/19881988-03-28/1988-03-30edtfy test
fr-FRle 29 mar 19881988-03-29edtfy test
fr-FRdu 28 mars 1988 au 30/03/19881988-03-28/1988-03-30edtfy test
en-USmonday 03/29/1988RejectedMarch 29, 1988 was Tuesday; weekdays must match. edtfy test
fr-FRjeudi 29/03/1988RejectedThe weekday contradicts the date. edtfy test
en-USfrom sep 1988 to 04/30/1988RejectedReversed intervals are invalid. edtfy test
en-USmarch 1988 - winter 2005?1988-03/2005-24?edtfy test
en-USfrom around sep 10 1988? to unknown1988-09-10%/edtfy test
fr-FRenviron l'hiver 1988?1988-24%edtfy test
fr-FR1988 - en cours1988/..edtfy test
en-USXIXth century1801/1900edtfy test
fr-FRXVIIIème siècle1701/1800edtfy test
fr-FRIV siecle0301/0400edtfy test
fr-FR2nd siècle après JC0101/0200edtfy test
en-US12th March 24BC-0023-03-12edtfy test
fr-FRprintemps 4AEC-0003-21edtfy test
en-USbf. 1988[..1987]edtfy test
fr-FRap. 1988[1989..]edtfy test
en-US<1988[..1987]edtfy test
fr-FR>1988[1989..]edtfy test
en-US198uRejectedLegacy u masks are not modern EDTF. Use 198X. edtfy test
fr-FR11/0u/1988RejectedLegacy slash masks are intentionally unsupported. Use modern EDTF 1988-0X-11. edtfy test
en-US11/10/21988RejectedThe selected EDTF profile supports extended years as year-only values, not extended full calendar dates. edtfy test

Remaining scope differences ​

The upstream tests include incorrect weekdays and reversed intervals; we reject them. Weekday prefixes constrain the full calendar date instead of being discarded. Draft u/* slash masks should be converted explicitly to modern EDTF with X; extended years remain year-only in the selected profile.

Shared-component collection syntax such as spring or summer 2015 and April 1 or 2 2015 remains outside this change (these cases are disabled in edtfy's suites). Use explicit members, such as One of: spring 2015, summer 2015 or One of: April 1, 2015, April 2, 2015. A future extension needs contextual component propagation through all collection members and language-specific word order, rather than guessing a year from the last number.

Bibliographic event labels such as printed are not discarded. Parse each event separately so dates and event roles are retained. A day within an approximate season cannot be encoded by appending -XX to a season code; use season precision if sufficient, or explicit calendar dates. No broad text-stripping or obsolete-EDTF compatibility mode was added.

Released under the MIT License.