{"_id":"iso-8601-regex","_rev":"8-528f22c09c5438009e84f716c6eab16d","name":"iso-8601-regex","dist-tags":{"latest":"0.2.5"},"versions":{"0.1.0":{"name":"iso-8601-regex","version":"0.1.0","keywords":["iso8601","regex","datetime","validation","node:test","leap-year","calendar","timezone","strict"],"author":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"license":"MIT","_id":"iso-8601-regex@0.1.0","maintainers":[{"name":"lightningspirit","email":"lightningspirit@gmail.com"}],"homepage":"https://gist.github.com/lightningspirit/01084f5674f70216a56b1c26ab364848#file-readme-md","bugs":{"url":"https://gist.github.com/lightningspirit/01084f5674f70216a56b1c26ab364848"},"dist":{"shasum":"6dfbdcfdb7d03e4fed4cbcf599c4bd91b997aa38","tarball":"https://registry.npmjs.org/iso-8601-regex/-/iso-8601-regex-0.1.0.tgz","fileCount":4,"integrity":"sha512-1Slbtc2xxUqx6F9Val2o8cDvELX1Ju5lkuDfuDoQzosh1w0U9TD1tpBSb+PaMDCnfMSTjFfTpWhj8XLPbsXaQQ==","signatures":[{"sig":"MEYCIQCMP+UX1Xtg5pduOuWmPJLFHGejL7134URrUhy4XnnN0QIhAKQhDiKEQ+Y+IpgSTHEnzo1qAA+76KzWFy2c4iBOit0L","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16024},"main":"./strict-iso-8601-regex.js","type":"module","engines":{"node":">=20.0.0"},"exports":{".":"./strict-iso-8601-regex.js","./test":"./strict-iso-8601-regex.test.js"},"gitHead":"d8542da2555ccd0e0eff85427da097bb61812d35","scripts":{"test":"node --test strict-iso-8601-regex.test.js"},"_npmUser":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"repository":{"url":"git+https://gist.github.com/01084f5674f70216a56b1c26ab364848.git","type":"git"},"_npmVersion":"10.8.2","description":"A strict ISO 8601 datetime validation regex with full calendar correctness (leap years, day/month limits, and timezone validation). Includes a comprehensive node:test suite.","directories":{},"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/iso-8601-regex_0.1.0_1762124031563_0.3101779003553733","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"iso-8601-regex","version":"0.1.1","keywords":["iso8601","regex","datetime","validation","node:test","leap-year","calendar","timezone","strict"],"author":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"license":"MIT","_id":"iso-8601-regex@0.1.1","maintainers":[{"name":"lightningspirit","email":"lightningspirit@gmail.com"}],"homepage":"https://gist.github.com/lightningspirit/01084f5674f70216a56b1c26ab364848#file-readme-md","bugs":{"url":"https://gist.github.com/lightningspirit/01084f5674f70216a56b1c26ab364848"},"dist":{"shasum":"5dfba8ce865c75719a27026c8aeb3e62eceed7f3","tarball":"https://registry.npmjs.org/iso-8601-regex/-/iso-8601-regex-0.1.1.tgz","fileCount":6,"integrity":"sha512-q6dFILwN1TT0FOW7vJptPhrdtzVzRMrflPE9UiHv/6Jlc4AyAHAb5/bwNrw4koP2069D7ozcwBJoZdfPlL3N6g==","signatures":[{"sig":"MEYCIQDQQRoQ9NwcDLZwcg0RoPwloMPXNAc8PcYqpKHh8YsLLgIhAPWpM4DojxjzthIJIMqaLC4/duMpYXAdewZLNABkvzID","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":20052},"main":"./strict-iso-8601-regex.js","type":"module","types":"./strict-iso-8601-regex.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./strict-iso-8601-regex.d.ts","import":"./strict-iso-8601-regex.js"},"./test":"./strict-iso-8601-regex.test.js"},"gitHead":"ad8f3e6b98524c0b4239920708f3b1e534c90a16","scripts":{"test":"node --test strict-iso-8601-regex.test.js"},"_npmUser":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"repository":{"url":"git+https://gist.github.com/01084f5674f70216a56b1c26ab364848.git","type":"git"},"_npmVersion":"10.8.2","description":"A strict ISO 8601 datetime validation regex with full calendar correctness (leap years, day/month limits, and timezone validation). Includes a comprehensive node:test suite.","directories":{},"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/iso-8601-regex_0.1.1_1762162661313_0.6124169889041886","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"iso-8601-regex","version":"0.2.0","keywords":["iso8601","regex","datetime","validation","node:test","leap-year","calendar","timezone","strict"],"author":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"license":"MIT","_id":"iso-8601-regex@0.2.0","maintainers":[{"name":"lightningspirit","email":"lightningspirit@gmail.com"}],"homepage":"https://gist.github.com/lightningspirit/01084f5674f70216a56b1c26ab364848#file-readme-md","bugs":{"url":"https://gist.github.com/lightningspirit/01084f5674f70216a56b1c26ab364848"},"dist":{"shasum":"a8b0611de5180cc2d263868a813148a9ace554d9","tarball":"https://registry.npmjs.org/iso-8601-regex/-/iso-8601-regex-0.2.0.tgz","fileCount":6,"integrity":"sha512-lErbqbkmD/fTHVJBDPsmFA6yuuGXxaBTRbyi+c8/d5gX1AYMLhS+wKcEK+X6ZqdbkckZO2CbNLr3ME79U3aKTg==","signatures":[{"sig":"MEQCIHLnnWC8DXBQn3ey3bc8k7q1Hg2zFNQPhBN5sJG1H7dZAiBL5sRw1Ygb0vJNM1omyeclQ3R/zgBq2xuEja7x5zqjxg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31356},"main":"./strict-iso-8601-regex.js","type":"module","types":"./strict-iso-8601-regex.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./strict-iso-8601-regex.d.ts","import":"./strict-iso-8601-regex.js"},"./test":"./strict-iso-8601-regex.test.js"},"gitHead":"33c7f4969e1e67f689749aebd62730feba2f022e","scripts":{"test":"node --test strict-iso-8601-regex.test.js"},"_npmUser":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"repository":{"url":"git+https://gist.github.com/01084f5674f70216a56b1c26ab364848.git","type":"git"},"_npmVersion":"10.8.2","description":"A strict ISO 8601 (RFC 3339) datetime validation regex with full calendar correctness (leap years, day/month limits, and timezone validation). Includes a comprehensive node:test suite.","directories":{},"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/iso-8601-regex_0.2.0_1762214063045_0.37267649287491844","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"iso-8601-regex","version":"0.2.1","keywords":["iso8601","regex","datetime","validation","node:test","leap-year","calendar","timezone","strict"],"author":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"license":"MIT","_id":"iso-8601-regex@0.2.1","maintainers":[{"name":"lightningspirit","email":"lightningspirit@gmail.com"}],"homepage":"https://lightningspir.it/iso-8601-regex","bugs":{"url":"https://gist.github.com/01084f5674f70216a56b1c26ab364848"},"dist":{"shasum":"26d9fe486ae7c7f2fab70d6286e5343020f5718c","tarball":"https://registry.npmjs.org/iso-8601-regex/-/iso-8601-regex-0.2.1.tgz","fileCount":6,"integrity":"sha512-xuvfS8aaoRgevCuza3964Ql/oGMZ+zIhFs2Er13+CimTDSHRDqYmfb70xJN3ZvcDbIuyoHbcl0/mSE88CkUJww==","signatures":[{"sig":"MEYCIQD+MgBr8JCl1phC0z6/PwTmznyDbdkSDHJvp7Hxv/hdZAIhAOF5vtnbB039oIbr8ryRC0g/sarEzfEDD/4l5EQLDLNg","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31300},"main":"./strict-iso-8601-regex.js","type":"module","types":"./strict-iso-8601-regex.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./strict-iso-8601-regex.d.ts","import":"./strict-iso-8601-regex.js"},"./test":"./strict-iso-8601-regex.test.js"},"gitHead":"40166029869467ec48381fa2e3a6c3890c074a30","scripts":{"test":"node --test strict-iso-8601-regex.test.js"},"_npmUser":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"repository":{"url":"git+https://gist.github.com/01084f5674f70216a56b1c26ab364848.git","type":"git"},"_npmVersion":"10.8.2","description":"A strict ISO 8601 (RFC 3339) datetime validation regex with full calendar correctness (leap years, day/month limits, and timezone validation). Includes a comprehensive node:test suite.","directories":{},"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/iso-8601-regex_0.2.1_1762215090779_0.25631383444174616","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"iso-8601-regex","version":"0.2.2","keywords":["iso8601","regex","datetime","validation","node:test","leap-year","calendar","timezone","strict"],"author":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"license":"MIT","_id":"iso-8601-regex@0.2.2","maintainers":[{"name":"lightningspirit","email":"lightningspirit@gmail.com"}],"homepage":"https://lightningspir.it/iso-8601-regex","bugs":{"url":"https://gist.github.com/01084f5674f70216a56b1c26ab364848"},"dist":{"shasum":"210df3d9e4d6d822f256c44d2b16eb9bba5ebc36","tarball":"https://registry.npmjs.org/iso-8601-regex/-/iso-8601-regex-0.2.2.tgz","fileCount":6,"integrity":"sha512-CahyoVp/sPjlt2p8NgwHLZMJlgK+AR9KSz9obe1sH9eK9x3ANeZAIwRnQklgv4Usd0sfcAfR8BodCg3nvopdLg==","signatures":[{"sig":"MEQCIH/3vjhZ/teTWsKi5sXxx1FoKsuagQwPbuy7euInR/PCAiBXt3MX50fLz2uDc1gACLR+W44SZUpaYNWwcl7TzwcsNg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31308},"main":"./strict-iso-8601-regex.js","type":"module","types":"./strict-iso-8601-regex.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./strict-iso-8601-regex.d.ts","import":"./strict-iso-8601-regex.js"},"./test":"./strict-iso-8601-regex.test.js"},"gitHead":"88ecb6c61459eacf8193568900634a0051f5ca16","scripts":{"test":"node --test strict-iso-8601-regex.test.js"},"_npmUser":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"repository":{"url":"git+https://gist.github.com/01084f5674f70216a56b1c26ab364848.git","type":"git"},"_npmVersion":"10.8.2","description":"A strict ISO 8601 (RFC 3339) datetime validation regex with full calendar correctness (leap years, day/month limits, and timezone validation). Includes a comprehensive node:test suite.","directories":{},"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/iso-8601-regex_0.2.2_1762251910119_0.4352083373034781","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"iso-8601-regex","version":"0.2.3","keywords":["iso8601","iso-8601","rfc3339","regex","regexp","datetime","date","time","validation","validator","node:test","leap-year","calendar","timezone","strict","typescript"],"author":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"license":"MIT","_id":"iso-8601-regex@0.2.3","maintainers":[{"name":"lightningspirit","email":"lightningspirit@gmail.com"}],"homepage":"https://lightningspir.it/iso-8601-regex","bugs":{"url":"https://github.com/lightningspirit/iso-8601-regex-ts/issues","email":"lightningspirit+bug-report@gmail.com"},"dist":{"shasum":"a9c21bfbb6114e4a0f14d0d21678efcc8ff5a17a","tarball":"https://registry.npmjs.org/iso-8601-regex/-/iso-8601-regex-0.2.3.tgz","fileCount":6,"integrity":"sha512-Isu/tQhPYeBa9rBe40Zx44kJd8+hp44aP4vLhoKatO7XMZ47MOMQYZ6Hc3dAvvzOwupQD+aekDhTcbSE634SIQ==","signatures":[{"sig":"MEUCIQCa6D0FpMsIVQKHS68TEvOtIF3Cwzjnt2VH1OaqAfQycAIgPIuvwi/O8iIZKZRpAmmbeWDbMqGxBsbr+8EYnNKuuRg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":20675},"main":"./strict-iso-8601-regex.cjs","type":"module","types":"./strict-iso-8601-regex.d.ts","module":"./strict-iso-8601-regex.js","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./strict-iso-8601-regex.d.ts","import":"./strict-iso-8601-regex.js","default":"./strict-iso-8601-regex.js","require":"./strict-iso-8601-regex.cjs"},"./test":"./strict-iso-8601-regex.test.js","./package.json":"./package.json"},"gitHead":"016448bc1ac268c757ec69906020694fd3a6a48f","scripts":{"test":"node --test strict-iso-8601-regex.test.js strict-iso-8601-regex.test.cjs","prepublishOnly":"npm test"},"_npmUser":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"repository":{"url":"git+https://github.com/lightningspirit/iso-8601-regex-ts.git","type":"git"},"_npmVersion":"10.8.2","description":"A strict ISO 8601 (RFC 3339) datetime validation regex with full calendar correctness (leap years, day/month limits, and timezone validation). Includes a comprehensive node:test suite.","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/iso-8601-regex_0.2.3_1762950372162_0.6484376852749754","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"iso-8601-regex","version":"0.2.4","keywords":["iso8601","iso-8601","rfc3339","regex","regexp","datetime","date","time","validation","validator","node:test","leap-year","calendar","timezone","strict","typescript"],"author":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"license":"MIT","_id":"iso-8601-regex@0.2.4","maintainers":[{"name":"lightningspirit","email":"lightningspirit@gmail.com"}],"homepage":"https://github.com/lightningspirit/iso-8601-regex-ts","bugs":{"url":"https://github.com/lightningspirit/iso-8601-regex-ts/issues","email":"lightningspirit+bug-report@gmail.com"},"dist":{"shasum":"14c35b811fcf03b886d1fe0521f67e87f3e9e580","tarball":"https://registry.npmjs.org/iso-8601-regex/-/iso-8601-regex-0.2.4.tgz","fileCount":6,"integrity":"sha512-UbFWvYi3tr0tTZ/iShTRcTyrmRQScMS7ieKMpyrXiSTP8Vccs5qvG8v+CoIuQ9bsvqVL/+uaBWiOOVcWCufbRg==","signatures":[{"sig":"MEUCIFufJVREwVV4i2DD4cZQDcQNjJOHq+CWijfSt6aHg4PxAiEAyXEyRW+0zhk3/4RgueT9RIqGwS7ey4XybZjzuI1fwyE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/iso-8601-regex@0.2.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":20763},"main":"./strict-iso-8601-regex.cjs","type":"module","types":"./strict-iso-8601-regex.d.ts","module":"./strict-iso-8601-regex.js","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./strict-iso-8601-regex.d.ts","import":"./strict-iso-8601-regex.js","default":"./strict-iso-8601-regex.js","require":"./strict-iso-8601-regex.cjs"},"./test":"./strict-iso-8601-regex.test.js","./package.json":"./package.json"},"gitHead":"9381f408c9150b5627208b8467203af6cbe8bb28","scripts":{"test":"node --test strict-iso-8601-regex.test.js strict-iso-8601-regex.test.cjs","prepublishOnly":"npm test"},"_npmUser":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"repository":{"url":"git+https://github.com/lightningspirit/iso-8601-regex-ts.git","type":"git"},"_npmVersion":"10.8.2","description":"A strict ISO 8601 (RFC 3339) datetime validation regex with full calendar correctness (leap years, day/month limits, and timezone validation). Includes a comprehensive node:test suite.","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/iso-8601-regex_0.2.4_1762951370236_0.8246255968513934","host":"s3://npm-registry-packages-npm-production"}},"0.2.5":{"name":"iso-8601-regex","version":"0.2.5","description":"A strict ISO 8601 (RFC 3339) datetime validation regex with full calendar correctness (leap years, day/month limits, and timezone validation). Includes a comprehensive node:test suite.","type":"module","main":"./strict-iso-8601-regex.cjs","module":"./strict-iso-8601-regex.js","types":"./strict-iso-8601-regex.d.ts","exports":{".":{"types":"./strict-iso-8601-regex.d.ts","import":"./strict-iso-8601-regex.js","require":"./strict-iso-8601-regex.cjs","default":"./strict-iso-8601-regex.js"},"./test":"./strict-iso-8601-regex.test.js","./package.json":"./package.json"},"scripts":{"test":"node --test strict-iso-8601-regex.test.js strict-iso-8601-regex.test.cjs","bench":"npm --prefix benchmark ci --silent && npm --prefix benchmark start","prepublishOnly":"npm test"},"keywords":["iso8601","iso-8601","rfc3339","regex","regexp","datetime","date","time","validation","validator","node:test","leap-year","calendar","timezone","strict","typescript"],"author":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"license":"MIT","engines":{"node":">=20.0.0"},"repository":{"type":"git","url":"git+https://github.com/lightningspirit/iso-8601-regex-ts.git"},"bugs":{"url":"https://github.com/lightningspirit/iso-8601-regex-ts/issues","email":"lightningspirit+bug-report@gmail.com"},"homepage":"https://github.com/lightningspirit/iso-8601-regex-ts","sideEffects":false,"_id":"iso-8601-regex@0.2.5","gitHead":"f1e805a1989a606d51d56c3de7228b32003c8b79","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-eMh9PGw4I4IthVZvqCrzBn9ir6yUxHz8vcGMsft1v3z0s/caIe9vGJ5QX74yS7LY4jbYE9jteV+MMkFGZ8+rvQ==","shasum":"71e5e21cee01857c4fa5287ba176a823cb09b595","tarball":"https://registry.npmjs.org/iso-8601-regex/-/iso-8601-regex-0.2.5.tgz","fileCount":6,"unpackedSize":29404,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/iso-8601-regex@0.2.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDaf2sqtwshgs5aogXqlXxmDDdptoTT8/hI9HTqwvir6gIhAO8Dt1SI4I3paTHq6nX4nL7CdMQumH3iDois36uR3oLb"}]},"_npmUser":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"directories":{},"maintainers":[{"name":"lightningspirit","email":"lightningspirit@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/iso-8601-regex_0.2.5_1779885549391_0.6994259688776308"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-02T22:53:51.562Z","modified":"2026-05-27T12:39:09.814Z","0.1.0":"2025-11-02T22:53:51.759Z","0.1.1":"2025-11-03T09:37:41.503Z","0.2.0":"2025-11-03T23:54:23.239Z","0.2.1":"2025-11-04T00:11:31.202Z","0.2.2":"2025-11-04T10:25:10.329Z","0.2.3":"2025-11-12T12:26:12.323Z","0.2.4":"2025-11-12T12:42:50.440Z","0.2.5":"2026-05-27T12:39:09.539Z"},"bugs":{"url":"https://github.com/lightningspirit/iso-8601-regex-ts/issues","email":"lightningspirit+bug-report@gmail.com"},"author":{"name":"lightningspirit","email":"lightningspirit@gmail.com"},"license":"MIT","homepage":"https://github.com/lightningspirit/iso-8601-regex-ts","keywords":["iso8601","iso-8601","rfc3339","regex","regexp","datetime","date","time","validation","validator","node:test","leap-year","calendar","timezone","strict","typescript"],"repository":{"type":"git","url":"git+https://github.com/lightningspirit/iso-8601-regex-ts.git"},"description":"A strict ISO 8601 (RFC 3339) datetime validation regex with full calendar correctness (leap years, day/month limits, and timezone validation). Includes a comprehensive node:test suite.","maintainers":[{"name":"lightningspirit","email":"lightningspirit@gmail.com"}],"readme":"# Strict ISO 8601 (RFC 3339) Date Regex\n\nThis repository contains a **fully validated strict ISO 8601 (RFC 3339) datetime regular expression** that delivers **top-tier performance**, remains **dependency-free** and **ReDoS-resistant**, and has a low memory footprint.\n\nIt ensures that timestamps strictly follow [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatting and [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339) strictness **with full calendar correctness**, including leap-year validation, month-day ranges, and time zone offsets, validated by a comprehensive **test suite** written with Node’s built-in [`node:test`](https://nodejs.org/api/test.html) module and a **benchmark** [runtime](#performance) against major validators.\n\n## Highlights\n\n- **Strict by construction** — calendar-correct (leap years, 30/31 days, Feb 29) and RFC 3339 timezone range (`−12:00 … +14:00`). What `Date.parse` silently accepts, this rejects.\n- **Top-tier performance** — competitive with `zod`, `validator.js`, `ajv`, `Date.parse`, `date-fns`, `luxon`, and `dayjs` on valid ISO 8601 inputs shown below, and significantly faster on invalid/fuzzy rejection ([benchmarks](#performance)). Up to **~100× faster than alternatives on invalid rejection.**\n- **Low allocation** — measured at <4 bytes/validation, with minimal observed GC overhead.\n- **ReDoS-hardened** — no catastrophic backtracking. Worst observed latency on adversarial input is **~1.5 µs**; fuzzed with 10 000 random strings via `fast-check` — zero crashes, zero hangs.\n- **Zero runtime dependencies, zero side effects** — one regex, ESM + CJS + `.d.ts`.\n- **Named capture groups** — `year`, `month`, `day`, `hour`, `minute`, `second`, `millisecond`, `timezone` — parse and validate in one pass, making it easy to build your own custom date-time parser.\n\n## Why\n\n1. After compilation, RegExp are fast and reliable\n2. Gregorian DateTime logic does not change — it is essentially static\n3. Because `Date` does not validate it semantically (eg. calendar correctness)\n\n```js\nnew Date('2025-11-31T00:00:00Z')\n// 2025-12-01T00:00:00.000Z\n```\nIn this example, passing `November 31st` will convert to `1st of December`, which can lead to VERY nasty bugs and exploits in some contexts (eg. money, enforcing contract dates, etc).\n\n## Usage\n\n### Test for strict RFC 3339 correctness\n\n```js\nimport { ISO8601Date } from 'iso-8601-regex';\n\nISO8601Date.test('2025-11-02T00:00:00.000Z'); // true — within boundaries\nISO8601Date.test('2025-11-31T00:00:00.000Z'); // false — only 30 days in November\n\nISO8601Date.test('2024-02-29T00:00:00.000Z'); // true — 2024 was a leap year\nISO8601Date.test('2025-02-29T00:00:00.000Z'); // false — not a leap year\n```\n\nWhen you get as input any ISO 8601 string, just use this to check its correctness.\n\n```js\nif (!ISO8601Date.test(request.startDate)) {\n  throw new Error('Invalid ISO 8601 DateString');\n}\n\n// safe startDate without temperings\nconst startDate = new Date(request.startDate);\n```\n\n### Using group captured values\n\nThis regex provides **named capturing groups** for every major datetime component.\nYou can use `RegExp.prototype.exec()` (or `.match()` with the `d` flag in future ECMAScript versions) to access them directly.\n\n```js\nimport { ISO8601Date } from 'iso-8601-regex';\n\nconst match = ISO8601Date.exec('2025-11-02T10:20:30.123+09:30');\n\nif (match) {\n  const g = match.groups;\n  console.log(g);\n  /*\n  {\n    year: '2025',\n    month: '11',\n    day: '02',\n    hour: '10',\n    minute: '20',\n    second: '30',\n    millisecond: '123',\n    timezone: '+09:30'\n  }\n  */\n}\n```\n\n#### Examples\n\n| Input string                    | Captured values                                                                                                                |\n| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| `2025-11-02T10:20:30Z`          | `{ year: '2025', month: '11', day: '02', hour: '10', minute: '20', second: '30', millisecond: undefined, timezone: 'Z' }`      |\n| `2038-01-19T03:14:07.045+13:59` | `{ year: '2038', month: '01', day: '19', hour: '03', minute: '14', second: '07', millisecond: '045', timezone: '+13:59' }`     |\n| `2000-02-29T00:00:00-12:00`     | `{ year: '2000', month: '02', day: '29', hour: '00', minute: '00', second: '00', millisecond: undefined, timezone: '-12:00' }` |\n| `2024-06-10T09:08:07.5+14:00`   | `{ year: '2024', month: '06', day: '10', hour: '09', minute: '08', second: '07', millisecond: '5', timezone: '+14:00' }`       |\n\n> **Tip:** The `millisecond` field may be `undefined` if no fractional component is present.\n> This is especially useful when normalizing ISO timestamps or building custom date-time parsers.\n\n\n## Performance\n\nBenchmarks are run with [tinybench](https://github.com/tinylibs/tinybench) on Node.js 22 against the most common datetime-handling libraries in the JS ecosystem. The full script lives in [`benchmark/index.ts`](./benchmark/index.ts) — run it locally with `npm run bench` (takes ~20 s; deps are installed into `benchmark/node_modules`, never into the published package).\n\n> **Hardware:** numbers below were measured on a **MacBook Pro M4 Max**. Absolute ops/s will differ on other machines and Node versions — the **relative ranking** is what matters.\n\nTwo kinds of library are compared in the same tables:\n\n| Kind            | Libraries                                                                                              |\n| --------------- | ------------------------------------------------------------------------------------------------------ |\n| **Validator** (validate only)        | `iso-8601-regex`, [`validator.js`](https://github.com/validatorjs/validator.js), [`zod`](https://github.com/colinhacks/zod) (`z.iso.datetime`), [`ajv`](https://github.com/ajv-validator/ajv) (+ `ajv-formats`, JSON Schema `format: date-time`) |\n| **Parser** (parse + validate)        | `Date.parse`, [`luxon`](https://github.com/moment/luxon), [`date-fns`](https://github.com/date-fns/date-fns) (`parseISO`+`isValid`), [`dayjs`](https://github.com/iamkun/dayjs) (strict mode)                                  |\n\n> **Fairness note:** parsers do strictly more work (they build a `DateTime`/timestamp), so they are at a disadvantage on raw throughput. The tables reflect the user-facing API of each library — which is the realistic choice point for application authors.\n\nThree columns matter:\n\n- **Throughput (ops/sec)** — each op = one full dataset pass (1 000 inputs for VALID/INVALID/FUZZY). Higher is better.\n- **Heap bytes / validation** — approximate steady-state allocation per input (measured with `--expose-gc`). Lower is better. Anything in the thousands means GC pressure under load.\n- **Kind** — validator vs parser.\n\n### Valid ISO 8601 inputs (mixed: UTC, offsets, milliseconds, leap year)\n\n| Library          |   ops/sec ↑ |        bytes/op ↓ | Kind      |\n| ---------------- | ----------: | ----------------: | --------- |\n| `zod`            |       25633 |             104.3 | validator |\n| `iso-8601-regex` |   **25116** |           **3.7** | validator |\n| `validator.js`   |       12109 |               3.9 | validator |\n| `Date.parse`     |       11545 |              16.3 | parser    |\n| `ajv`            |        3842 |             757.1 | validator |\n| `date-fns`       |        1297 |            2028.6 | parser    |\n| `luxon`          |         778 |            8598.1 | parser    |\n| `dayjs`          |          81 |           13127.5 | parser    |\n\n### Invalid inputs (early-rejection path)\n\n| Library          | ops/sec ↑ | bytes/op ↓ | Kind      |\n| ---------------- | --------: | ---------: | --------- |\n| `iso-8601-regex` | **58219** |    **0.3** | validator |\n| `validator.js`   |     38013 |        0.3 | validator |\n| `ajv`            |     35927 |      352.4 | validator |\n| `Date.parse`     |     31516 |       16.3 | parser    |\n| `date-fns`       |      2144 |     1512.1 | parser    |\n| `luxon`          |      1133 |     7445.3 | parser    |\n| `zod`            |       153 |     5218.7 | validator |\n| `dayjs`          |        42 |     8064.8 | parser    |\n\n### Fuzzy / adversarial inputs (random + repeated near-matches)\n\n| Library          | ops/sec ↑ | bytes/op ↓ | Kind      |\n| ---------------- | --------: | ---------: | --------- |\n| `iso-8601-regex` | **56281** |    **0.5** | validator |\n| `Date.parse`     |     26623 |       16.5 | parser    |\n| `validator.js`   |     18058 |        0.5 | validator |\n| `luxon`          |      5211 |     2706.0 | parser    |\n| `ajv`            |       521 |    12685.4 | validator |\n| `date-fns`       |       505 |    12799.7 | parser    |\n| `zod`            |       301 |     5374.4 | validator |\n| `dayjs`          |       144 |    22617.3 | parser    |\n\n### Worst-case latency and fuzz crash safety\n\n| Check                                | Result      |\n| ------------------------------------ | ----------: |\n| Worst-case latency on fuzzy evil set |  0.0015 ms  |\n| `fast-check` property fuzz (10 000 random strings) | ✓ no crashes / hangs |\n\n### What the numbers say\n\n- **Fastest validator across all three datasets** — including against `zod` (close on valid inputs but ~170× slower on invalid).\n- **Effectively zero heap allocation** (0.3–3.7 bytes/validation across all datasets). The closest competitor on allocation, `validator.js`, is also allocation-free but ~2× slower throughput.\n- **No ReDoS pathology**: worst observed latency on adversarial input is ~1.5 µs.\n\n> Absolute ops/s shifts between machines, Node versions, and V8 JIT specialization. The **relative ranking** is what matters — datasets are shuffled and re-evaluated on every run to limit IC specialization.\n\n## Comparison\n\n| Feature                                     | `iso-8601-regex` | `validator.js` | `zod` | `ajv` | `date-fns` | `dayjs` | `luxon` | `Date.parse` |\n| ------------------------------------------- | :--------------: | :------------: | :---: | :---: | :--------: | :-----: | :-----: | :----------: |\n| Strict RFC 3339 validation                  |        ✅        |     partial    |  ✅  |  ✅   |  partial   | partial | partial |      ❌      |\n| Calendar correctness (leap year, month/day) |        ✅        |       ❌       |  ❌  |  ❌   |    ✅      |   ✅    |   ✅    |      ❌      |\n| Strict timezone range `−12:00 … +14:00`     |        ✅        |       ❌       |  ❌  |  ❌   |    ❌      |   ❌    |   ❌    |      ❌      |\n| Named capture groups                        |        ✅        |       ❌       |  —   |  —   |     —      |    —    |    —    |      —      |\n| Zero runtime dependencies                   |        ✅        |       ❌       |  ❌  |  ❌   |    ❌      |   ❌    |   ❌    |      —      |\n| Zero heap allocation per call               |        ✅        |       ✅       |  ❌  |  ❌   |    ❌      |   ❌    |   ❌    |      ❌      |\n| ReDoS-tested (fuzz + adversarial)           |        ✅        |       ❌       |  ❌  |  ❌   |    ❌      |   ❌    |   ❌    |      —      |\n| Fast invalid rejection                      |        ✅        |       ✅       |  ❌  |  ✅   |    ⚠️      |   ❌    |   ⚠️    |      ✅      |\n\n## Mechanics\n\nThe regex matches only **valid and complete** ISO 8601 datetime strings of the form:\n\n```\nYYYY-MM-DDTHH:mm:ss(.SSS)?(Z|±HH:MM)\n```\n\n### Examples that match\n\n| Example                         | Description           |\n| ------------------------------- | --------------------- |\n| `2025-11-02T10:20:30Z`          | Basic UTC timestamp   |\n| `2025-11-02T10:20:30.123Z`      | With milliseconds     |\n| `2025-11-02T10:20:30+09:30`     | With positive offset  |\n| `2024-02-29T12:00:00Z`          | Leap year February 29 |\n| `2025-04-30T23:59:59.999+00:00` | Month with 30 days    |\n\n### Examples that do *not* match\n\n| Example                 | Reason                          |\n| ----------------------- | ------------------------------- |\n| `2025-11-02T10:20:30`   | Missing `Z` or offset           |\n| `2025-11-02 10:20:30Z`  | Space instead of `T`            |\n| `2025-04-31T12:00:00Z`  | April has only 30 days          |\n| `2025-11-02T24:00:00Z`  | Hour overflow                   |\n| `1900-02-29T00:00:00Z`  | 1900 not a leap year            |\n| ` 2025-11-02T10:20:30Z` | Leading space (anchored at `^`) |\n\n\n## Regex Features\n\n### Enforces\n\n* Year: `0000–9999`\n* Month: `01–12`\n* Day: `01–31` (valid per month, leap-year aware)\n* Hours: `00–23`\n* Minutes: `00–59`\n* Seconds: `00–59`\n* Milliseconds: optional `1–3` digits\n* Time zone: `Z` or `±HH:MM` (00–23h / 00–59m)\n* Anchored at both ends (`^…$`) — **no leading/trailing characters allowed**\n\n### Leap Year Logic\n\nLeap years match the Gregorian rule:\n\n* Divisible by 4 → leap year\n* Except years divisible by 100 → *not* leap year\n* Except years divisible by 400 → leap year again\n\n- `2000`, `2016`, `2024` are leap years\n- `1900`, `2100` are not\n\n## Test Coverage\n\nThe test suite verifies:\n\n| Category             | Examples tested                                          |\n| -------------------- | -------------------------------------------------------- |\n| **Basic formats**    | UTC (`Z`), fractional seconds, positive/negative offsets |\n| **Time boundaries**  | `00:00:00`–`23:59:59`, offsets `±00:00`–`±23:59`         |\n| **Month/day bounds** | Correct 30- vs 31-day months                             |\n| **Invalid overflow** | Hours ≥24, minutes/seconds ≥60, too many ms digits       |\n| **Non-ISO shapes**   | Wrong separators, missing parts, trailing junk           |\n| **Leap years**       | Accepts Feb 29 only in leap years                        |\n| **Common years**     | Rejects Feb 29 on non-leap years                         |\n| **Anchors**          | Rejects leading/trailing spaces and extra characters     |\n| **Regression cases** | Valid timestamps across centuries and time zones         |\n\n## Running the Tests\n\nMake sure you’re using **Node.js v20+**, then run:\n\n```bash\nnpm test\n```\n\n## Notes & Limitations\n\n* **Performance:** Large but ReDoS-resistant and consistently faster than `validator.js`, `luxon`, and `Date.parse` for validation — see [Performance](#performance).\n* **Scope:** Designed for *datetime strings*, not partial ISO dates (`YYYY-MM`, `YYYY-Wxx`, etc.).\n* **Whitespace:** Leading/trailing spaces cause rejection; trim inputs before testing.\n* **Calendar bounds:** Days per month and leap-year rules are enforced; invalid combinations (e.g. April 31) fail.\n\n## References\n\n* [ISO 8601:2019 — Date and time format specification](https://www.iso.org/iso-8601-date-and-time-format.html)\n* [RFC 3339 — Date and Time on the Internet: Timestamps](https://datatracker.ietf.org/doc/html/rfc3339)\n* [ECMAScript Date.toISOString()](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)\n\n## Changelog\n\n### v0.2.5 — 2026-05-27\n\n* Added comprehensive performance + memory benchmarks against `validator.js`, `zod`, `ajv`, `date-fns`, `dayjs`, `luxon`, and `Date.parse` ([`benchmark/`](./benchmark/)).\n* New **Performance** and **Comparison** sections in README with ops/sec and heap-bytes-per-validation numbers.\n* Benchmark suite isolated under `benchmark/` with its own `package.json`; **root package is now zero-dependency** (`luxon` and `validator` moved out of runtime deps — they were only used by the benchmark).\n* Added GitHub Actions workflow to run benchmarks on PRs and comment results.\n\n### v0.2.4 — 2025-11-12\n\n* Security enhancement, added provenance files\n\n### v0.2.3 — 2025-11-12\n\n* Added CommonJS export\n* Improved test suite with performance tests\n* Moved to a proper repository\n\n### v0.2.2 — 2025-11-04\n\n* Update import example in README.md\n\n### v0.2.1 — 2025-11-04\n\n* Changing README.md title\n* Update homepage URL in `package.json`\n\n### v0.2.0 — 2025-11-03\n\n**Breaking**\n\n* Validate strict timezone range `−12:00…+14:00`\n\n**Added**\n\n* Named capturing groups: `year`, `month`, `day`, `hour`, `minute`, `second`, `millisecond`, and `timezone`.\n* New section in README: **“Using group captured values”**, with examples and table of captured outputs.\n* Extended test suite for group extraction (`node:test`).\n\n**Improved**\n\n* Simplified month capture pattern (`0[1-9]|1[0-2]`) for readability and correctness.\n* Refined timezone range enforcement: now validates strictly within **−12:00 … +14:00**, rejecting `−12:01…−12:59` and `+14:01…+14:59`.\n* Unified spelling to **`millisecond`** across code and documentation.\n\n### v0.1.1 — 2025-11-02\n\n**Added**\n\n* Strict ISO 8601 regex with full Gregorian calendar correctness (month/day validation and leap-year logic).\n* Test suite using Node’s native `node:test` and `assert/strict` modules.\n* Validation of fractional seconds, offsets, and anchors.\n\n**Improved**\n\n* Leap-year computation: accepts `2000`, `2400`, rejects `1900`, `2100`.\n* Tests covering non-ISO shapes and extended formats.\n\n### v0.1.0 — 2025-11-02\n\n**Initial release:** foundational strict ISO 8601 validation for UTC.\n\n## License\n\nMIT License\n\nCopyright 2025 lightningspirit@gmail.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","readmeFilename":"README.md"}