diff --git a/src/date-util/date-util.spec.ts b/src/date-util/date-util.spec.ts index eea4d50..3540427 100644 --- a/src/date-util/date-util.spec.ts +++ b/src/date-util/date-util.spec.ts @@ -4,7 +4,11 @@ import { durationTo, endOfByTimezone, formatDate, + formatInIso8601, fromNow, + getDateString, + getDatetimeString, + getTimestampString, getTimezoneOffsetInHours, isAdult, isLastDateOfMonth, @@ -19,6 +23,7 @@ import { } from './date-util'; import { DATE_FORMAT, + DATETIME_FORMAT, DATETIME_FORMAT_WITH_MILLIS, TIMESTAMP_FORMAT, TIMEZONE_PST, @@ -482,6 +487,49 @@ describe('format', () => { }); }); +describe('formatInIso8601', () => { + it('should return formatted date string in ISO format string', () => { + const testDatetime = new Date(testDatetimeStr8); + expect(formatInIso8601(testDatetime, { format: DATE_FORMAT })).toEqual(testDateStr); + expect(formatInIso8601(testDatetime, { format: DATETIME_FORMAT })).toEqual(testDatetimeStr5); + expect(formatInIso8601(testDatetime, { format: DATETIME_FORMAT_WITH_MILLIS })).toEqual(testDatetimeStr8); + }); + it('should return formatted date string of local time', () => { + const testDatetime = new Date(testDatetimeStr8); + expect(formatInIso8601(testDatetime, { format: DATETIME_FORMAT, isUtc: false, timeZone: 'Asia/Seoul' })).toEqual( + `2022-02-23T10:23:45+09:00` + ); + expect(formatInIso8601(testDatetime, { isUtc: false, timeZone: 'PST8PDT' })).toEqual('2022-02-22T17:23:45-08:00'); + }); +}); + +describe('getDateString', () => { + it('should return formatted date string', () => { + expect(getDateString(new Date(testDatetimeStr8))).toBe(testDateStr); + }); + it('should return formatted date string of local time', () => { + expect(getDateString(new Date(testDatetimeStr6), false)).toBe(testDateStr); + }); +}); + +describe('getDatetimeString', () => { + it('should return format datetime string', () => { + expect(getDatetimeString(new Date(testDatetimeStr8))).toBe(testDatetimeStr5); + }); + it('should return formatted datetime string of local time', () => { + expect(getDatetimeString(new Date(testDatetimeStr8), false)).toBe('2022-02-23 10:23:45'); + }); +}); + +describe('getTimestampString', () => { + it('should return formatted timestamp string', () => { + expect(getTimestampString(new Date(testDatetimeStr8))).toBe(testTimestampStr); + }); + it('should return formatted timestamp string of local time', () => { + expect(getTimestampString(new Date(testDatetimeStr8), false)).toBe('20220223102345678'); + }); +}); + describe('durationTo', () => { it('시간을 초로 바꾸어 리턴한다.', () => { expect(durationTo('09:10:30')).toEqual(33030); diff --git a/src/date-util/date-util.ts b/src/date-util/date-util.ts index 0b5950f..dba532e 100644 --- a/src/date-util/date-util.ts +++ b/src/date-util/date-util.ts @@ -2,6 +2,7 @@ import { LoggerFactory } from '../logger'; import { DatePropertyType, DateType, TimeZoneType } from './date-util-base.type'; import { ADULT_AGE_DEFAULT, + DATE_FORMAT, DATETIME_FORMAT, LOCAL_DATETIME_FORMAT, ONE_DAY_IN_MILLI, @@ -14,7 +15,7 @@ import { TIMESTAMP_FORMAT, } from './date-util.const'; import type { TimeAnnotationSet } from './date-util.interface'; -import type { CalcDatetimeOpts, DatetimeFormatOpts } from './date-util.type'; +import type { CalcDatetimeOpts, DatetimeFormatOpts, IsoDatetimeFormatOpts } from './date-util.type'; const timeZoneMap: Record = { 'Asia/Seoul': 540, 'Asia/Tokyo': 540, PST8PDT: -480, UTC: 0 }; const logger = LoggerFactory.getLogger('pebbles:date-util'); @@ -372,6 +373,61 @@ export function formatDate(d: Date, opts?: Readonly): string }); } +/** + * + * @description It converts `date` in `opts.format` if it's given. Otherwise the default format would be `YYYY-MM-DDTHH:mm:ssZ`. + * - Other format options can be `YYYY-MM-DD` or `YYYY-MM-DDTHH:mm:ss.SSSZ`. + */ +export function formatInIso8601(date: Date, opts?: Readonly): string { + const formatOpts: IsoDatetimeFormatOpts = opts ?? {}; + formatOpts.format = opts?.format ?? DATETIME_FORMAT; + return formatDate(date, formatOpts); +} + +/** + * + * @description It converts `date` in `YYYY-MM-DD` format. + */ +export function getDateString(date: Date, isUtc = true, timeZone: TimeZoneType = 'Asia/Seoul'): string { + return formatDate(date, { format: DATE_FORMAT, isUtc, timeZone }); +} + +/** + * + * @description It converts `date` in `YYYY-MM-DDTHH:mm:ssZ` format if isUtc is true by default. + * Otherwise the format would be `YYYY-MM-DD HH:mm:ss`. + */ +export function getDatetimeString(date: Date, isUtc = true, timeZone: TimeZoneType = 'Asia/Seoul'): string { + return formatDate(date, { isUtc, timeZone }); +} + +/** + * + * @description It converts `date` in `YYYYMMDDHHmmssSSS` format. + */ +export function getTimestampString(date: Date, isUtc = true, timeZone: TimeZoneType = 'Asia/Seoul'): string { + return formatDate(date, { format: TIMESTAMP_FORMAT, isUtc, timeZone }); +} + +/** + * + * @description It converts `totalSeconds` in `hh:mm:ss` format. + */ +export function getTimeStringFromSeconds(totalSeconds: number): string { + if (totalSeconds < 0) { + throw new Error('Invalid number'); + } + + const seconds = totalSeconds % 60; + const totalMinutes = (totalSeconds - seconds) / 60; + const minutes = totalMinutes % 60; + const hh = String((totalMinutes - minutes) / 60).padStart(2, '0'); + const mm = String(minutes).padStart(2, '0'); + const ss = String(seconds).padStart(2, '0'); + + return `${hh}:${mm}:${ss}`; +} + export function durationTo(duration: string, unitType: DatePropertyType = 'second'): number { if (unitType !== 'second') { throw new Error('Not supported yet'); diff --git a/src/date-util/index.ts b/src/date-util/index.ts index 80055db..5f13c57 100644 --- a/src/date-util/index.ts +++ b/src/date-util/index.ts @@ -6,7 +6,12 @@ export { endOfByTimezone, format12HourInLocale, formatDate, + formatInIso8601, fromNow, + getDateString, + getDatetimeString, + getTimestampString, + getTimeStringFromSeconds, getTimezoneOffsetInHours, getTimezoneOffsetString, isAdult,