<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><id>tag:dnevnik.fabon.info,2026:feed</id><title>fabon&apos;s blog</title><author><name>fabon</name></author><link rel="self" type="application/atom+xml" href="https://dnevnik.fabon.info/feed.xml"/><updated>2026-09-13T19:17:27.595Z</updated><entry><id>tag:dnevnik.fabon.info,2026:entry:2026-09-14/gregory-vs-iso8601</id><title>The difference between `gregory` and `iso8601` calendars in ECMAScript</title><link href="https://dnevnik.fabon.info/posts/2026/09/14/gregory-vs-iso8601/" /><content type="html">&lt;p&gt;&lt;code&gt;Temporal&lt;/code&gt; and &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; can handle various calendars, such as the Gregorian calendar with Japanese regnal eras, East Asian lunisolar calendars, Hijri calendars, and the Hebrew calendar. They also support the &lt;code&gt;iso8601&lt;/code&gt; and &lt;code&gt;gregory&lt;/code&gt; calendars, both of which represent the proleptic Gregorian calendar. So, what is the difference between &lt;code&gt;iso8601&lt;/code&gt; and &lt;code&gt;gregory&lt;/code&gt;?&lt;/p&gt;&#10;&lt;p&gt;The short answer is: &lt;code&gt;gregory&lt;/code&gt; is the real-world Gregorian calendar in the context of internationalization, while &lt;code&gt;iso8601&lt;/code&gt; is an &amp;quot;artificial&amp;quot; and &amp;quot;culturally neutral&amp;quot; Gregorian calendar modeled for computer usage.&lt;/p&gt;&#10;&lt;h2&gt;&lt;code&gt;iso8601&lt;/code&gt; as a calendar&lt;/h2&gt;&#10;&lt;p&gt;ISO 8601 is the origin of standard date and time formats for data exchange. However, the standard itself is not suitable for practical use as a reference: we cannot obtain the ISO standard document for free, the syntax definition is ambiguous, and it defines various formats that almost no one uses. The term &amp;quot;ISO 8601 format&amp;quot; roughly refers to formats defined in RFC 3339 and its successors.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href=&quot;https://www.rfc-editor.org/info/rfc3339/&quot;&gt;https://www.rfc-editor.org/info/rfc3339/&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href=&quot;https://ijmacd.github.io/rfc3339-iso8601/&quot;&gt;https://ijmacd.github.io/rfc3339-iso8601/&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;The ISO 8601 format is based on the Gregorian calendar with &lt;a href=&quot;https://en.wikipedia.org/wiki/Astronomical_year_numbering&quot;&gt;astronomical year numbering&lt;/a&gt; (year 0 for 1 BC), so it does not depend on the concept of eras. ISO 8601 also defines formats based on weeks and days of the week. The start of the week is Monday, and days of the week are 1-indexed (1 for Monday, 7 for Sunday). The first week of the year is defined as the week that contains 4 January.&lt;/p&gt;&#10;&lt;p&gt;The calendar ID &lt;code&gt;iso8601&lt;/code&gt; comes from CLDR. I suspect it originally meant the Gregorian calendar with ISO 8601 week numbering, in contrast to &lt;code&gt;gregory&lt;/code&gt;, which referred to the Gregorian calendar with locale-dependent week numbering.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href=&quot;https://github.com/unicode-org/cldr/commit/dd46a84dabf145428cdd7fbf9a350368f3055d78&quot;&gt;https://github.com/unicode-org/cldr/commit/dd46a84dabf145428cdd7fbf9a350368f3055d78&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;As an aside, TC39 and the Unicode Consortium concluded that there was insufficient evidence for locale-dependent week numbering systems other than ISO 8601. Across the world, people who care about week numbers usually expect the ISO 8601 definition. While some people may use different week numbering systems for specific use cases, it is generally not something that should be determined by locale.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href=&quot;https://github.com/tc39/proposal-intl-locale-info/issues/86&quot;&gt;https://github.com/tc39/proposal-intl-locale-info/issues/86&lt;/a&gt;&lt;/p&gt;&#10;&lt;h3&gt;&lt;code&gt;iso8601&lt;/code&gt; as a culturally neutral data model&lt;/h3&gt;&#10;&lt;p&gt;In ECMAScript, the &lt;code&gt;iso8601&lt;/code&gt; calendar is defined as a culturally neutral calendar, while &lt;code&gt;gregory&lt;/code&gt; is a Gregorian calendar closely tied to cultural contexts. I am not sure when this distinction was first established, but we can see many discussions and decisions that assume it in the meeting notes of TC39 and ECMA-402 (TG2), issues on date-related proposals, and so on.&lt;/p&gt;&#10;&lt;p&gt;Of course, the &lt;code&gt;iso8601&lt;/code&gt; calendar is based on the Gregorian calendar and anno Domini, so it inevitably has European and Christian origins. That being said, it is obvious that the ISO 8601 format and the calendar model behind it are widely used, even in non-Western and non-Christian regions. Therefore, I believe that it is practical and reasonable to treat the &lt;code&gt;iso8601&lt;/code&gt; calendar as neutral, even though it is not completely neutral.&lt;/p&gt;&#10;&lt;h2&gt;&lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;&lt;/h2&gt;&#10;&lt;p&gt;We can specify the calendar in &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;. If no calendar is specified, &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; selects the default calendar for the locale (&lt;code&gt;gregory&lt;/code&gt; in most cases). &lt;code&gt;gregory&lt;/code&gt; represents the standard Gregorian calendar used in the real world, so it includes the concept of eras, such as BC/BCE and AD/CE. You can display the era using the &lt;code&gt;era&lt;/code&gt; option.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; formatter&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Intl&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;DateTimeFormat&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;en-US&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;formatter&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2026-06-01&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// returns a date format used in the US, such as &quot;6/1/2026&quot;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;formatter&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;resolvedOptions&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;calendar&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// &quot;gregory&quot;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;-000020-01-01&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;en-US&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  era&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;short&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  year&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  month&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;long&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  day&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // &quot;January 1, 21 BC&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;You can format dates with the &lt;code&gt;iso8601&lt;/code&gt; calendar via &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;, since the API supports all calendars specified in ECMAScript. However, there is no specification or consensus on what it means to &amp;quot;format dates in the &lt;code&gt;iso8601&lt;/code&gt; calendar&amp;quot;. JavaScript engines tend to choose a pattern similar to the ISO 8601 format, but in general, the result is neither a machine-readable ISO 8601 string nor a natural human-readable format (use Temporal if you want the former). Specifying formatting options that contradict the ISO 8601 format is semantically contradictory, and the output can even be broken in such cases:&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// A format similar to ISO 8601 with English month names (semantically conflicting)&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; Date&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;en-u-ca-iso8601&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  year&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  month&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;long&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// &quot;2026 July&quot; in Chrome&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// &quot;2026 &quot; in Node.js (!!!)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;&lt;a href=&quot;https://github.com/tc39/ecma402/issues/1036&quot;&gt;https://github.com/tc39/ecma402/issues/1036&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href=&quot;https://github.com/nodejs/node/issues/63041&quot;&gt;https://github.com/nodejs/node/issues/63041&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Because &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; is designed for internationalization and produces localized output for humans, we should generally use &lt;code&gt;gregory&lt;/code&gt; here rather than &lt;code&gt;iso8601&lt;/code&gt;. We do not use the &lt;code&gt;iso8601&lt;/code&gt; calendar in daily life.&lt;/p&gt;&#10;&lt;h2&gt;Temporal&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;iso8601&lt;/code&gt; and &lt;code&gt;gregory&lt;/code&gt; behave differently in Temporal. For example, the &lt;code&gt;weekOfYear&lt;/code&gt; and &lt;code&gt;yearOfWeek&lt;/code&gt; properties return the ISO week number for &lt;code&gt;iso8601&lt;/code&gt;, but they are &lt;code&gt;undefined&lt;/code&gt; for other calendars, including &lt;code&gt;gregory&lt;/code&gt;.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; isoDate&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2024-12-31&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; gregorianDate&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2024-12-31[u-ca=gregory]&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// 31 Dec 2024 belongs to the first week of 2025&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;isoDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;weekOfYear&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // 1&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;isoDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;yearOfWeek&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // 2025&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// `undefined` for other calendars&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;gregorianDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;weekOfYear&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // undefined&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;gregorianDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;yearOfWeek&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // undefined&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;The &lt;code&gt;year&lt;/code&gt; property uses astronomical year numbering for both calendars. However, &lt;code&gt;iso8601&lt;/code&gt; does not have eras, whereas &lt;code&gt;gregory&lt;/code&gt; defines two eras: &lt;code&gt;bce&lt;/code&gt; and &lt;code&gt;ce&lt;/code&gt;.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; isoDate&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;-000020-01-01&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;isoDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;year&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // -20&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// &quot;iso8601&quot; does not have eras&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;isoDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;era&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // undefined&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;isoDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;eraYear&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // undefined&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; gregorianDate&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;-000020-01-01[u-ca=gregory]&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;gregorianDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;year&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // -20&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// &quot;year -20&quot; corresponds to 21 BC&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;gregorianDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;era&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // &quot;bce&quot;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;gregorianDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;eraYear&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // 21&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;The most fundamental difference between &lt;code&gt;iso8601&lt;/code&gt; and &lt;code&gt;gregory&lt;/code&gt; is that &lt;code&gt;iso8601&lt;/code&gt; is treated as a special calendar in Temporal, while &lt;code&gt;gregory&lt;/code&gt; is not. Temporal places &lt;code&gt;gregory&lt;/code&gt; in the same category as other cultural calendars like &lt;code&gt;chinese&lt;/code&gt; (the traditional Chinese calendar) and &lt;code&gt;hebrew&lt;/code&gt; (the Hebrew calendar).&lt;/p&gt;&#10;&lt;h3&gt;ECMA-262 and ECMA-402&lt;/h3&gt;&#10;&lt;p&gt;ECMA-262 is the core specification of JavaScript, defining almost all of its core language features. On the other hand, ECMA-402 defines internationalization features, primarily the APIs under the &lt;code&gt;Intl&lt;/code&gt; namespace. The specification for Temporal spans both ECMA-262 and ECMA-402, because Temporal deals heavily with domains closely tied to internationalization, particularly time zones and calendars.&lt;/p&gt;&#10;&lt;p&gt;The behavior of the &lt;code&gt;iso8601&lt;/code&gt; calendar in Temporal is explicitly specified in ECMA-262 with no implementation-defined behavior. For example, the date and time arithmetic algorithms are fully defined in ECMA-262. In fact, &lt;code&gt;iso8601&lt;/code&gt; is the only calendar defined in ECMA-262; all other calendars are implementation-defined in ECMA-262, and &lt;code&gt;gregory&lt;/code&gt; is not mentioned there at all.&lt;/p&gt;&#10;&lt;p&gt;ECMA-402 defines the list of calendars that conforming implementations must support, which includes &lt;code&gt;gregory&lt;/code&gt;. A conforming ECMA-402 implementation cannot omit any of these calendars or add arbitrary extra ones.&lt;/p&gt;&#10;&lt;p&gt;This distinction reflects the underlying design principle: &lt;code&gt;iso8601&lt;/code&gt; is a neutral model, whereas &lt;code&gt;gregory&lt;/code&gt; is the Gregorian calendar as used in the real world. ECMA-262, as the core language specification, aims to remain culturally neutral, and &lt;code&gt;iso8601&lt;/code&gt; is the only calendar that satisfies this requirement.&lt;/p&gt;&#10;&lt;h3&gt;How &lt;code&gt;iso8601&lt;/code&gt; and &lt;code&gt;gregory&lt;/code&gt; work in Temporal&lt;/h3&gt;&#10;&lt;p&gt;While &lt;code&gt;iso8601&lt;/code&gt; is a very special calendar in Temporal&apos;s specification, &lt;code&gt;gregory&lt;/code&gt; is treated just like any other calendar. This difference becomes apparent when using &lt;code&gt;Temporal.PlainYearMonth&lt;/code&gt; and &lt;code&gt;Temporal.PlainMonthDay&lt;/code&gt;, the two trickiest types in Temporal.&lt;/p&gt;&#10;&lt;p&gt;Dates can be converted between calendars, but isolated &amp;quot;year and month&amp;quot; or &amp;quot;month and day&amp;quot; values cannot. For example, Tamuz (M10) 5786 in the Hebrew calendar spans dates from 16 June to 14 July 2026, so there is no single corresponding &amp;quot;year and month&amp;quot; in the &lt;code&gt;iso8601&lt;/code&gt; calendar. This is why &lt;code&gt;Temporal.PlainYearMonth&lt;/code&gt; and &lt;code&gt;Temporal.PlainMonthDay&lt;/code&gt; do not have a &lt;code&gt;withCalendar&lt;/code&gt; method.&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;2026-07[u-ca=hebrew]&lt;/code&gt; clearly makes no sense, whereas &lt;code&gt;2026-07&lt;/code&gt; is a valid ISO 8601 string for July 2026 in the &lt;code&gt;iso8601&lt;/code&gt; calendar. A &lt;code&gt;Temporal.PlainYearMonth&lt;/code&gt; representing Tamuz 5786 is serialized as an ISO date string representing the first day of that month (&lt;code&gt;2026-06-16[u-ca=hebrew]&lt;/code&gt;). For consistency, &lt;code&gt;Temporal.PlainYearMonth&lt;/code&gt; rejects &lt;code&gt;2026-07[u-ca=gregory]&lt;/code&gt; just as it rejects &lt;code&gt;2026-07[u-ca=hebrew]&lt;/code&gt;. For the same reason, both &lt;code&gt;07-01[u-ca=hebrew]&lt;/code&gt; and &lt;code&gt;07-01[u-ca=gregory]&lt;/code&gt; are invalid for &lt;code&gt;Temporal.PlainMonthDay&lt;/code&gt;, whereas &lt;code&gt;07-01&lt;/code&gt; is valid for 1 July in the &lt;code&gt;iso8601&lt;/code&gt; calendar.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainYearMonth&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2026-07&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// July 2026 in `iso8601`&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainMonthDay&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;07-01&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// 1st July in `iso8601`&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainYearMonth&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2026-07[u-ca=gregory]&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainMonthDay&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;07-01[u-ca=gregory]&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// parse error&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;You can create a &lt;code&gt;Temporal.PlainMonthDay&lt;/code&gt; from a month number and day in &lt;code&gt;iso8601&lt;/code&gt;, but you cannot do so for other calendars. You must provide either the year or the month code.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainMonthDay&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; month&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; day&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// 1st January in `iso8601`&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainMonthDay&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  month&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  day&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  calendar&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;gregory&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// error&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainMonthDay&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  year&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 2026&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  month&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  day&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  calendar&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;gregory&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// or...&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainMonthDay&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  monthCode&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;M01&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  day&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  calendar&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;gregory&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;This is because the month number for a given month can vary by year in calendars with leap months, such as the Hebrew and Chinese calendars. For example, the month of Tamuz in the Hebrew calendar is the 10th month in regular years, but the 11th month in leap years due to the insertion of an intercalary month (Adar I). When &lt;code&gt;Temporal.PlainMonthDay.from&lt;/code&gt; receives a month number without year information, it throws an error for all calendars other than &lt;code&gt;iso8601&lt;/code&gt;, rather than only throwing for calendars that have leap months. I guess this rule was chosen for consistency across non-ISO calendars.&lt;/p&gt;&#10;&lt;h3&gt;Friction between Temporal and &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;&lt;/h3&gt;&#10;&lt;p&gt;Most developers will not need to use the &lt;code&gt;gregory&lt;/code&gt; calendar directly in Temporal, so the differences described above rarely cause issues. However, friction does arise when formatting a &lt;code&gt;Temporal.PlainYearMonth&lt;/code&gt; or &lt;code&gt;Temporal.PlainMonthDay&lt;/code&gt; with &lt;code&gt;toLocaleString&lt;/code&gt; or &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; formatter&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Intl&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;DateTimeFormat&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;en-GB&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;formatter&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2026-07-01&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// &quot;01/07/2026&quot;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;formatter&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainYearMonth&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2026-07&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// error&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainYearMonth&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2026-07&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;en-GB&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// error&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;formatter&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainMonthDay&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;01-01&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// error&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainMonthDay&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;01-01&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;en-GB&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// error&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;Why does this happen?&lt;/p&gt;&#10;&lt;p&gt;While Temporal objects default to the &lt;code&gt;iso8601&lt;/code&gt; calendar, &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; instances default to &lt;code&gt;gregory&lt;/code&gt; for most locales.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Intl&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;DateTimeFormat&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;ja&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;resolvedOptions&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;calendar&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// &quot;gregory&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;This mismatch does not cause an error when formatting a &lt;code&gt;Temporal.PlainDate&lt;/code&gt;. Because &lt;code&gt;iso8601&lt;/code&gt; is the default and transparent calendar, the date in &lt;code&gt;iso8601&lt;/code&gt; is automatically converted to the calendar of the &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; instance. This conversion applies to all calendars (not only for &lt;code&gt;gregory&lt;/code&gt;), consistent with the principle that &lt;code&gt;iso8601&lt;/code&gt; is special while &lt;code&gt;gregory&lt;/code&gt; is treated like any other calendar.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; date&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2026-07-01&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Intl&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;DateTimeFormat&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;ja&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;date&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// &quot;2026/7/1&quot;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Intl&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;DateTimeFormat&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;en-u-ca-hebrew&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;date&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// &quot;16 Tamuz 5786&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;However, because &lt;code&gt;Temporal.PlainYearMonth&lt;/code&gt; and &lt;code&gt;Temporal.PlainMonthDay&lt;/code&gt; are calendar-dependent and cannot be converted between calendars, a mismatch between the calendar on the Temporal object (&lt;code&gt;iso8601&lt;/code&gt;) and the formatter (&lt;code&gt;gregory&lt;/code&gt;) throws an error. One might argue that &lt;code&gt;iso8601&lt;/code&gt; and &lt;code&gt;gregory&lt;/code&gt; are same and that JavaScript should simply overlook the difference, but such an exception would contradict the core design principle.&lt;/p&gt;&#10;&lt;p&gt;Formatting dates with the &lt;code&gt;iso8601&lt;/code&gt; calendar is usually not what developers want, so the proper workaround is to construct a &lt;code&gt;Temporal.PlainYearMonth&lt;/code&gt; or &lt;code&gt;Temporal.PlainMonthDay&lt;/code&gt; using the &lt;code&gt;gregory&lt;/code&gt; calendar before formatting:&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; pym&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainYearMonth&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2026-07&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; pymGregory&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainYearMonth&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  year&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; pym&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;year&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  month&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; pym&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;month&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  calendar&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;gregory&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Intl&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;DateTimeFormat&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;ja&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;pymGregory&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// &quot;2026/7&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h2&gt;Conclusion&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;iso8601&lt;/code&gt;: The Gregorian calendar as a culturally neutral data model, primarily used in &lt;code&gt;Temporal&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;gregory&lt;/code&gt;: The Gregorian calendar as used in the real world with cultural conventions and eras, primarily used in &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;</content><updated>2026-09-13T19:15:00Z</updated></entry><entry><id>tag:dnevnik.fabon.info,2026:entry:2026-07-08/11ty-markdown-exit</id><title>How to use markdown-exit (or another Markdown renderer) in Eleventy</title><link href="https://dnevnik.fabon.info/posts/2026/07/08/11ty-markdown-exit/" /><content type="html">&lt;h2&gt;Problem&lt;/h2&gt;&#10;&lt;p&gt;Eleventy uses &lt;a href=&quot;https://github.com/markdown-it/markdown-it&quot;&gt;markdown-it&lt;/a&gt; as its default Markdown renderer. However, markdown-it forces plugins to be synchronous, which makes it impossible to, for example, fetch Open Graph data or optimize images during Markdown rendering. &lt;a href=&quot;https://shiki.style/&quot;&gt;Shiki&lt;/a&gt;, my favorite syntax highlighter, is also asynchronous by default. Shiki can be run synchronously, but we would have to load all languages in advance or manually specify the languages used in our Markdown files. Neither solution is ideal.&lt;/p&gt;&#10;&lt;p&gt;Several projects attempt to address this issue. &lt;a href=&quot;https://github.com/antfu/markdown-it-async&quot;&gt;markdown-it-async&lt;/a&gt;, a thin wrapper for markdown-it authored by one of the maintainers of Shiki, adds support for asynchronous syntax highlighting. &lt;a href=&quot;https://markdown-exit.pages.dev/&quot;&gt;markdown-exit&lt;/a&gt; is a drop-in replacement for markdown-it that addresses a broader set of markdown-it&apos;s issues, including support for asynchronous rendering.&lt;/p&gt;&#10;&lt;p&gt;I read the &lt;a href=&quot;https://www.11ty.dev/docs/languages/markdown/&quot;&gt;&amp;quot;Markdown&amp;quot; page&lt;/a&gt; of the official documentation and learned how to modify markdown-it options or add plugins. Since markdown-exit is compatible with markdown-it, we can replace the markdown-it instance with markdown-exit via &lt;code&gt;setLibrary&lt;/code&gt; as described in the documentation, but this does not enable asynchronous rendering. Eleventy calls the &lt;code&gt;render&lt;/code&gt; method of the library instance and expects it to return a string.&lt;/p&gt;&#10;&lt;p&gt;It took me a while to find a solution because I had been stuck on using the default &lt;code&gt;setLibrary&lt;/code&gt; approach. In reality, the best solution doesn&apos;t even rely on compatibility between markdown-it and markdown-exit.&lt;/p&gt;&#10;&lt;h2&gt;Solution&lt;/h2&gt;&#10;&lt;p&gt;Actually, Eleventy does not crash and still generates HTML correctly even if the &lt;code&gt;render&lt;/code&gt; method returns &lt;code&gt;Promise&amp;lt;string&amp;gt;&lt;/code&gt;, so the following code &lt;em&gt;accidentally&lt;/em&gt; works fine. Of course, this behavior is undocumented and could change at any time.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// It works, but...&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;setLibrary&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;md&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; render&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; md&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;renderAsync&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;bind&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;md&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;Fortunately, Eleventy is flexible enough to allow us to use a completely different Markdown renderer. This behavior is explicitly documented.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href=&quot;https://www.11ty.dev/docs/languages/custom/#overriding-or-extending-an-existing-template-language&quot;&gt;Custom — Eleventy&lt;/a&gt;&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; shikiPlugin&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;@shikijs/markdown-exit&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; createMarkdownExit&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;markdown-exit&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// Eleventy enables the `html` option by default&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; md&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; createMarkdownExit&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; html&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;md&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;shikiPlugin&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; theme&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;nord&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;addExtension&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;md&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  async&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; compile&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; path&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; md&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;renderAsync&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;It is worth noting that we could even choose a library that is not compatible with markdown-it, such as Remark or Marked. However, I still use markdown-exit because it is the fastest Markdown renderer that Shiki officially supports; it is noticeably faster than Remark &amp;amp; Rehype.&lt;/p&gt;&#10;&lt;h2&gt;Source code&lt;/h2&gt;&#10;&lt;p&gt;This blog is built using Eleventy v4 alpha and markdown-exit. Note that the blog&apos;s technology stack may change in the future.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href=&quot;https://github.com/fabon-f/dnevnik.fabon.info/blob/9d1866497fefc00284f83cf12a6ef0dd9b4f10e8/eleventy.config.ts#L37-L41&quot;&gt;&lt;code&gt;eleventy.config.ts&lt;/code&gt; at 9d18664&lt;/a&gt;&lt;/p&gt;&#10;</content><updated>2026-07-07T15:10:00Z</updated></entry><entry><id>tag:dnevnik.fabon.info,2026:entry:2026-04-30/temporal-polyfill-lite</id><title>I made another Temporal polyfill from scratch</title><link href="https://dnevnik.fabon.info/posts/2026/04/30/temporal-polyfill-lite/" /><content type="html">&lt;p&gt;It&apos;s because existing polyfills were insufficient for me.&lt;/p&gt;&#10;&lt;h2&gt;Brief summary&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;I created &lt;a href=&quot;https://npmx.dev/package/temporal-polyfill-lite&quot;&gt;&lt;code&gt;temporal-polyfill-lite&lt;/code&gt;&lt;/a&gt;, a lightweight Temporal polyfill.&lt;/li&gt;&#10;&lt;li&gt;It supports the final spec of Temporal and is compatible with the official TypeScript type definition.&lt;/li&gt;&#10;&lt;li&gt;For the majority of developers (those who only need the Gregorian calendar), it&apos;s the smallest Temporal polyfill available as of April 2026.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2&gt;The state of ECMAScript Temporal&lt;/h2&gt;&#10;&lt;p&gt;The Temporal proposal recently reached Stage 4. Firefox shipped it in May of last year, and Chrome followed suit this January. Node.js is planning to ship Temporal in its next major version (v26), which is set for release this May&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://dnevnik.fabon.info/posts/2026/04/30/temporal-polyfill-lite/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;. Safari is lagging a bit behind, but implementation is underway, so it&apos;s only a matter of time&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://dnevnik.fabon.info/posts/2026/04/30/temporal-polyfill-lite/#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;. We can finally start using Temporal!&lt;/p&gt;&#10;&lt;p&gt;Well, we still need a polyfill for now. Until recently, there were only two polyfills: &lt;a href=&quot;https://npmx.dev/package/@js-temporal/polyfill&quot;&gt;&lt;code&gt;@js-temporal/polyfill&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://npmx.dev/package/temporal-polyfill&quot;&gt;&lt;code&gt;temporal-polyfill&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2&gt;Existing polyfills&lt;/h2&gt;&#10;&lt;h3&gt;&lt;code&gt;@js-temporal/polyfill&lt;/code&gt;&lt;/h3&gt;&#10;&lt;p&gt;&lt;code&gt;@js-temporal/polyfill&lt;/code&gt; is based on the reference polyfill from the &lt;a href=&quot;https://github.com/tc39/proposal-temporal&quot;&gt;Temporal proposal repository&lt;/a&gt; and is maintained by some of the proposal&apos;s champions. The reference polyfill itself is mainly for spec verification and doesn&apos;t aim to be production-ready, so several performance optimizations were added to make it suitable for real-world use. Sounds good so far, right?&lt;/p&gt;&#10;&lt;p&gt;The downside, however, is the massive bundle size: 160 kB minified and 45 kB gzipped. For comparison, the core of Moment.js is 60 kB minified and 18.5 kB gzipped. Compared to other date and time libraries, this polyfill is excessively large for frontend projects. The original code is a literal, word-for-word reference implementation of the spec and wasn&apos;t built with bundle size in mind. While it&apos;s relatively easy to optimize performance later, optimizing bundle size is much more difficult.&lt;/p&gt;&#10;&lt;p&gt;Moreover, while the upstream reference polyfill is actively maintained, &lt;code&gt;@js-temporal/polyfill&lt;/code&gt; wasn&apos;t for a while. The champions always fix reported bugs quickly and reflect spec changes immediately in the proposal repository, but those changes hadn&apos;t been merged into &lt;code&gt;@js-temporal/polyfill&lt;/code&gt; for ten months (though merging has recently resumed, e.g., &lt;a href=&quot;https://github.com/js-temporal/temporal-polyfill/pull/361&quot;&gt;js-temporal/temporal-polyfill#361&lt;/a&gt;). I want to clarify that &lt;strong&gt;I am not blaming the maintainers&lt;/strong&gt;. Maintaining both the upstream and the fork is tough work, and the champions have a massive number of tasks to handle during the standardization process.&lt;/p&gt;&#10;&lt;h3&gt;&lt;code&gt;temporal-polyfill&lt;/code&gt;&lt;/h3&gt;&#10;&lt;p&gt;On the other hand, &lt;code&gt;temporal-polyfill&lt;/code&gt; has a much smaller bundle size: 57 kB minified and 20 kB gzipped. It&apos;s still a bit large but acceptable, considering the Temporal spec is over 10,000 lines long. Unfortunately, like &lt;code&gt;@js-temporal/polyfill&lt;/code&gt;, it refers to an outdated version of the spec. Consequently, various bugs and confusing behaviors that were resolved in the final spec have remained for months (note: updates seem to be &lt;a href=&quot;https://github.com/fullcalendar/temporal-polyfill/issues/94&quot;&gt;in progress&lt;/a&gt; now, but aren&apos;t finished yet). Some issues are rare edge cases, but others can bite anyone using Temporal in the real world. Here are a few examples:&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// regular DST change:&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;ZonedDateTime&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2025-11-02T01:01:00-07:00[America/Vancouver]&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;until&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2025-11-02T01:00:00-08:00[America/Vancouver]&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;  largestUnit&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;days&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// Throws `RangeError` in both polyfills,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// but should be PT59M (59 minutes) per the final spec&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainYearMonth&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2024-02&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;subtract&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; years&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; overflow&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;reject&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// Throws `RangeError` in both polyfills,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// but should be 2023-02 (February 2023) per the final spec&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;In particular, era definitions for calendars were finalized relatively recently, and existing polyfills haven&apos;t caught up yet. Developers working with non-ISO calendars will likely run into trouble here:&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2026-04-01[u-ca=gregory]&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;era&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// Returns &quot;gregory&quot; in both polyfills, but &quot;ce&quot; per the final spec&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainDate&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2026-04-01[u-ca=hebrew]&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;era&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// Returns undefined in both polyfills, but &quot;am&quot; per the final spec&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;&lt;code&gt;temporal-polyfill&lt;/code&gt; also has some bugs related to time zones and date arithmetic. While bugs are inevitable, they haven&apos;t been fixed for a while, which can hinder the adoption of Temporal. For me, these were deal-breakers; I believe that reliable date arithmetic and time zone calculations are exactly the reason for being of Temporal. I didn&apos;t want to implement workarounds just because of a polyfill.&lt;/p&gt;&#10;&lt;p&gt;Once again, &lt;strong&gt;I don&apos;t want to blame the maintainer&lt;/strong&gt;. Maintaining a Temporal polyfill is incredibly hard work (likely harder than you&apos;d imagine), and criticizing OSS maintainers for a lack of bandwidth or time goes against the spirit of open source.&lt;/p&gt;&#10;&lt;h2&gt;Why is it so hard to implement a polyfill?&lt;/h2&gt;&#10;&lt;p&gt;Generally, while writing a polyfill requires specialized knowledge, it is not as hard as you might think: read the spec and implement it word for word. If you&apos;re interested in ECMAScript, writing a polyfill is usually a great place to start.&lt;/p&gt;&#10;&lt;p&gt;Temporal, however, is a clear exception. It&apos;s a gigantic proposal with 13,000 lines of spec text. For context, ECMA-262 (the core JS spec) is 53,000 lines, and ECMA-402 (the i18n spec) is 10,000 lines before Temporal is merged. It is the largest addition in the history of ECMAScript. Let alone implementation, even understanding the structure of such a huge spec is difficult. It requires deep knowledge of ECMA-402 and i18n, especially time zones, calendars, and &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;, in addition to knowledge necessary for typical polyfill authors.&lt;/p&gt;&#10;&lt;h2&gt;The options&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;temporal-polyfill&lt;/code&gt; was virtually my only option, but it had critical issues, and it seemed like nobody was working on them at the time. Literally nobody. That&apos;s understandable because not many developers have the ability, willingness, and time to fix &lt;code&gt;temporal-polyfill&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;I&apos;m just a graduate student&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://dnevnik.fabon.info/posts/2026/04/30/temporal-polyfill-lite/#fn3&quot; id=&quot;fnref3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt; who loves web technologies; I don&apos;t belong to any standards bodies or browser vendors. However, to make a long story short, I had some knowledge of Temporal and i18n, the ability to dive into the spec, and plenty of enthusiasm for the JavaScript ecosystem. I felt like I had an obligation to do something useful instead of just posting &amp;quot;any updates?&amp;quot; comments on GitHub.&lt;/p&gt;&#10;&lt;p&gt;At first, I tried to fix the bugs in &lt;code&gt;temporal-polyfill&lt;/code&gt; and sent &lt;a href=&quot;https://github.com/fullcalendar/temporal-polyfill/pull/79&quot;&gt;a pull request&lt;/a&gt;. Unfortunately, it&apos;s been open for six months and hasn&apos;t been merged yet. I wanted to fix the remaining time zone bugs too, but I found it hard to do so while respecting the original author&apos;s architectural decisions. It would have been even harder to debate design on GitHub for me. Furthermore, the project&apos;s structure differed from the spec, making it difficult for me to track down the root cause of the arithmetic bugs. I just wasn&apos;t smart enough to map the spec text to the existing code.&lt;/p&gt;&#10;&lt;p&gt;Eventually, I started considering a &amp;quot;crazier&amp;quot; option: building a polyfill from scratch. It was not only because there was no other option for me. I had been curious to see how small a polyfill could be if it only supported the Gregorian calendar. I suspected that a lot of the bulk in existing polyfills came from complex non-Gregorian calendars that only a tiny fraction of developers actually need.&lt;/p&gt;&#10;&lt;h2&gt;Requirements and design decisions&lt;/h2&gt;&#10;&lt;p&gt;I started building &lt;code&gt;temporal-polyfill-lite&lt;/code&gt; with a different set of design principles.&lt;/p&gt;&#10;&lt;h3&gt;Project structure&lt;/h3&gt;&#10;&lt;p&gt;&lt;code&gt;temporal-polyfill-lite&lt;/code&gt; is almost a word-for-word implementation of the spec. This allows the project to benefit directly from the work of spec writers and implementers.&lt;/p&gt;&#10;&lt;p&gt;The spec text is extremely well-maintained pseudocode that has been reviewed and debugged by many people (including myself). Following it closely reduces bugs. It also makes debugging easier because I can compare my code directly to the reference polyfill.&lt;/p&gt;&#10;&lt;p&gt;If the spec text is simplified upstream, I can easily apply those simplifications to my code. Conversely, if I find a way to simplify my code, I might even be able to contribute that change back to the spec.&lt;/p&gt;&#10;&lt;h3&gt;No protection against global namespace mutation&lt;/h3&gt;&#10;&lt;p&gt;&lt;code&gt;temporal-polyfill-lite&lt;/code&gt; won&apos;t work if built-in methods (like &lt;code&gt;String.prototype.replace&lt;/code&gt; or &lt;code&gt;Array.prototype.map&lt;/code&gt;) are deleted or modified. While this isn&apos;t strictly spec-compliant, does it really matter? If someone invasively mutates the global namespace, your entire application is going to break anyway. Protecting a polyfill from such mutations (using the &amp;quot;primordials&amp;quot; trick) sacrifices both bundle size and performance for very little practical gain.&lt;/p&gt;&#10;&lt;p&gt;For more on this, I recommend the excellent article &amp;quot;&lt;a href=&quot;https://43081j.com/2026/03/three-pillars-of-javascript-bloat&quot;&gt;The Three Pillars of JavaScript Bloat&lt;/a&gt;&amp;quot;.&lt;/p&gt;&#10;&lt;h3&gt;Bundle size&lt;/h3&gt;&#10;&lt;p&gt;From the start, &lt;code&gt;temporal-polyfill-lite&lt;/code&gt; was built with bundle size as a priority. I&apos;ve applied various reduction techniques throughout the codebase.&lt;/p&gt;&#10;&lt;h3&gt;Internal representation of large integers&lt;/h3&gt;&#10;&lt;p&gt;Temporal supports timestamps and durations with nanosecond precision. &amp;quot;Epoch nanoseconds&amp;quot; and &amp;quot;time durations&amp;quot; can exceed JavaScript&apos;s maximum safe integer (53-bit) or even a 64-bit integer.&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;temporal-polyfill-lite&lt;/code&gt; represents these large integers as an array of two numbers (a quotient and a remainder of &lt;code&gt;x / 8.64e13&lt;/code&gt;) internally, rather than using &lt;code&gt;BigInt&lt;/code&gt;. I borrowed this clever idea from &lt;code&gt;temporal-polyfill&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h3&gt;Browser support&lt;/h3&gt;&#10;&lt;p&gt;&lt;code&gt;temporal-polyfill-lite&lt;/code&gt; works in any browser released after 2020 (it uses features from &amp;quot;Baseline 2020&amp;quot;).&lt;/p&gt;&#10;&lt;p&gt;Since it doesn&apos;t rely on &lt;code&gt;BigInt&lt;/code&gt; internally, it could work in older browsers if you transpile &lt;code&gt;temporal-polyfill-lite&lt;/code&gt; and inject polyfills for APIs used internally (since code using &lt;code&gt;BigInt&lt;/code&gt; can&apos;t be transpiled or polyfilled at all).&lt;/p&gt;&#10;&lt;h3&gt;Time zones&lt;/h3&gt;&#10;&lt;p&gt;&lt;code&gt;temporal-polyfill-lite&lt;/code&gt; supports all time zones. This is definitely a long-awaited feature. Who wants to use Temporal without proper time zone support?&lt;/p&gt;&#10;&lt;h3&gt;Calendars&lt;/h3&gt;&#10;&lt;p&gt;By default, it only supports &lt;code&gt;iso8601&lt;/code&gt; and &lt;code&gt;gregory&lt;/code&gt; calendars, which keeps the bundle small for most developers. Support for &lt;code&gt;gregory&lt;/code&gt; is actually required if you want to format &lt;code&gt;Temporal.PlainMonthDay&lt;/code&gt; or &lt;code&gt;Temporal.PlainYearMonth&lt;/code&gt; using &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; or &lt;code&gt;toLocaleString&lt;/code&gt;, due to some quirks in those classes:&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainYearMonth&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2026-04&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;en-US&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;  dateStyle&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;long&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// Throws a confusing &quot;calendar mismatch&quot; error&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainYearMonth&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2026-04&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;en-US&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;  calendar&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;iso8601&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;  dateStyle&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;long&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// Returns &quot;2026 April&quot; in Chrome/Firefox, which isn&apos;t usually what you want&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// (this format is not used in America).&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// Node.js v25 returns a broken result: &quot;2026 &quot;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Temporal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;PlainYearMonth&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;2026-04-01[u-ca=gregory]&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;en-US&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; dateStyle&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;long&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// &quot;April 2026&quot; (exactly what you&apos;d expect)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h2&gt;Implementation&lt;/h2&gt;&#10;&lt;p&gt;It was a long, tough journey.&lt;/p&gt;&#10;&lt;p&gt;I started the project in June 2025, but it stalled for months because I didn&apos;t have the time to commit to it. I restarted it from zero in December 2025 (reusing many parts of the old code) and finally released the initial version in late January 2026. It took about seven weeks from the &amp;quot;reboot&amp;quot; to the first release.&lt;/p&gt;&#10;&lt;p&gt;Thanks to the enormous effort of the champions and implementers to expand &lt;a href=&quot;https://github.com/tc39/test262&quot;&gt;test262&lt;/a&gt;, Temporal has almost 100% test coverage in test262 now. A fast test runner developed by the champions (&lt;a href=&quot;https://github.com/js-temporal/temporal-test262-runner&quot;&gt;&lt;code&gt;temporal-test262-runner&lt;/code&gt;&lt;/a&gt;) was a lifesaver, significantly reducing test execution time. The Temporal proposal repository also has &amp;quot;thorough tests&amp;quot;, scripts for testing implementation against a vast number of test cases. I found various bugs in my implementation with the aid of these tests.&lt;/p&gt;&#10;&lt;p&gt;I should mention that I was a latecomer. Unlike other polyfill authors, I implemented the polyfill based on the almost finalized spec. I didn&apos;t have to navigate the major normative changes (like the big scope reduction in June 2024) that the pioneers had to deal with. I have immense respect for those who kept their polyfills updated for years as the spec evolved.&lt;/p&gt;&#10;&lt;p&gt;As a side effect of building this, I found and reported several bugs and errors in the spec text and even submitted a pull request to improve it (&lt;a href=&quot;https://github.com/tc39/proposal-temporal/pull/3271&quot;&gt;tc39/proposal-temporal#3271&lt;/a&gt;). I&apos;m very happy to have contributed to the proposal in some small way.&lt;/p&gt;&#10;&lt;p&gt;I know some people think human coding is obsolete. Claude Code or Codex could probably write a Temporal polyfill in days or even hours. But I wrote every line by hand, and I don&apos;t regret it. It was a &amp;quot;desirable difficulty&amp;quot; that expanded my knowledge. Understanding the details of the spec and implementation, such as how to deal with an &lt;a href=&quot;https://github.com/tc39/proposal-temporal/issues/2910&quot;&gt;unusual time zone transition in Canada 100 years ago&lt;/a&gt; or the quirks of floating-point arithmetic in JavaScript, isn&apos;t a &amp;quot;boring task&amp;quot; I want to outsource to an agent; it&apos;s exactly what I find interesting. For me, coding is like DIY and isn&apos;t something I have to &amp;quot;streamline&amp;quot; at the expense of the joy of understanding how things work&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://dnevnik.fabon.info/posts/2026/04/30/temporal-polyfill-lite/#fn4&quot; id=&quot;fnref4&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;&#10;&lt;h3&gt;Time zone calculations&lt;/h3&gt;&#10;&lt;p&gt;The only way to access the time zone database in JavaScript engines is by parsing the output of &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; with the &lt;code&gt;timeZone&lt;/code&gt; option. Parsing localized strings is usually a terrible idea, as formats vary between engines and versions, but there&apos;s no other choice. Fortunately, the &lt;code&gt;formatToParts&lt;/code&gt; method returns structured data that is relatively reliable to parse.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Intl&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;DateTimeFormat&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;en&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;  year&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;  month&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;  day&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;  hour&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;  minute&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;  second&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;  hour12&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;  timeZone&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;Asia/Tokyo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;formatToParts&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// Result:&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;[&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;month&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;literal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;day&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;literal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;year&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;1970&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;literal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;hour&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;09&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;literal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;minute&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;00&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;literal&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;second&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;00&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;Essentially, we can calculate the UTC offset by comparing the formatted parts to the original timestamp. Most date and time libraries (Luxon, Day.js with &lt;code&gt;tz&lt;/code&gt; plugin, &lt;code&gt;@date-fns/tz&lt;/code&gt;, etc.) and other Temporal polyfills use a similar approach too.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; getOffsetMilliseconds&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;epochSeconds&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; number&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; timeZone&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; parts&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; Intl&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;DateTimeFormat&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;en&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;    year&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;    month&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;    day&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;    hour&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;    minute&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;    second&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;numeric&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;    hour12&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;    timeZone&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  }&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;formatToParts&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;epochSeconds&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 1000&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; units&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;year&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;month&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;day&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;hour&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;minute&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;second&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;localYear&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; localMonth&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; localDay&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; localHour&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; localMinute&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; localSecond&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;    units&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;unit&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; parseInt&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;parts&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;find&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; p&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; unit&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; (&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;    Date&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;UTC&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;      localYear&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;      localMonth&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;      localDay&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;      localHour&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;      localMinute&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;      localSecond&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;    ) &lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;-&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;    epochSeconds&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 1000&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;  )&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getOffsetMilliseconds&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;Europe/London&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // 3600000 (UTC+1)&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getOffsetMilliseconds&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;America/New_York&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // -18000000 (UTC-5)&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getOffsetMilliseconds&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;Asia/Tokyo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // 32400000 (UTC+9)&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;getOffsetMilliseconds&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;Africa/Monrovia&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // -2670000 (UTC-0:44:30)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;Because &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; is slow, the polyfill uses an LRU cache. However, the current mechanism is far from ideal. It caches offsets for every second, even though offsets rarely change. Most countries and regions don&apos;t use DST (daylight saving time), and time zone offsets change at most twice per year in time zones where DST is observed. Time zone offset transitions for political reasons are even less common. I&apos;m currently working on a more efficient caching algorithm (&lt;a href=&quot;https://github.com/fabon-f/temporal-polyfill-lite/issues/26&quot;&gt;issue&lt;/a&gt;).&lt;/p&gt;&#10;&lt;h2&gt;Reducing bundle size&lt;/h2&gt;&#10;&lt;p&gt;One of my main goals was a small bundle size. I wrote a script to measure the size (with and without compression) to ensure every optimization actually worked. You can&apos;t optimize what you don&apos;t measure.&lt;/p&gt;&#10;&lt;p&gt;If you look at minified JavaScript code, you&apos;ll notice many long property names. That&apos;s because mangling properties is unsafe; it can easily break your code. Properties in public APIs or internal properties accessed by the bracket operator can&apos;t be mangled.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// original:&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; fooBarBaz&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; prop&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;fooBarBaz&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Object&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;keys&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // [&quot;fooBarBaz&quot;]&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;prop&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // 0&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// after mangling properties:&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; a&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B48EAD&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; prop&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;fooBarBaz&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;Object&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;keys&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // [&quot;a&quot;]&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;prop&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#616E88&quot;&gt; // undefined&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;Initially, I tried to write the whole polyfill using tuples instead of objects, but that was almost impossible to maintain. No one wants to remember that &lt;code&gt;isoDateTime[0][1]&lt;/code&gt; actually means &lt;code&gt;isoDateTime.date.month&lt;/code&gt;. So, I decided to introduce property mangling when I &amp;quot;rebooted&amp;quot; the project.&lt;/p&gt;&#10;&lt;p&gt;Instead of making a long list of properties we want to preserve, I introduced a simple naming convention: every internal property that should be mangled starts with a &lt;code&gt;$&lt;/code&gt; (e.g., &lt;code&gt;$isoDate&lt;/code&gt;) or &lt;code&gt;_&lt;/code&gt;. This allows the minifier to safely mangle internal properties while leaving the public API intact. I picked up this idea from &lt;a href=&quot;https://zenn.dev/mizchi/articles/mangle-best-practice&quot;&gt;this article&lt;/a&gt; (&lt;a href=&quot;https://zenn.dev/mizchi/articles/mangle-best-practice?locale=en&quot;&gt;English version&lt;/a&gt; available too) on JavaScript minification.&lt;/p&gt;&#10;&lt;p&gt;I also prioritized expressions over statements. Multiple function calls can be merged using the comma operator, and &lt;code&gt;if&lt;/code&gt; statements can be converted into conditional or logical operators if the block doesn&apos;t contain any statements.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  bar&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;  baz&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// after minification:&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;bar&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; baz&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;It might seem weird to replace &lt;code&gt;throw&lt;/code&gt; statements with function calls that throw errors, but it actually reduced the bundle size significantly because it allowed the minifier to optimize the code further. I also removed intermediate variables wherever possible to keep the code as a series of expressions.&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// before:&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; aaaaa&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;    throw&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; RangeError&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; bar&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; baz&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; qux&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;bar&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// code above is minified like below:&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; aaaaa&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; RangeError&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt; t&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; baz&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; qux&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;t&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// after:&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; throwRangeError&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  throw&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; RangeError&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; aaaaa&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;    throwRangeError&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; qux&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;baz&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;())&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;// code above is minified like below:&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; aaaaa&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#616E88&quot;&gt;  // Note that `throwRangeError` will be also mangled in the production build.&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; throwRangeError&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt; qux&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#88C0D0&quot;&gt;baz&lt;/span&gt;&lt;span style=&quot;color:#D8DEE9FF&quot;&gt;()))&lt;/span&gt;&lt;span style=&quot;color:#81A1C1&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;Compared to the initial release, the bundle size has dropped by 15% (from 60 kB to 52 kB) minified, and 10% (from 19.7 kB to 18 kB) gzipped. What a huge win!&lt;/p&gt;&#10;&lt;h2&gt;Support for non-Gregorian calendars&lt;/h2&gt;&#10;&lt;p&gt;After spending a few weeks to reduce the bundle size, I became confident that the whole codebase was optimized enough. As a next step, I looked into adding non-Gregorian calendars without increasing the bundle size for the majority of users (&lt;a href=&quot;https://github.com/fabon-f/temporal-polyfill-lite/issues/6&quot;&gt;issue&lt;/a&gt;). It had been in my backlog for months, but I hadn&apos;t figured out yet how to implement it.&lt;/p&gt;&#10;&lt;p&gt;I wanted something like &lt;a href=&quot;https://doc.rust-lang.org/cargo/reference/features.html&quot;&gt;Rust&apos;s feature flags&lt;/a&gt;, but that doesn&apos;t really exist in the JavaScript ecosystem. After human deep research and ultrathinking, I decided to use custom conditions for conditional exports and imports. Fortunately, all toolchains I use in this project (Node.js, TypeScript compiler, and Rolldown) support this.&lt;/p&gt;&#10;&lt;p&gt;The &lt;code&gt;package.json&lt;/code&gt; looks like this:&lt;/p&gt;&#10;&lt;pre class=&quot;shiki nord&quot; style=&quot;background-color:#2e3440ff;color:#d8dee9ff&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  &quot;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    &quot;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;./dist/index.js&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    &quot;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;./calendars-full&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;./dist/calendars/index.js&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  &quot;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;imports&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    &quot;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;#calendricalCalculations&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;      &quot;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;nonIsoCalendars&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;./src/internal/calendars/all.ts&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;      &quot;&lt;/span&gt;&lt;span style=&quot;color:#8FBCBB&quot;&gt;default&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A3BE8C&quot;&gt;./src/internal/calendars/basic.ts&lt;/span&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;&#10;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ECEFF4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;The polyfill has two entrypoints. The standard one is built without the &lt;code&gt;nonIsoCalendars&lt;/code&gt; condition, while &lt;code&gt;calendars-full&lt;/code&gt; includes it. Both &lt;code&gt;all.ts&lt;/code&gt; and &lt;code&gt;basic.ts&lt;/code&gt; export identical functions with different sets of supported calendars (see &lt;a href=&quot;https://github.com/fabon-f/temporal-polyfill-lite/pull/7&quot;&gt;fabon-f/temporal-polyfill-lite#7&lt;/a&gt; for details).&lt;/p&gt;&#10;&lt;h3&gt;Calendrical calculations&lt;/h3&gt;&#10;&lt;p&gt;While JavaScript engines can calculate non-Gregorian dates internally, there&apos;s no direct API to access those results (this is exactly what Temporal does). Unlike time zone calculations, parsing the output of &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; for non-Gregorian calendars is theoretically possible but unreliable, because formats produced by &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; for those calendars are far more inconsistent than for Gregorian across JavaScript engines or even operating systems (cf. &lt;a href=&quot;https://github.com/js-temporal/temporal-polyfill/issues/284&quot;&gt;js-temporal/temporal-polyfill#284&lt;/a&gt;).&lt;/p&gt;&#10;&lt;p&gt;Instead, I implemented the calendrical calculations myself for rule-based calendars. In particular, the &lt;code&gt;hebrew&lt;/code&gt; calendar is purely arithmetic but incredibly complex, so I tested my implementation against &lt;a href=&quot;https://github.com/unicode-org/icu4x&quot;&gt;ICU4X&lt;/a&gt; to ensure accuracy. For calendars that require astronomical simulation or historical calendar data (i.e., &lt;code&gt;islamic-umalqura&lt;/code&gt;, &lt;code&gt;persian&lt;/code&gt;, &lt;code&gt;chinese&lt;/code&gt;, and &lt;code&gt;dangi&lt;/code&gt;), the polyfill defers to the native &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2&gt;The result&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;temporal-polyfill-lite&lt;/code&gt; is currently the only Temporal polyfill that follows the final spec and is compatible with the &lt;a href=&quot;https://devblogs.microsoft.com/typescript/announcing-typescript-6-0/#new-types-for-temporal&quot;&gt;official TypeScript type definitions in v6.0&lt;/a&gt;. In my opinion, it&apos;s also the most reliable one for now. These points are important for developers who want to use Temporal right now, but will be irrelevant in the near future since other polyfills will eventually be updated too. I&apos;m not sure when, but I hope so.&lt;/p&gt;&#10;&lt;p&gt;Instead, the real advantage of &lt;code&gt;temporal-polyfill-lite&lt;/code&gt; is the bundle size. The table below shows the comparison as of April 2026. Note that the result can change in the future, in particular when &lt;code&gt;temporal-polyfill&lt;/code&gt; and &lt;code&gt;@js-temporal/polyfill&lt;/code&gt; reflect the final spec (see &lt;a href=&quot;https://github.com/fabon-f/temporal-polyfill-comparison&quot;&gt;comparison repository&lt;/a&gt; for the latest result). While I&apos;m happy with the results, I still think the &lt;code&gt;calendars-full&lt;/code&gt; version could be a bit smaller.&lt;/p&gt;&#10;&lt;table&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th&gt;&lt;/th&gt;&#10;&lt;th&gt;minified&lt;/th&gt;&#10;&lt;th&gt;gzip&lt;/th&gt;&#10;&lt;th&gt;brotli&lt;/th&gt;&#10;&lt;th&gt;zstd&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td&gt;native&lt;/td&gt;&#10;&lt;td&gt;0 kB&lt;/td&gt;&#10;&lt;td&gt;0 kB&lt;/td&gt;&#10;&lt;td&gt;0 kB&lt;/td&gt;&#10;&lt;td&gt;0 kB&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td&gt;&lt;code&gt;temporal-polyfill-lite&lt;/code&gt;&lt;/td&gt;&#10;&lt;td&gt;52.1 kB&lt;/td&gt;&#10;&lt;td&gt;17.9 kB&lt;/td&gt;&#10;&lt;td&gt;15.9 kB&lt;/td&gt;&#10;&lt;td&gt;18.6 kB&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td&gt;&lt;code&gt;temporal-polyfill-lite/calendars-full&lt;/code&gt;&lt;/td&gt;&#10;&lt;td&gt;63.6 kB&lt;/td&gt;&#10;&lt;td&gt;22.2 kB&lt;/td&gt;&#10;&lt;td&gt;19.6 kB&lt;/td&gt;&#10;&lt;td&gt;23.2 kB&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td&gt;&lt;code&gt;temporal-polyfill&lt;/code&gt;&lt;/td&gt;&#10;&lt;td&gt;57.0 kB&lt;/td&gt;&#10;&lt;td&gt;20.3 kB&lt;/td&gt;&#10;&lt;td&gt;18.2 kB&lt;/td&gt;&#10;&lt;td&gt;21.2 kB&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td&gt;&lt;code&gt;@js-temporal/polyfill&lt;/code&gt;&lt;/td&gt;&#10;&lt;td&gt;159.7 kB&lt;/td&gt;&#10;&lt;td&gt;45.3 kB&lt;/td&gt;&#10;&lt;td&gt;39.3 kB&lt;/td&gt;&#10;&lt;td&gt;47.2 kB&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;I haven&apos;t checked the runtime performance, so perhaps there is room for optimization. Of course I want to speed up the polyfill while not bloating the bundle size.&lt;/p&gt;&#10;&lt;h2&gt;Which polyfill should we use?&lt;/h2&gt;&#10;&lt;p&gt;I&apos;ll try to be as objective and honest as I can.&lt;/p&gt;&#10;&lt;h3&gt;Backend projects&lt;/h3&gt;&#10;&lt;p&gt;Introducing Temporal to backend projects sounds very reasonable and promising, because Temporal enables us to handle dates and times in a reliable manner.&lt;/p&gt;&#10;&lt;p&gt;You don&apos;t have to mind bundle size too much for backend. Rather, the primary requirement for these projects is robustness. I believe &lt;code&gt;temporal-polyfill-lite&lt;/code&gt; is the best polyfill for now, but &lt;code&gt;@js-temporal/polyfill&lt;/code&gt; would also be a good option after it is updated (I hope the update will be done in a few weeks). Both polyfills have very few bugs.&lt;/p&gt;&#10;&lt;p&gt;Anyway, Node.js v26 with support for Temporal will move to LTS this October, so we can remove a Temporal polyfill from backend projects soon.&lt;/p&gt;&#10;&lt;h3&gt;Frontend projects&lt;/h3&gt;&#10;&lt;p&gt;Honestly, it would be too early to use Temporal for most frontend projects since it isn&apos;t even &amp;quot;Baseline Newly available&amp;quot; yet and a Temporal polyfill isn&apos;t tiny. However, Temporal is no longer unstable or experimental, so you can try it. In particular, projects using SSG frameworks such as Astro can benefit from Temporal without increasing JavaScript size.&lt;/p&gt;&#10;&lt;p&gt;In my opinion, &lt;code&gt;temporal-polyfill-lite&lt;/code&gt; is the least painful polyfill for frontend projects, because it is up-to-date, least buggy, and the smallest for most developers, at least for now. &lt;code&gt;temporal-polyfill&lt;/code&gt; can be another option after it is fixed and updated.&lt;/p&gt;&#10;&lt;h2&gt;Conclusion&lt;/h2&gt;&#10;&lt;p&gt;I&apos;ve been following the Temporal proposal for the last two years, always wondering when it would be ready for production. Now I can answer that question with confidence: you can use it today if you really want. If you want to start using Temporal right now, &lt;code&gt;temporal-polyfill-lite&lt;/code&gt; is exactly what you need for the foreseeable future (for a few years at most, I believe).&lt;/p&gt;&#10;&lt;p&gt;If you find any bugs, please feel free to report them on &lt;a href=&quot;https://github.com/fabon-f/temporal-polyfill-lite/issues&quot;&gt;GitHub&lt;/a&gt;. I&apos;ll fix them as soon as possible.&lt;/p&gt;&#10;&lt;p&gt;In closing, it&apos;s a great honor to contribute to Temporal, the unparalleled project in the history of ECMAScript. Long live web standards! Long live ECMAScript!&lt;/p&gt;&#10;&lt;hr class=&quot;footnotes-sep&quot;&gt;&#10;&lt;section class=&quot;footnotes&quot;&gt;&#10;&lt;ol class=&quot;footnotes-list&quot;&gt;&#10;&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;The release is originally planned in 22nd April, but it has been postponed until 4th May due to build issues, mainly caused by Temporal implementation. V8 introduced Rust dependencies (ICU4X and &lt;code&gt;temporal_rs&lt;/code&gt;) for the first time to implement Temporal (cf. &lt;a href=&quot;https://github.com/nodejs/node/issues/58730&quot;&gt;nodejs/node#58730&lt;/a&gt;), therefore Node.js have to add Rust toolchains to build pipeline. The work is basically done, but Node.js developers are still struggling with build errors. &lt;a href=&quot;https://dnevnik.fabon.info/posts/2026/04/30/temporal-polyfill-lite/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;I agree about the part that it&apos;s a matter of time, but I can&apos;t say irresponsibly that Safari will ship Temporal soon. Honestly, I think it can&apos;t happen in this year. There is still great uncertainty, especially problems of calendrical calculations in ICU4C. I even suspect communication between Igalia and Apple doesn&apos;t work well, or implementation of Temporal has low priority, but I hope I&apos;m wrong. &lt;a href=&quot;https://dnevnik.fabon.info/posts/2026/04/30/temporal-polyfill-lite/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Actually, I&apos;m not even a STEM student. I&apos;m currently studying modern Russian history at the University of Tokyo. &lt;a href=&quot;https://dnevnik.fabon.info/posts/2026/04/30/temporal-polyfill-lite/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;That being said, I&apos;m still exploring how to integrate coding agents into my workflow without losing the parts of coding I find fun. &lt;a href=&quot;https://dnevnik.fabon.info/posts/2026/04/30/temporal-polyfill-lite/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;/section&gt;&#10;</content><updated>2026-04-29T17:45:00Z</updated></entry></feed>