From 37308fe2613b840abe692036de482b1280d6b5f8 Mon Sep 17 00:00:00 2001 From: Keith Cirkel Date: Wed, 12 Jul 2023 09:33:18 +0100 Subject: [PATCH 1/4] ensure ci runs on PRs and pushes to main --- .github/workflows/test.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f5dc344..489b945 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,10 @@ name: Node CI -on: [push] +on: + push: + branches: [main] + pull_request: + branches: [main] jobs: build: From 56238aa04f4c0f9bd4abc4270ab6bb4056fc9812 Mon Sep 17 00:00:00 2001 From: Andreas Deininger Date: Sat, 15 Jul 2023 18:35:57 +0200 Subject: [PATCH 2/4] Fixing typos --- .github/workflows/test.yml | 4 ++-- README.md | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 489b945..20ee438 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,9 +10,9 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Use Node.js 18.x - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: node-version: 18.x - name: npm install, build, and test diff --git a/README.md b/README.md index bc5ca8d..34bbe20 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ So, a relative date phrase is used for up to a month and then the actual date is | Property Name | Attribute Name | Possible Values | Default Value | |:---------------|:-----------------|:--------------------------------------------------------------------------------------------|:---------------------------------| | `datetime` | `datetime` | `string` | - | -| `format` | `format` | `'datetime'\|'relative'\|'duration'` | `'auto'` | +| `format` | `format` | `'datetime'\|'relative'\|'duration'` | `'auto'` | | `date` | - | `Date \| null` | - | | `tense` | `tense` | `'auto'\|'past'\|'future'` | `'auto'` | | `precision` | `precision` | `'year'\|'month'\|'day'\|'hour'\|'minute'\|'second'` | `'second'` | @@ -83,7 +83,7 @@ So, a relative date phrase is used for up to a month and then the actual date is *: If unspecified, `formatStyle` will return `'narrow'` if `format` is `'elapsed'` or `'micro'`, `'short'` if the format is `'relative'` or `'datetime'`, otherwise it will be `'long'`. -**: If unspecified, `month` will return the same value as `formatStyle` whenever `format` is `'datetime'`, otherwise it wil be `'short'`. +**: If unspecified, `month` will return the same value as `formatStyle` whenever `format` is `'datetime'`, otherwise it will be `'short'`. ***: If unspecified, `weekday` will return the same value as `formatStyle` whenever `format` is `'datetime'`, otherwise it will be `undefined`. @@ -122,7 +122,7 @@ Unless specified, it will consider `weekday` to be `'long'`, `month` to be `'lon ###### `format=relative` -The default `relative` format will display dates relative to the current time (unless they are past the `threshold` value - see below). The values are rounded to display a single unit, for example if the time between the given `datetime` and the current wall clock time exceeds a day, then the format will _only_ ouput in days, and will not display hours, minutes or seconds. Some examples of this format with the default options and an `en` locale: +The default `relative` format will display dates relative to the current time (unless they are past the `threshold` value - see below). The values are rounded to display a single unit, for example if the time between the given `datetime` and the current wall clock time exceeds a day, then the format will _only_ output in days, and will not display hours, minutes or seconds. Some examples of this format with the default options and an `en` locale: - `in 20 days` - `20 days ago` @@ -146,7 +146,7 @@ This is similar to the `format=duration`, except the `formatStyle` defaults to ` ###### `format=auto` -This is identical to `format=relative`. Code that uses `format=auto` should migrae to `format=relative` as this will be the new default in a later version. +This is identical to `format=relative`. Code that uses `format=auto` should migrate to `format=relative` as this will be the new default in a later version. ###### `format=micro` From 6e02a15018c01f6979033d85d7bbd4d5f15c99f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 02:25:10 +0000 Subject: [PATCH 3/4] Bump word-wrap from 1.2.3 to 1.2.4 Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4. - [Release notes](https://github.com/jonschlinkert/word-wrap/releases) - [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4) --- updated-dependencies: - dependency-name: word-wrap dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1f1b311..7c40a12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6753,9 +6753,9 @@ } }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -11874,9 +11874,9 @@ } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", "dev": true }, "wordwrapjs": { From afdd4ea1e56512ca87c74e5f83e0c4460f8bf678 Mon Sep 17 00:00:00 2001 From: Keith Cirkel Date: Fri, 12 Jan 2024 13:43:59 +0000 Subject: [PATCH 4/4] round years using calendar years only Fixes #270 --- src/duration.ts | 46 +++++++++++++++++++++++++++---------------- test/duration.ts | 8 +++++++- test/relative-time.js | 13 +++++++++--- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/src/duration.ts b/src/duration.ts index 5dc7a3c..a0529e3 100644 --- a/src/duration.ts +++ b/src/duration.ts @@ -151,33 +151,45 @@ export function roundToSingleUnit(duration: Duration, {relativeTo = Date.now()}: if (!days && hours >= 21) days += Math.round(hours / 24) if (days || weeks || months || years) hours = 0 + // Resolve calendar dates const currentYear = relativeTo.getFullYear() let currentMonth = relativeTo.getMonth() const currentDate = relativeTo.getDate() - if (days >= 27 || (years + months && days)) { - relativeTo.setDate(currentDate + days * sign) - months += Math.abs( - relativeTo.getFullYear() >= currentYear - ? relativeTo.getMonth() - currentMonth - : relativeTo.getMonth() - currentMonth - 12, - ) - if (months) { - days = 0 + if (days >= 27 || years + months + days) { + const newDate = new Date(relativeTo) + newDate.setFullYear(currentYear + years * sign) + newDate.setMonth(currentMonth + months * sign) + newDate.setDate(currentDate + days * sign) + const yearDiff = newDate.getFullYear() - relativeTo.getFullYear() + const monthDiff = newDate.getMonth() - relativeTo.getMonth() + const daysDiff = Math.abs(Math.round((Number(newDate) - Number(relativeTo)) / 86400000)) + const monthsDiff = Math.abs(yearDiff * 12 + monthDiff) + if (daysDiff < 27) { + if (days >= 6) { + weeks += Math.round(days / 7) + days = 0 + } else { + days = daysDiff + } + months = years = 0 + } else if (monthsDiff < 11) { + months = monthsDiff + years = 0 + } else { + months = 0 + years = yearDiff * sign } + if (months || years) days = 0 currentMonth = relativeTo.getMonth() } - - if (days >= 6) weeks += Math.round(days / 7) - if (weeks || months || years) days = 0 + if (years) months = 0 if (weeks >= 4) months += Math.round(weeks / 4) if (months || years) weeks = 0 - - if (months >= 11 || (years && months)) { - relativeTo.setMonth(relativeTo.getMonth() + months * sign) - years += Math.abs(currentYear - relativeTo.getFullYear()) + if (days && weeks && !months && !years) { + weeks += Math.round(days / 7) + days = 0 } - if (years) months = 0 return new Duration( years * sign, diff --git a/test/duration.ts b/test/duration.ts index ef96d97..d90c490 100644 --- a/test/duration.ts +++ b/test/duration.ts @@ -293,6 +293,7 @@ suite('duration', function () { ['P9M20DT25H', 'P10M', {relativeTo: new Date('2023-01-12T00:00:00Z')}], ['P11M', 'P1Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}], ['-P11M', '-P1Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}], + ['-P11M15D', '-P1Y', {relativeTo: new Date('2024-01-06T00:00:00')}], ['P1Y4D', 'P1Y', {relativeTo: new Date('2022-11-01T00:00:00Z')}], ['P1Y5M13D', 'P1Y', {relativeTo: new Date('2023-01-01T00:00:00Z')}], ['P1Y5M15D', 'P1Y', {relativeTo: new Date('2023-01-01T00:00:00Z')}], @@ -308,7 +309,12 @@ suite('duration', function () { relativeTo: new Date('2022-01-01T00:00:00Z'), }, ], - ['-P27D', '-P1M', {relativeTo: new Date('2023-02-28T00:00:00Z')}], + ['-P27D', '-P27D', {relativeTo: new Date('2023-02-28T00:00:00Z')}], + ['-P27D', '-P1M', {relativeTo: new Date('2023-02-27T00:00:00Z')}], + ['P1Y2M1D', 'P2Y', {relativeTo: new Date('2022-12-31T12:00:00.000Z')}], + ['-P1Y8D', '-P1Y', {relativeTo: new Date('2024-01-11T12:00:00.000Z')}], + ['-P1Y7DT19H43M19S', '-P1Y', {relativeTo: new Date('2024-01-11T12:00:00.000Z')}], + ['-P1Y11D', '-P2Y', {relativeTo: new Date('2024-01-11T12:00:00.000Z')}], ]) for (const [input, expected, opts] of roundTests) { test(`roundToSingleUnit(${input}) === ${expected}`, () => { diff --git a/test/relative-time.js b/test/relative-time.js index 1f20571..c49d731 100644 --- a/test/relative-time.js +++ b/test/relative-time.js @@ -482,7 +482,7 @@ suite('relative-time', function () { time.setAttribute('datetime', datetime) time.setAttribute('format', 'micro') await Promise.resolve() - assert.equal(time.shadowRoot.textContent, '10y') + assert.equal(time.shadowRoot.textContent, '11y') }) test('micro formats future times', async () => { @@ -2416,14 +2416,14 @@ suite('relative-time', function () { datetime: '2024-03-01T12:00:00.000Z', tense: 'future', format: 'auto', - expected: 'in 3 years', + expected: 'in 2 years', }, { reference: '2022-12-31T12:00:00.000Z', datetime: '2024-03-01T12:00:00.000Z', tense: 'future', format: 'micro', - expected: '3y', + expected: '2y', }, { reference: '2021-04-24T12:00:00.000Z', @@ -2432,6 +2432,13 @@ suite('relative-time', function () { format: 'micro', expected: '2y', }, + { + reference: '2024-01-04T12:00:00.000Z', + datetime: '2020-02-16T16:16:41.000Z', + tense: 'past', + format: 'auto', + expected: '4 years ago', + }, ]) for (const {