From 41247953a21c7eef1edd73699cf6432cbab95f5c Mon Sep 17 00:00:00 2001 From: aki Date: Sun, 24 Jul 2022 20:49:39 +0900 Subject: [PATCH] feat(useDateFormat): add format --- packages/shared/useDateFormat/index.md | 3 ++ packages/shared/useDateFormat/index.test.ts | 9 ++++ packages/shared/useDateFormat/index.ts | 53 +++++++++++++-------- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/packages/shared/useDateFormat/index.md b/packages/shared/useDateFormat/index.md index 65c2a86dfc5..6f84cd664e4 100644 --- a/packages/shared/useDateFormat/index.md +++ b/packages/shared/useDateFormat/index.md @@ -26,6 +26,9 @@ Get the formatted date according to the string of tokens passed in, inspired by | `ss` | 00-59 | The second, 2-digits | | `SSS` | 000-999 | The millisecond, 3-digits | | `d` | 0-6 | The day of the week, with Sunday as 0 | +| `dd` | S-S | The min name of the day of the week | +| `ddd` | Sun-Sat | The short name of the day of the week | +| `dddd` | Sunday-Saturday | The name of the day of the week | ## Usage diff --git a/packages/shared/useDateFormat/index.test.ts b/packages/shared/useDateFormat/index.test.ts index fb674497165..f63a787a04e 100644 --- a/packages/shared/useDateFormat/index.test.ts +++ b/packages/shared/useDateFormat/index.test.ts @@ -28,4 +28,13 @@ describe('useDateFormat', () => { it('should work with HH:mm:ss d', () => { expect(useDateFormat(new Date('2022-01-01 15:05:05'), 'HH:mm:ss d').value).toBe('15:05:05 6') }) + it('should work with YYYY/MM/DD dd', () => { + expect(useDateFormat(new Date('2022-01-01 15:05:05'), 'YYYY/MM/DD dd', { locales: 'en-US' }).value).toBe('2022/01/01 S') + }) + it('should work with YYYY/MM/DD ddd', () => { + expect(useDateFormat(new Date('2022-01-01 15:05:05'), 'YYYY/MM/DD ddd', { locales: 'en-US' }).value).toBe('2022/01/01 Sat') + }) + it('should work with YYYY/MM/DD dddd', () => { + expect(useDateFormat(new Date('2022-01-01 15:05:05'), 'YYYY/MM/DD dddd', { locales: 'en-US' }).value).toBe('2022/01/01 Saturday') + }) }) diff --git a/packages/shared/useDateFormat/index.ts b/packages/shared/useDateFormat/index.ts index 0c837e7c448..2cdf8bd9b8d 100644 --- a/packages/shared/useDateFormat/index.ts +++ b/packages/shared/useDateFormat/index.ts @@ -4,10 +4,17 @@ import { computed } from 'vue-demi' export type DateLike = Date | number | string | undefined +export interface UseDateFormatOptions { + /** + * A locale string + */ + locales?: Intl.LocalesArgument +} + const REGEX_PARSE = /* #__PURE__ */ /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/ const REGEX_FORMAT = /* #__PURE__ */ /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g -export const formatDate = (date: Date, formatStr: string) => { +export const formatDate = (date: Date, formatStr: string, locales?: Intl.LocalesArgument) => { const years = date.getFullYear() const month = date.getMonth() const days = date.getDate() @@ -16,25 +23,28 @@ export const formatDate = (date: Date, formatStr: string) => { const seconds = date.getSeconds() const milliseconds = date.getMilliseconds() const day = date.getDay() - const matches: Record = { - YY: String(years).slice(-2), - YYYY: years, - M: month + 1, - MM: `${month + 1}`.padStart(2, '0'), - D: String(days), - DD: `${days}`.padStart(2, '0'), - H: String(hours), - HH: `${hours}`.padStart(2, '0'), - h: `${hours % 12 || 12}`.padStart(1, '0'), - hh: `${hours % 12 || 12}`.padStart(2, '0'), - m: String(minutes), - mm: `${minutes}`.padStart(2, '0'), - s: String(seconds), - ss: `${seconds}`.padStart(2, '0'), - SSS: `${milliseconds}`.padStart(3, '0'), - d: day, + const matches: Record string | number> = { + YY: () => String(years).slice(-2), + YYYY: () => years, + M: () => month + 1, + MM: () => `${month + 1}`.padStart(2, '0'), + D: () => String(days), + DD: () => `${days}`.padStart(2, '0'), + H: () => String(hours), + HH: () => `${hours}`.padStart(2, '0'), + h: () => `${hours % 12 || 12}`.padStart(1, '0'), + hh: () => `${hours % 12 || 12}`.padStart(2, '0'), + m: () => String(minutes), + mm: () => `${minutes}`.padStart(2, '0'), + s: () => String(seconds), + ss: () => `${seconds}`.padStart(2, '0'), + SSS: () => `${milliseconds}`.padStart(3, '0'), + d: () => day, + dd: () => date.toLocaleDateString(locales, { weekday: 'narrow' }), + ddd: () => date.toLocaleDateString(locales, { weekday: 'short' }), + dddd: () => date.toLocaleDateString(locales, { weekday: 'long' }), } - return formatStr.replace(REGEX_FORMAT, (match, $1) => $1 || matches[match]) + return formatStr.replace(REGEX_FORMAT, (match, $1) => $1 || matches[match]()) } export const normalizeDate = (date: DateLike) => { @@ -63,10 +73,11 @@ export const normalizeDate = (date: DateLike) => { * @see https://vueuse.org/useDateFormat * @param date * @param formatStr + * @param options */ -export function useDateFormat(date: MaybeComputedRef, formatStr: MaybeComputedRef = 'HH:mm:ss') { - return computed(() => formatDate(normalizeDate(resolveUnref(date)), resolveUnref(formatStr))) +export function useDateFormat(date: MaybeComputedRef, formatStr: MaybeComputedRef = 'HH:mm:ss', options: UseDateFormatOptions = {}) { + return computed(() => formatDate(normalizeDate(resolveUnref(date)), resolveUnref(formatStr), options?.locales)) } export type UseDateFormatReturn = ReturnType