diff --git a/packages/core/i18n/README.md b/packages/core/i18n/README.md index 61745a7c6f..20e218a50d 100644 --- a/packages/core/i18n/README.md +++ b/packages/core/i18n/README.md @@ -12,6 +12,8 @@ - [HTML safe formatting with ``](#html-safe-formatting-with-i18n-t) - [Formatting numbers, dates and times](#formatting-numbers-dates-and-times) - [Additional service functions.](#additional-service-functions) + - [formatUnixTimeStamp](#formatunixtimestamp) + - [formatIsoDate](#formatisodate) - [te](#te) - [tm](#tm) @@ -395,6 +397,40 @@ Every single method listed in [FormatJS](https://formatjs.io/docs/intl) is expos (as previously exposed by vue18n-n) +### formatUnixTimeStamp + +Formats a unix timestamp into a formatted date string + +`code:` + +```ts +const { formatUnixTimeStamp } = useI18n() +console.log(formatUnixTimeStamp('1558006979')) +``` + +`result:` + +```json +May 16, 2019, 11:42 AM +``` + +### formatIsoDate + +Format an ISO formatted date + +`code:` + +```ts +const { formatIsoDate } = useI18n() +console.log(formatIsoDate('2019-05-16T11:42:59.000Z')) +``` + +`result:` + +```json +May 16, 2019, 11:42 AM +``` + ### te check if translation message exists @@ -412,7 +448,6 @@ check if translation message exists ```ts const { te } = useI18n() console.log({p: te('global.ok'), n: te('global.not.ok')}) -console.log() ``` `result:` diff --git a/packages/core/i18n/src/i18n.spec.ts b/packages/core/i18n/src/i18n.spec.ts index 4a2f55f6bf..19c713dd54 100644 --- a/packages/core/i18n/src/i18n.spec.ts +++ b/packages/core/i18n/src/i18n.spec.ts @@ -107,6 +107,54 @@ describe('i18n', () => { }) }) + describe('formatUnixTimeStamp()', () => { + beforeAll(() => { + createI18n('en-us', english, true) + }) + + it('should return a properly formatted date', () => { + const { formatUnixTimeStamp } = useI18n() + const formattedDateAM = formatUnixTimeStamp(1558006979) + const formattedDatePM = formatUnixTimeStamp(1558057179) + const january = formatUnixTimeStamp(1547506800) + const october = formatUnixTimeStamp(1570111995) + const november = formatUnixTimeStamp(1573772400) + const decimalTimestamp = formatUnixTimeStamp(1570111995.652561) + const integerTimestamp = formatUnixTimeStamp(1570111995) + + expect(formattedDateAM).toBe('May 16, 2019, 11:42 AM') + expect(formattedDatePM).toBe('May 17, 2019, 1:39 AM') + expect(january.substring(0, 7)).toBe('Jan 14,') + expect(october.substring(0, 7)).toBe('Oct 3, ') + expect(november.substring(0, 7)).toBe('Nov 14,') + expect(decimalTimestamp).toEqual(integerTimestamp) + }) + }) + + describe('formatIsoDate()', () => { + beforeAll(() => { + createI18n('en-us', english, true) + }) + + it('should return a properly formatted date', () => { + const { formatIsoDate } = useI18n() + const formattedDateAM = formatIsoDate('2019-05-16T11:42:59.000Z') + const formattedDatePM = formatIsoDate('2019-05-17T01:39:39.000Z') + const january = formatIsoDate('2019-01-14T23:00:00.000Z') + const october = formatIsoDate('2019-10-03T14:13:15.000Z') + const november = formatIsoDate('2019-11-14T23:00:00.000Z') + const decimalTimestamp = formatIsoDate('2019-10-03T14:13:15.000Z') + const integerTimestamp = formatIsoDate('2019-10-03T14:13:15.000Z') + + expect(formattedDateAM).toBe('May 16, 2019, 11:42 AM') + expect(formattedDatePM).toBe('May 17, 2019, 1:39 AM') + expect(january.substring(0, 7)).toBe('Jan 14,') + expect(october.substring(0, 7)).toBe('Oct 3, ') + expect(november.substring(0, 7)).toBe('Nov 14,') + expect(decimalTimestamp).toEqual(integerTimestamp) + }) + }) + // the cases bellow are for reference only. See https://formatjs.io/docs/intl/ for more details and usage describe('formatNumber', () => { diff --git a/packages/core/i18n/src/i18n.ts b/packages/core/i18n/src/i18n.ts index 4e77eb946f..cbf231580d 100644 --- a/packages/core/i18n/src/i18n.ts +++ b/packages/core/i18n/src/i18n.ts @@ -37,6 +37,43 @@ export const createI18n = > const { $t, ...otherProps } = intlOriginal const intl = otherProps + /** + * Formats a unix timestamp into a formatted date string + * @param {Number} timestamp a unix timestamp in seconds + * @returns a date string formatted like 'Apr 6, 2022 10:50' + */ + const formatUnixTimeStamp = (timestamp: number): string => { + const invalidDate = 'Invalid Date' + if (!timestamp) { + return invalidDate + } + + try { + const date = new Date(timestamp * 1000) + + return intl.formatDate(date, { + year: 'numeric', + month: 'short', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + }) + } catch (err) { + return invalidDate + } + } + + /** + * Format an ISO formatted date + * @param {String} isoDate ISO formatted date string + * @returns {String} date formatted like 'Apr 6, 2022 10:50' + */ + const formatIsoDate = (isoDate: string): string => { + const date = Date.parse(isoDate) / 1000 + + return formatUnixTimeStamp(date) + } + const t = (translationKey: PathToDotNotation, values?: Record | undefined, opts?: IntlMessageFormatOptions): string => { return intl.formatMessage({ id: translationKey }, values, opts) } @@ -51,6 +88,8 @@ export const createI18n = > } const localIntl: IntlShapeEx = { + formatUnixTimeStamp, + formatIsoDate, t, te, tm, diff --git a/packages/core/i18n/src/types/index.ts b/packages/core/i18n/src/types/index.ts index 34f83a7ad3..a054654f8e 100644 --- a/packages/core/i18n/src/types/index.ts +++ b/packages/core/i18n/src/types/index.ts @@ -15,6 +15,8 @@ export type PathToDotNotation = MessageSource extends V ? '' : // Omit the native $t function export type IntlShapeEx> = Omit & { + formatUnixTimeStamp: (timestamp: number) => string + formatIsoDate: (isoDate: string) => string t: (translationKey: PathToDotNotation, values?: Record | undefined, opts?: IntlMessageFormatOptions) => string te: (translationKey: PathToDotNotation) => boolean tm: (translationKey: PathToDotNotation) => Array