https://www.zachleat.com/web/adventures-in-date-parsing/ Skip to Content Zach's ugly mug (his face) Zach Leatherman Home About Uses Archives Search Talks Eleventy @zachleat on GitHub @zachleat@zachleat.com on Mastodon @zachleat.com on Mastodon RSS IndieWeb Avatar for https://www.11ty.dev/ 2007 Sparkline representing frequency of posts written from 2007 to 2025 2025 Popular Never write your own Date Parsing Library 3 days A Comprehensive Guide to Font Loading Strategies 9 years BigText Makes Text Big 14.5 years Never write your own Date Parsing Library Dresser top with mini calendar of September and potted plant July 23, 2025 Never write your own date parsing library. Never. No exceptions. [S:Never have I ever...:S] So... I've written my own date parsing library. Why? Our story begins seven years ago in the year 2018. I made the very sensible choice to adopt luxon as the Date Parsing library for Eleventy. This parsing behavior is used when Eleventy finds a String for the date value in the Data Cascade (though YAML front matter will bypass this behavior when encountering a YAML-compatible date). This choice was good for Eleventy's Node.js-only requirements at the time: accurate and not too big (relatively speaking). Eleventy has used luxon since @0.2.12 and has grown with the dependency all the way through @3.7.1. Now that's what I call a high quality dependency! As we move Eleventy to run in more JavaScript environments and runtimes (including on the client) we've had to take a hard look at our use of Luxon, currently our largest dependency: * 4.7 MB of 21.3 MB (22%) of @11ty/eleventy node_modules * 229 kB of 806 kB (28%) of @11ty/client (not yet released!) bundle size (unminified) Given that our use of Luxon is strictly limited to the DateTime.fromISO function for ISO 8601 date parsing (not formatting or display), it would have been nice to enable tree-shaking on the Luxon library to reduce its size in the bundle (though that wouldn't have helped the node_modules size, I might have settled for that trade-off). Unfortunately, Luxon does not yet support tree-shaking so it's an all or nothing for the bundle. The Search Begins I did the next sensible thing and looked at a few alternatives: Package Type Disk Size Bundle Size luxon@3.7.1 Dual 4.59 MB 81.6 kB (min) moment@2.30.1 CJS 4.35 MB 294.9 kB (min) dayjs@1.11.13 CJS 670 kB 6.9 kB (min) date-fns@4.1.0 Dual 22.6 MB 77.2 kB (min) The next in line to the throne was clearly dayjs, which is small on disk and in bundle size. Unfortunately I found it to be inaccurate: dayjs fails about 80 of the 228 tests in the test suite I'm using moving forward. As an aside, this search has made me tempted to ask: do we need to keep Dual publishing packages? I prefer ESM over CJS but maybe just pick one? Breaking Changes Most date parsing woes (in my opinion) come from ambiguity: from supporting too many formats or attempting maximum flexibility in parsing. And guess what: ISO 8601 is a big 'ol standard with a lot of subformats. There is a maintenance freedom and simplicity in strict parsing requirements (don't let XHTML hear me say that). Consider "200". Is this the year 200? Is this the 200th day of the current year? Surprise, in ISO 8601 it's neither -- it's a decade, spanning from the year 2000 to the year 2010. And "20" is the century from the year 2000 to the year 2100. Moving forward, we're tightening up the default date parsing in Eleventy (this is configurable -- keep using Luxon if you want!). Luckily we have a north star date format: RFC 9557, billed as "an extension to the ISO 8601 / RFC 3339" formats and already in use by the upcoming Temporal web standard APIs for date and time parsing coming to a JavaScript runtime near you. There are a few notable differences: Format ISO 8601 Date.parse* luxon RFC 9557 YYYY YYYY-MM YYYY-MM-DD +-YYYYYY-MM-DD Optional - delimiters in dates YYYY-MM-DDTHH YYYY-MM-DD HH (space delimiter) YYYY-MM-DDtHH (lowercase delimiter) YYYY-MM-DDTHH:II YYYY-MM-DDTHH:II:SS Optional : delimiters in time YYYY-MM-DDTHH:II:SS.SSS YYYY-MM-DDTHH:II:SS,SSS Microseconds (6 digit precision) Nanoseconds (9 digit precision) YYYY-MM-DDTHH.H Fractional hours YYYY-MM-DDTHH:II.I Fractional minutes YYYY-W01 ISO Week Date YYYY-DDD Year Day HH:II YYYY-MM-DDTHH:II:SSZ YYYY-MM-DDTHH:II:SS+-00 YYYY-MM-DDTHH:II:SS+-00:00 YYYY-MM-DDTHH:II:SS+-0000 Unsupported Inaccurate parsing Face looking surprised Surprising (to me) * Note that Date.parse results may be browser/runtime dependent. The results above were generated from Node.js. A new challenger appears It is with a little trepidation that I have shipped @11ty/ parse-date-strings, a new RFC 9557 compatible date parsing library that Eleventy will use moving forward. The support table of this library matches the RFC 9557 column documented above. It's focused on parsing only and our full test suite compares outputs with both the upcoming Temporal API and existing Luxon output. While there are a few breaking changes when compared with Luxon output (noted above), this swap will ultimately prepare us for native Temporal support without breaking changes later! Package Type Disk Size Bundle Size @11ty/parse-date-strings@2.0.4 ESM 6.69 kB 2.3 kB (min) This library saves ~230 kB in the upcoming @11ty/client bundle. It should also allow @11ty/eleventy node_modules install weight to drop from 21.3 MB to 16.6 MB. (Some folks might remember when @11ty/ eleventy@1 weighed in at 155 MB!) Late Additions For posterity, here are a few other alternative date libraries / Temporal polyfills that I think are worth mentioning (and might help you in different ways on your own date parsing journey): Package Type Disk Size Bundle Size @js-temporal/polyfill@0.3.0 Dual 2.98 MB 186.5 kB (min) temporal-polyfill@0.3.0 Dual 551 kB 56.3 kB (min) @formkit/tempo@0.1.2 Dual 501 kB 17.3 kB (min) --------------------------------------------------------------------- Tags: Eleventy Project #1 Popular (per day) #51 Popular (total) 6,590 Views IndieWeb Avatar for https://unsplash.com/Poster image by Blessing Ri Older > How to import() a JavaScript String Zach Leatherman IndieWeb Avatar for https://zachleat.com/is a builder for the web at Font Awesome and the creator/maintainer of IndieWeb Avatar for https://www.11ty.devEleventy (11ty), an award-winning open source site generator. At one point he became entirely too fixated on web fonts. He has given 85 talks in nine different countries at events like Beyond Tellerrand, Smashing Conference, Jamstack Conf, CSSConf, and The White House. Formerly part of CloudCannon, Netlify, Filament Group, NEJS CONF, and NebraskaJS. Learn more about Zach >> * Follow on Mastodon * Follow on Bluesky * Subscribe 16 Reposts Fynn Ellie BeckerDave RupertFrontend DogmaPaul ShryockMat "Wilto" MarquisIndieWeb Avatar for https://lemmy.bestiver.seRamon Corominas Mark EriksonAlex RiviereNick NisiNicolas BouilleaudMichael Klopzig Jean Pierre KolbEleventy v3.1.2Brian LeRoux * gaytham steel (non-toxic pan gay, can cook four eggs) 49 Likes jenn schiffer ????[?]????[?]Paul Shryock[]asker the gauche, glycojohn destroyer of carbsBrent Larsonw-lfpup[]LucaDoug HankeIndieWeb Avatar for https://bsky.appSergioCarlos SolisOleksa ????????Ramon Corominas Prince WilsonzeuMark Erikson[]Nick NisimichaJonDIANAMattcastastrophe Adam WyludaJean Pierre KolbGryphonJeremias MenichelliPat ByrneTyler Combsfabian wohlgemuthStuart RutherfordDave RupertGuy Gascoigne-PiggfordCharlieEleventy v3.1.2Alex RiviereAdrian A. LorenzanaMike Hendersoncory hughartChris MChristophe MichelPatrick O& apos;BrienmoshyfawnJake LazaroffFrancis Beaudetcory hughart * gaytham steel (non-toxic pan gay, can cook four eggs)Christian "Schepp" Schaefer 16 Comments 1. Brian LeRoux Brian LeRoux 25 Jul 2025 This one never got much attention but maybe useful reference. I think it's ok to write code if you're a programmer but I'm a weirdo that way. www.npmjs.com/package/spac... 2. Zach Leatherman :11ty: Zach Leatherman :11ty: 25 Jul 2025 @pete seems about right ???? 3. Zach Leatherman :11ty: Zach Leatherman :11ty: 25 Jul 2025 @db I would be honored! 4. Zach Leatherman Zach Leatherman 25 Jul 2025 nice! I hadn't seen this one before either! I too think it's okay to write code (and by hand even) 5. Zach Leatherman Zach Leatherman 25 Jul 2025 I am so sorry and so proud but mostly sorry 6. Zach Leatherman :11ty: Zach Leatherman :11ty: 25 Jul 2025 @db nerd sniped ???? 7. Gryphon Gryphon 25 Jul 2025 Intl gets me most of the way there these days 8. Zach Leatherman Zach Leatherman 25 Jul 2025 well wait -- I don't see any date parsing things in those APIs -- only formatting/display 9. Zach Leatherman :11ty: Zach Leatherman :11ty: 25 Jul 2025 @jimniels Geordi is one of my favorite fictional engineers so I take this as very high praise thank you 10. Zach Leatherman :11ty: Zach Leatherman :11ty: 25 Jul 2025 @scrwd JON this definitely feels more ???? than ???? ???? 11. [] bsky.app 25 Jul 2025 "As an aside, this search has made me tempted to ask: do we need to keep Dual publishing packages? I prefer ESM over CJS but maybe just pick one?" Could this mean you'll drop support for CJS config in Eleventy v4? Would mean we wouldn't have to Dual publish plugi... Truncated 12. Zach Leatherman Zach Leatherman 25 Jul 2025 naw, there's no reason to drop CJS config/data/template file support in Eleventy. It's written in ESM but works with CJS (in Node 18 too) None of the official Eleventy plugins are dual published either, fwiw -- if they need to support core < 3, they'll stay as CJS. If core >... Truncated 13. Zach Leatherman Zach Leatherman 25 Jul 2025 to be clear, CJS configs can import ESM plugins with `await import` 14. Zach Leatherman :11ty: Zach Leatherman :11ty: 25 Jul 2025 @db @eeeps since I have the benefit of comparing test output against other libraries, I can just generate random input and see what happens right ???? 15. Zach Leatherman :11ty: Zach Leatherman :11ty: 25 Jul 2025 eww, no thank you 16. Zach Leatherman Zach Leatherman 25 Jul 2025 only general zod can judge me Shamelessly plug your related post These are webmentions via the IndieWeb and webmention.io. URL of your site: [ ] [Send Webmention] Sharing on social media? This is what will show up when you share this post on Social Media: Never write your own Date Parsing Library How did you do this? I automated my Open Graph images. (Peer behind the curtain at the test page) Built with Eleventy v3.1.2 * MIT license * Style Guide * Twitter Archive * Edit this page Built with Eleventy, Red balloon floats away CSS Web Fonts