Skip to content

Commit

Permalink
Feature/intl timezone (#18)
Browse files Browse the repository at this point in the history
* Added a timezone using Intl.DateTimeFormat

* Refactored

* Refactored

* Updated the readme

* Updated the docs

* Added more tests

---------

Co-authored-by: Rob Blackbourn <rob.blackbourn@gmail.com>
  • Loading branch information
rob-blackbourn and Rob Blackbourn committed Mar 9, 2024
1 parent 82965a3 commit 9a25b89
Show file tree
Hide file tree
Showing 36 changed files with 633 additions and 368 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ This project provides utilities for working with dates and timezones.
The JavaScript built-in [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)
object is a simple offset from an epoch. It provides functions
to resolve this into date components (days, months, years, etc.) in both the local
timezone of the browser, and UTC. A browser currently has no access to the hosts
timezone database.
timezone of the browser, and UTC.

This library provides two things:

Expand Down Expand Up @@ -110,3 +109,17 @@ fetch(`https://cdn.jsdelivr.net/npm/@jetblack/tzdata/dist/latest/${timezoneName}
```

The list of all available zones is provided at `dist/latest/zones.json`.

### Intl Timezones

Timezone offsets can be calculated by using Intl.DateTimeFormat. This may be slower
than fetching the database, but it is more convenient.

```js
import { IntlTimezone } from '@jetblack/date'

const tzBrussels = new IntlTimezone('Europe/Brussels')

const newYearsDay = tzBrussels.makeDate(2000, 1, 1).toISOString()
// returns "2000-01-01T01:00:00Z"
```
2 changes: 1 addition & 1 deletion docs/assets/search.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/classes/Calendar.html

Large diffs are not rendered by default.

38 changes: 19 additions & 19 deletions docs/classes/Duration.html

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions docs/classes/HolidayCalendar.html

Large diffs are not rendered by default.

56 changes: 6 additions & 50 deletions docs/classes/IANATimezone.html

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions docs/classes/IntlTimezone.html

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions docs/classes/LocaleInfo.html

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions docs/classes/Timezone.html

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions docs/classes/WeekendCalendar.html

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions docs/enums/BusinessDayConvention.html

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions docs/index.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/interfaces/DatePartResponse.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/interfaces/DayPlurals.html

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions docs/interfaces/I18nSettings.html

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions docs/interfaces/TimezoneOffset.html

Large diffs are not rendered by default.

236 changes: 118 additions & 118 deletions docs/modules.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/pages/guide/calculations.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ <h2>Using IANA Timezones With Date</h2>
<h2>What next ?</h2>
</a>
<p><a href="date-arithmetic.html">Date Arithmetic</a></p>
</div></div><div class="col-4 col-menu menu-sticky-wrap menu-highlight"><nav class="tsd-navigation primary"><ul><li class=""><a href="../../modules.html">Exports</a></li><li class="current pages-entry pages-entry-menu pages-entry-depth-0"><a>Guides</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="getting-started.html">Getting <wbr/>Started</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="general-usage.html">General <wbr/>Usage</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="design-choices.html">Design <wbr/>Choices</a></li><li class="current pages-entry pages-entry-page pages-entry-depth-1"><a href="calculations.html">Calculations</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="date-arithmetic.html">Date <wbr/>Arithmetic</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="timezones.html">Timezones</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="iana-timezones.html">IANA <wbr/>Timezones</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="calendars.html">Calendars</a></li></ul></nav><nav class="tsd-navigation secondary menu-sticky"><ul></ul></nav></div></div></div><footer class="with-border-bottom"><div class="container"><h2>Legend</h2><div class="tsd-legend-group"><ul class="tsd-legend"><li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li><li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li><li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li><li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li></ul></div><h2>Settings</h2><p>Theme <select id="theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></p></div></footer><div class="container tsd-generator"><p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></div><div class="overlay"></div><script src="../../assets/main.js"></script></body></html>
</div></div><div class="col-4 col-menu menu-sticky-wrap menu-highlight"><nav class="tsd-navigation primary"><ul><li class=""><a href="../../modules.html">Exports</a></li><li class="current pages-entry pages-entry-menu pages-entry-depth-0"><a>Guides</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="getting-started.html">Getting <wbr/>Started</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="general-usage.html">General <wbr/>Usage</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="design-choices.html">Design <wbr/>Choices</a></li><li class="current pages-entry pages-entry-page pages-entry-depth-1"><a href="calculations.html">Calculations</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="date-arithmetic.html">Date <wbr/>Arithmetic</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="timezones.html">Timezones</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="iana-timezones.html">IANA <wbr/>Timezones</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="calendars.html">Calendars</a></li></ul></nav><nav class="tsd-navigation secondary menu-sticky"><ul></ul></nav></div></div></div><footer class="with-border-bottom"><div class="container"><h2>Legend</h2><div class="tsd-legend-group"><ul class="tsd-legend"><li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li><li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li><li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li><li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li></ul></div><h2>Settings</h2><p>Theme <select id="theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></p></div></footer><div class="container tsd-generator"><p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></div><div class="overlay"></div><script src="../../assets/main.js"></script></body></html>
2 changes: 1 addition & 1 deletion docs/pages/guide/calendars.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ <h2>Custom Calendars</h2>
</ul>
<pre><code class="language-ts"><span class="hl-0">export</span><span class="hl-1"> </span><span class="hl-4">class</span><span class="hl-1"> </span><span class="hl-9">Target</span><span class="hl-1"> </span><span class="hl-4">extends</span><span class="hl-1"> </span><span class="hl-9">YearlyCalendar</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">constructor</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">super</span><span class="hl-1">(</span><span class="hl-3">&quot;TARGET&quot;</span><span class="hl-1">, [</span><span class="hl-7">6</span><span class="hl-1">, </span><span class="hl-7">0</span><span class="hl-1">]) </span><span class="hl-8">// Saturdays, Sundays.</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-4">protected</span><span class="hl-1"> </span><span class="hl-4">override</span><span class="hl-1"> </span><span class="hl-6">fetchHolidays</span><span class="hl-1">(</span><span class="hl-2">year</span><span class="hl-1">: </span><span class="hl-9">number</span><span class="hl-1">, </span><span class="hl-2">tz</span><span class="hl-1">: </span><span class="hl-9">Timezone</span><span class="hl-1">): </span><span class="hl-9">Set</span><span class="hl-1">&lt;</span><span class="hl-9">number</span><span class="hl-1">&gt; {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">holidays</span><span class="hl-1">: </span><span class="hl-9">Set</span><span class="hl-1">&lt;</span><span class="hl-9">number</span><span class="hl-1">&gt; = </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-9">Set</span><span class="hl-1">()</span><br/><br/><span class="hl-1"> </span><span class="hl-8">// New Year&#39;s Day, January 1st.</span><br/><span class="hl-1"> </span><span class="hl-2">holidays</span><span class="hl-1">.</span><span class="hl-6">add</span><span class="hl-1">(</span><span class="hl-2">tz</span><span class="hl-1">.</span><span class="hl-6">makeDate</span><span class="hl-1">(</span><span class="hl-2">year</span><span class="hl-1">, </span><span class="hl-7">0</span><span class="hl-1">, </span><span class="hl-7">1</span><span class="hl-1">).</span><span class="hl-6">getTime</span><span class="hl-1">())</span><br/><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">year</span><span class="hl-1"> &gt;= </span><span class="hl-7">2000</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">easterSunday</span><span class="hl-1"> = </span><span class="hl-6">easter</span><span class="hl-1">(</span><span class="hl-2">year</span><span class="hl-1">, </span><span class="hl-2">tz</span><span class="hl-1">)</span><br/><span class="hl-1"> </span><span class="hl-8">// Good Friday (since 2000).</span><br/><span class="hl-1"> </span><span class="hl-2">holidays</span><span class="hl-1">.</span><span class="hl-6">add</span><span class="hl-1">(</span><span class="hl-6">addDays</span><span class="hl-1">(</span><span class="hl-2">easterSunday</span><span class="hl-1">, -</span><span class="hl-7">2</span><span class="hl-1">, </span><span class="hl-2">tz</span><span class="hl-1">).</span><span class="hl-6">getTime</span><span class="hl-1">())</span><br/><span class="hl-1"> </span><span class="hl-8">// Easter Monday (since 2000).</span><br/><span class="hl-1"> </span><span class="hl-2">holidays</span><span class="hl-1">.</span><span class="hl-6">add</span><span class="hl-1">(</span><span class="hl-6">addDays</span><span class="hl-1">(</span><span class="hl-2">easterSunday</span><span class="hl-1">, </span><span class="hl-7">1</span><span class="hl-1">, </span><span class="hl-2">tz</span><span class="hl-1">).</span><span class="hl-6">getTime</span><span class="hl-1">())</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">year</span><span class="hl-1"> &gt;= </span><span class="hl-7">2000</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-8">// Labour Day, May 1st (since 2000).</span><br/><span class="hl-1"> </span><span class="hl-2">holidays</span><span class="hl-1">.</span><span class="hl-6">add</span><span class="hl-1">(</span><span class="hl-2">tz</span><span class="hl-1">.</span><span class="hl-6">makeDate</span><span class="hl-1">(</span><span class="hl-2">year</span><span class="hl-1">, </span><span class="hl-7">4</span><span class="hl-1">, </span><span class="hl-7">1</span><span class="hl-1">).</span><span class="hl-6">getTime</span><span class="hl-1">())</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-8">// Christmas Day, December 25th.</span><br/><span class="hl-1"> </span><span class="hl-2">holidays</span><span class="hl-1">.</span><span class="hl-6">add</span><span class="hl-1">(</span><span class="hl-2">tz</span><span class="hl-1">.</span><span class="hl-6">makeDate</span><span class="hl-1">(</span><span class="hl-2">year</span><span class="hl-1">, </span><span class="hl-7">11</span><span class="hl-1">, </span><span class="hl-7">25</span><span class="hl-1">).</span><span class="hl-6">getTime</span><span class="hl-1">())</span><br/><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">year</span><span class="hl-1"> &gt;= </span><span class="hl-7">2000</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-8">// Day of Goodwill, December 26th (since 2000).</span><br/><span class="hl-1"> </span><span class="hl-2">holidays</span><span class="hl-1">.</span><span class="hl-6">add</span><span class="hl-1">(</span><span class="hl-2">tz</span><span class="hl-1">.</span><span class="hl-6">makeDate</span><span class="hl-1">(</span><span class="hl-2">year</span><span class="hl-1">, </span><span class="hl-7">11</span><span class="hl-1">, </span><span class="hl-7">26</span><span class="hl-1">).</span><span class="hl-6">getTime</span><span class="hl-1">())</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">year</span><span class="hl-1"> === </span><span class="hl-7">1998</span><span class="hl-1"> || </span><span class="hl-2">year</span><span class="hl-1"> === </span><span class="hl-7">1999</span><span class="hl-1"> || </span><span class="hl-2">year</span><span class="hl-1"> === </span><span class="hl-7">2001</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-8">// December 31st (1998, 1999, and 2001).</span><br/><span class="hl-1"> </span><span class="hl-2">holidays</span><span class="hl-1">.</span><span class="hl-6">add</span><span class="hl-1">(</span><span class="hl-2">tz</span><span class="hl-1">.</span><span class="hl-6">makeDate</span><span class="hl-1">(</span><span class="hl-2">year</span><span class="hl-1">, </span><span class="hl-7">11</span><span class="hl-1">, </span><span class="hl-7">31</span><span class="hl-1">).</span><span class="hl-6">getTime</span><span class="hl-1">())</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> </span><span class="hl-2">holidays</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
</code></pre>
</div></div><div class="col-4 col-menu menu-sticky-wrap menu-highlight"><nav class="tsd-navigation primary"><ul><li class=""><a href="../../modules.html">Exports</a></li><li class="current pages-entry pages-entry-menu pages-entry-depth-0"><a>Guides</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="getting-started.html">Getting <wbr/>Started</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="general-usage.html">General <wbr/>Usage</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="design-choices.html">Design <wbr/>Choices</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="calculations.html">Calculations</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="date-arithmetic.html">Date <wbr/>Arithmetic</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="timezones.html">Timezones</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="iana-timezones.html">IANA <wbr/>Timezones</a></li><li class="current pages-entry pages-entry-page pages-entry-depth-1"><a href="calendars.html">Calendars</a></li></ul></nav><nav class="tsd-navigation secondary menu-sticky"><ul></ul></nav></div></div></div><footer class="with-border-bottom"><div class="container"><h2>Legend</h2><div class="tsd-legend-group"><ul class="tsd-legend"><li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li><li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li><li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li><li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li></ul></div><h2>Settings</h2><p>Theme <select id="theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></p></div></footer><div class="container tsd-generator"><p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></div><div class="overlay"></div><script src="../../assets/main.js"></script></body></html>
</div></div><div class="col-4 col-menu menu-sticky-wrap menu-highlight"><nav class="tsd-navigation primary"><ul><li class=""><a href="../../modules.html">Exports</a></li><li class="current pages-entry pages-entry-menu pages-entry-depth-0"><a>Guides</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="getting-started.html">Getting <wbr/>Started</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="general-usage.html">General <wbr/>Usage</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="design-choices.html">Design <wbr/>Choices</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="calculations.html">Calculations</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="date-arithmetic.html">Date <wbr/>Arithmetic</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="timezones.html">Timezones</a></li><li class=" pages-entry pages-entry-page pages-entry-depth-1"><a href="iana-timezones.html">IANA <wbr/>Timezones</a></li><li class="current pages-entry pages-entry-page pages-entry-depth-1"><a href="calendars.html">Calendars</a></li></ul></nav><nav class="tsd-navigation secondary menu-sticky"><ul></ul></nav></div></div></div><footer class="with-border-bottom"><div class="container"><h2>Legend</h2><div class="tsd-legend-group"><ul class="tsd-legend"><li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li><li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li><li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li><li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li></ul></div><h2>Settings</h2><p>Theme <select id="theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></p></div></footer><div class="container tsd-generator"><p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></div><div class="overlay"></div><script src="../../assets/main.js"></script></body></html>
Loading

0 comments on commit 9a25b89

Please sign in to comment.