Skip to content

Commit

Permalink
Implement localized week information (#1454)
Browse files Browse the repository at this point in the history
* begin adding support for locale-dependent start of week

* Use an options parameter for locale week startOf

* Add tests for locale week start and end

* Add useLocaleWeeks option to DateTime.hasSame and add tests

* Add useLocaleWeeks option to Interval.count

* Add Intl.Locale.weekInfo as a reported optional feature and test for it

* Add Info.getStartOfWeek method

* Add DateTime.isWeekend and DateTime.localDayOfWeek getters

* Improve localized week code in DateTime#startOf

* Implement DateTime#localWeekYear and DateTime#localWeekNumber
Adjust localWeekDay to be in line with weekday

* Add documentatino for DateTime#localWeekNumber and DateTime#localWeekYear

* Add Info.getMinimumDaysInFirstWeek and Info.getWeekendWeekdays and tests

* Add DateTime#isWeekend test

* Add tests for DateTime#localWeekNumber and localWeekYear

* Add tests for localWeekday

* Add formatting tokens for localWeekYear and localWeekNumber

* Add tests for formatting tokens n, nn, ii, iiii

* Implement DateTime#weeksInLocalWeekYear and proper week year length calculations based on locale week settings

* Support setting locale based week units with `DateTime#set`

* Fix Typo

* Add tests for DateTime#set with locale based week units and DateTime#weeksInLocalWeekYear

* Accept locale-based week units in DateTime#fromObject

* Add Settings.defaultWeekSettings

* Add documentation for locale-based weeks

* Remove unused value from usesLocalWeekValues

* Remove incorrect claim in documentation

* Remove dumb import
  • Loading branch information
diesieben07 authored Oct 12, 2023
1 parent 5ea19fb commit 1b8679e
Show file tree
Hide file tree
Showing 18 changed files with 1,031 additions and 53 deletions.
6 changes: 5 additions & 1 deletion docs/formatting.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ The macro options available correspond one-to-one with the preset formats define
(Examples below given for `2014-08-06T13:07:04.054` considered as a local time in America/New_York).

| Standalone token | Format token | Description | Example |
| ---------------- | ------------ | -------------------------------------------------------------- | ------------------------------------------------------------- |
|------------------| ------------ |----------------------------------------------------------------| ------------------------------------------------------------- |
| S | | millisecond, no padding | `54` |
| SSS | | millisecond, padded to 3 | `054` |
| u | | fractional seconds, functionally identical to SSS | `054` |
Expand Down Expand Up @@ -219,6 +219,10 @@ The macro options available correspond one-to-one with the preset formats define
| kkkk | | ISO week year, padded to 4 | `2014` |
| W | | ISO week number, unpadded | `32` |
| WW | | ISO week number, padded to 2 | `32` |
| ii | | Local week year, unpadded | `14` |
| iiii | | Local week year, padded to 4 | `2014` |
| n | | Local week number, unpadded | `32` |
| nn | | Local week number, padded to 2 | `32` |
| o | | ordinal (day of year), unpadded | `218` |
| ooo | | ordinal (day of year), padded to 3 | `218` |
| q | | quarter, no padding | `3` |
Expand Down
68 changes: 68 additions & 0 deletions docs/intl.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,71 @@ Similar to `locale`, you can set the default numbering system for new instances:
```js
Settings.defaultNumberingSystem = "beng";
```

## Locale-based weeks

Most of Luxon uses the [ISO week date](https://en.wikipedia.org/wiki/ISO_week_date) system when working with week-related data.
This means that the week starts on Monday and the first week of the year is that week, which has 4 or more of its days in January.

This definition works for most use-cases, however locales can define different rules. For example, in many English-speaking countries
the week is said to start on Sunday and the 1 January always defines the first week of the year. This information is
available through the Luxon as well.

Note that your runtime needs to support [`Intl.Locale#getWeekInfo`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/getWeekInfo) for this to have an effect. If unsupported, Luxon will fall back
to using the ISO week dates.

### Accessing locale-based week info

The `Info` class exposes methods `getStartOfWeek`, `getMinimumDaysInFirstWeek` and `getWeekendWeekdays` for informational
purposes.

### Accessing locale-based week data

```js
const dt = DateTime.local(2022, 1, 1, { locale: "en-US" });
dt.localWeekday // 7, because Saturday is the 7th day of the week in en-US
dt.localWeekNumber // 1, because 1 January is always in the first week in en-US
dt.localWeekYear // 2022, because 1 January is always in the first week in en-US
dt.weeksInLocalWeekYear // 53, because 2022 has 53 weeks in en-US
```

### Using locale-based week data when creating DateTimes

When creating a DateTime instance using `fromObject`, you can use the `localWeekday`, `localWeekNumber` and `localWeekYear`
properties. They will use the same locale that the newly created DateTime will use, either explicitly provided or falling back
to the system default.

```js
const dt = DateTime.fromObject({localWeekYear: 2022, localWeekNumber: 53, localWeekday: 7});
dt.toISODate(); // 2022-12-31
```

### Setting locale-based week data

When modifying an existing DateTime instance using `set`, you can use the `localWeekday`, `localWeekNumber` and `localWeekYear`
properties. They will use the locale of the existing DateTime as reference.

```js
const dt = DateTime.local(2022, 1, 2, { locale: "en-US" });
const modified = dt.set({localWeekNumber: 2});
modified.toISODate(); // 2022-01-08
```

### Locale-based weeks with math

The methods `startOf`, `endOf`, `hasSame` of `DateTime` as well as `count` of `Interval` accept an option `useLocaleWeeks`.
If enabled, the methods will treat the `week` unit according to the locale, respecting the correct start of the week.

```js
const dt = DateTime.local(2022, 1, 6, { locale: "en-US" });
const startOfWeek = dt.startOf('week', {useLocaleWeeks: true});
startOfWeek.toISODate(); // 2022-01-02, a Sunday
```

### Overriding defaults

You can override the runtime-provided defaults for the week settings using `Settings.defaultWeekSettings`:

```js
Settings.defaultWeekSettings = { firstDay: 7, minimalDays: 1, weekend: [6, 7] }
```
Loading

0 comments on commit 1b8679e

Please sign in to comment.