Skip to content

Commit

Permalink
feat: relative time formatter (#36)
Browse files Browse the repository at this point in the history
* feat: relative time formatter

* chore: rename `relative()` to `relativeTime()`
  • Loading branch information
euaaaio authored Oct 4, 2023
1 parent 9ef824b commit 59d22c1
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 14 deletions.
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ locale.set('fr')
[Intl locale format]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locale_identification_and_negotiation


### Date & Number Format
### Date, Number & Relative Time Format

`formatter()` creates a store with a functions to format number and time.

Expand All @@ -204,7 +204,7 @@ import { formatter } from '@nanostores/i18n'
export const format = formatter(locale)
```

This store will have `time()` and `number()` functions.
This store will have `time()`, `number()` and `relativeTime()` functions.

```js
import { useStore } from '@nanostores/react'
Expand All @@ -217,7 +217,8 @@ export const Date = (date) => {
```

These functions accepts options
of [`Intl.DateTimeFormat`] and [`Intl.NumberFormat`].
of [`Intl.DateTimeFormat`], [`Intl.NumberFormat`]
and [`Intl.RelativeTimeFormat`].

```ts
time(date, {
Expand All @@ -227,10 +228,13 @@ time(date, {
hour: 'numeric',
minute: 'numeric'
}) //=> "November 1, 01:56:33"

relativeTime(-1, 'day', { numeric: 'auto' }) //=> "yesterday"
```

[`Intl.DateTimeFormat`]: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat
[`Intl.DateTimeFormat`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat
[`Intl.NumberFormat`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat
[`Intl.RelativeTimeFormat`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat


### I18n Object
Expand Down Expand Up @@ -311,7 +315,7 @@ export const Robots = ({ name }) => {
}
```

You can use `time()` and `number()` [formatting functions].
You can use `time()`, `number()` and `relativeTime()` [formatting functions].

[formatting functions]: https://github.com/nanostores/i18n/#date--number-format

Expand Down
2 changes: 1 addition & 1 deletion demo/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export let i18n = createI18n(locale, {
setTimeout(() => {
resolve({
page: {
desc: 'Сегодня {date}',
desc: 'Сегодня {date}, a {relativeDate} станет лучше',
title: 'Демо интернационализации'
}
})
Expand Down
7 changes: 4 additions & 3 deletions demo/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@ import { params } from '../index.js'
import { format, i18n } from './i18n.js'

let messages = i18n('page', {
desc: params('Today is {date}'),
desc: params('Today is {date} and {relativeDate} will be better'),
title: 'I18n demo'
})

let title = document.querySelector('h1')
let desc = document.querySelector('span')

messages.subscribe(t => {
let { time } = format.get()
let { relativeTime, time } = format.get()
title.innerText = t.title
desc.innerText = t.desc({
date: time(new Date(), {
day: 'numeric',
month: 'long',
year: 'numeric'
})
}),
relativeDate: relativeTime(1, 'day', { numeric: 'auto' })
})
})
10 changes: 8 additions & 2 deletions formatter/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@ import type { LocaleStore } from '../locale-from/index.js'

export interface Formatter {
number(num: number, opts?: Intl.NumberFormatOptions): string
relativeTime(
num: number,
unit: Intl.RelativeTimeFormatUnit,
opts?: Intl.RelativeTimeFormatOptions
): string
time(date?: Date | number, opts?: Intl.DateTimeFormatOptions): string
}

/**
* Create time/number formatter connected to current locale.
*
* See `Intl.DateTimeFormat` and `Intl.NumberFormat` for options.
* See `Intl.DateTimeFormat`, `Intl.NumberFormat`
* and `Intl.RelativeTimeFormat` for options.
*
* ```js
* import { formatter, localeFrom } from '@nanostores/i18n'
Expand All @@ -24,7 +30,7 @@ export interface Formatter {
* import { useStore } from 'nanostores'
* import { format } from '../stores/i18n.js'
*
* export Date = (date) => {
* export let Date = (date) => {
* let { time } = useStore(format)
* return time(date)
* }
Expand Down
3 changes: 3 additions & 0 deletions formatter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export function formatter(locale) {
number(num, opts) {
return new Intl.NumberFormat(code, opts).format(num)
},
relativeTime(num, unit, opts) {
return new Intl.RelativeTimeFormat(code, opts).format(num, unit)
},
time(date, opts) {
return new Intl.DateTimeFormat(code, opts).format(date)
}
Expand Down
6 changes: 5 additions & 1 deletion formatter/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { equal } from 'uvu/assert'

import { formatter } from '../index.js'

test('has number and date formatter', () => {
test('has number, date and relative time formatters', () => {
let locale = atom('en')
let format = formatter(locale)

Expand All @@ -19,11 +19,15 @@ test('has number and date formatter', () => {
equal(f.number(10000, { useGrouping: false }), '10000')
equal(f.time(new Date(86400000)), '1/2/1970')
equal(f.time(new Date(86400000), { month: '2-digit' }), '01')
equal(f.relativeTime(-1, 'day'), '1 day ago')
equal(f.relativeTime(-1, 'day', { numeric: 'auto' }), 'yesterday')

if (!process.version.startsWith('v12.')) {
locale.set('ru')
equal(f.number(10000), '10 000')
equal(f.time(new Date(86400000)), '02.01.1970')
equal(f.relativeTime(-1, 'day'), '1 день назад')
equal(f.relativeTime(-1, 'day', { numeric: 'auto' }), 'вчера')
}
})

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,12 @@
{
"name": "Minimum",
"import": "{ localeFrom, createI18n }",
"limit": "733 B"
"limit": "731 B"
},
{
"name": "Maximum",
"import": "{ localeFrom, browser, createI18n, params, count, formatter, createProcessor }",
"limit": "1166 B"
"limit": "1179 B"
}
],
"clean-publish": {
Expand Down

0 comments on commit 59d22c1

Please sign in to comment.