8000 feat(useDateFormat): add date ordinal formatting (#3474) · vueuse/vueuse@61ceb19 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit 61ceb19

Browse files
lanxizhuantfu
andauthored
feat(useDateFormat): add date ordinal formatting (#3474)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
1 parent 771e7ff commit 61ceb19

File tree

3 files changed

+54
-28
lines changed

3 files changed

+54
-28
lines changed

packages/shared/useDateFormat/index.md

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
88

99
**List of all available formats (HH:mm:ss by default):**
1010

11-
| Format | Output | Description |
12-
|--------| ---------------- |---------------------------------------|
13-
| `YY` | 18 | Two-digit year |
14-
| `YYYY` | 2018 | Four-digit year |
15-
| `M` | 1-12 | The month, beginning at 1 |
16-
| `MM` | 01-12 | The month, 2-digits |
17-
| `MMM` | Jan-Dec | The abbreviated month name |
18-
| `MMMM` | January-December | The full month name |
19-
| `D` | 1-31 | The day of the month |
20-
| `DD` | 01-31 | The day of the month, 2-digits |
21-
| `H` | 0-23 | The hour |
22-
| `HH` | 00-23 | The hour, 2-digits |
23-
| `h` | 1-12 | The hour, 12-hour clock |
24-
| `hh` | 01-12 | The hour, 12-hour clock, 2-digits |
25-
| `m` | 0-59 | The minute |
26-
| `mm` | 00-59 | The minute, 2-digits |
27-
| `s` | 0-59 | The second |
28-
| `ss` | 00-59 | The second, 2-digits |
29-
| `SSS` | 000-999 | The millisecond, 3-digits |
30-
| `A` | AM PM | The meridiem |
31-
| `AA` | A.M. P.M. | The meridiem, periods |
32-
| `a` | am pm | The meridiem, lowercase |
33-
| `aa` | a.m. p.m. | The meridiem, lowercase and periods |
34-
| `d` | 0-6 | The day of the week, with Sunday as 0 |
35-
| `dd` | S-S | The min name of the day of the week |
36-
| `ddd` | Sun-Sat | The short name of the day of the week |
37-
| `dddd` | Sunday-Saturday | The name of the day of the week |
11+
| Format | Output | Description |
12+
|--------| ------------------------ |-----------------------------------------|
13+
| `Yo` | 2018th | Ordinal formatted year |
14+
| `YY` | 18 | Two-digit year |
15+
| `YYYY` | 2018 | Four-digit year |
16+
| `M` | 1-12 | The month, beginning at 1 |
17+
| `Mo` | 1st, 2nd, ..., 12th | The month, ordinal formatted |
18+
| `MM` | 01-12 | The month, 2-digits |
19+
| `MMM` | Jan-Dec | The abbreviated month name |
20+
| `MMMM` | January-December 8000 | The full month name |
21+
| `D` | 1-31 | The day of the month |
22+
| `Do` | 1st, 2nd, ..., 31st | The day of the month, ordinal formatted |
23+
| `DD` | 01-31 | The day of the month, 2-digits |
24+
| `H` | 0-23 | The hour |
25+
| `Ho` | 0th, 1st, 2nd, ..., 23rd | The hour, ordinal formatted |
26+
| `HH` | 00-23 | The hour, 2-digits |
27+
| `h` | 1-12 | The hour, 12-hour clock |
28+
| `ho` | 1st, 2nd, ..., 12th | The hour, 12-hour clock, sorted |
29+
| `hh` | 01-12 | The hour, 12-hour clock, 2-digits |
30+
| `m` | 0-59 | The minute |
31+
| `mo` | 0th, 1st, ..., 59th | The minute, ordinal formatted |
32+
| `mm` | 00-59 | The minute, 2-digits |
33+
| `s` | 0-59 | The second |
34+
| `so` | 0th, 1st, ..., 59th | The second, ordinal formatted |
35+
| `ss` | 00-59 | The second, 2-digits |
36+
| `SSS` | 000-999 | The millisecond, 3-digits |
37+
| `A` | AM PM | The meridiem |
38+
| `AA` | A.M. P.M. | The meridiem, periods |
39+
| `a` | am pm | The meridiem, lowercase |
40+
| `aa` | a.m. p.m. | The meridiem, lowercase and periods |
41+
| `d` | 0-6 | The day of the week, with Sunday as 0 |
42+
| `dd` | S-S | The min name of the day of the week |
43+
| `ddd` | Sun-Sat | The short name of the day of the week |
44+
| `dddd` | Sunday-Saturday | The name of the day of the week |
3845

3946
- Meridiem is customizable by defining `customMeridiem` in `options`.
4047

packages/shared/useDateFormat/index.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ describe('useDateFormat', () => {
6767
it('should work with MMMM DD YYYY', () => {
6868
expect(useDateFormat(new Date('2022-01-01 15:05:05'), 'MMMM DD YYYY', { locales: 'en-US' }).value).toBe('January 01 2022')
6969
})
70+
it('should work with Mo Do Yo', () => {
71+
expect(useDateFormat(new Date('2022-01-01 15:05:05'), 'MMMM Do Yo', { locales: 'en-US' }).value).toBe('January 1st 2022nd')
72+
expect(useDateFormat(new Date('2022-12-11 15:05:05'), 'MMMM Do Yo', { locales: 'en-US' }).value).toBe('December 11th 2022nd')
73+
expect(useDateFormat(new Date('2023-12-12 15:05:05'), 'MMMM Do Yo', { locales: 'en-US' }).value).toBe('December 12th 2023rd')
74+
expect(useDateFormat(new Date('2024-12-23 15:05:05'), 'MMMM Do Yo', { locales: 'en-US' }).value).toBe('December 23rd 2024th')
75+
})
7076

7177
describe('meridiem', () => {
7278
it.each([

packages/shared/useDateFormat/index.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export interface UseDateFormatOptions {
2020
}
2121

2222
const REGEX_PARSE = /* #__PURE__ */ /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/
23-
const REGEX_FORMAT = /* #__PURE__ */ /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a{1,2}|A{1,2}|m{1,2}|s{1,2}|Z{1,2}|SSS/g
23+
const REGEX_FORMAT = /* #__PURE__ */ /[YMDHhms]o|\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a{1,2}|A{1,2}|m{1,2}|s{1,2}|Z{1,2}|SSS/g
2424

2525
function defaultMeridiem(hours: number, minutes: number, isLowercase?: boolean, hasPeriod?: boolean) {
2626
let m = (hours F438 < 12 ? 'AM' : 'PM')
@@ -29,6 +29,12 @@ function defaultMeridiem(hours: number, minutes: number, isLowercase?: boolean,
2929
return isLowercase ? m.toLowerCase() : m
3030
}
3131

32+
function formatOrdinal(num: number) {
33+
const suffixes = ['th', 'st', 'nd', 'rd']
34+
const v = num % 100
35+
return num + (suffixes[(v - 20) % 10] || suffixes[v] || suffixes[0])
36+
}
37+
3238
export function formatDate(date: Date, formatStr: string, options: UseDateFormatOptions = {}) {
3339
const years = date.getFullYear()
3440
const month = date.getMonth()
@@ -40,21 +46,28 @@ export function formatDate(date: Date, formatStr: string, options: UseDateFormat
4046
const day = date.getDay()
4147
const meridiem = options.customMeridiem ?? defaultMeridiem
4248
const matches: Record<string, () => string | number> = {
49+
Yo: () => formatOrdinal(years),
4350
YY: () => String(years).slice(-2),
4451
YYYY: () => years,
4552
M: () => month + 1,
53+
Mo: () => formatOrdinal(month + 1),
4654
MM: () => `${month + 1}`.padStart(2, '0'),
4755
MMM: () => date.toLocaleDateString(options.locales, { month: 'short' }),
4856
MMMM: () => date.toLocaleDateString(options.locales, { month: 'long' }),
4957
D: () => String(days),
58+
Do: () => formatOrdinal(days),
5059
DD: () => `${days}`.padStart(2, '0'),
5160
H: () => String(hours),
61+
Ho: () => formatOrdinal(hours),
5262
HH: () => `${hours}`.padStart(2, '0'),
5363
h: () => `${hours % 12 || 12}`.padStart(1, '0'),
64+
ho: () => formatOrdinal(hours % 12 || 12),
5465
hh: () => `${hours % 12 || 12}`.padStart(2, '0'),
5566
m: () => String(minutes),
67+
mo: () => formatOrdinal(minutes),
5668
mm: () => `${minutes}`.padStart(2, '0'),
5769
s: () => String(seconds),
70+
so: () => formatOrdinal(seconds),
5871
ss: () => `${seconds}`.padStart(2, '0'),
5972
SSS: () => `${milliseconds}`.padStart(3, '0'),
6073
d: () => day,

0 commit comments

Comments
 (0)
0