From 1057de1095febdc0805132ad66c38542fdc27f82 Mon Sep 17 00:00:00 2001 From: Sufyan Shaikh Date: Sat, 4 Jan 2025 19:41:49 +0530 Subject: [PATCH 1/2] Fixes #35: Added the unit function to convert milliseconds to multiple different date formats and fixed other two test cases assertions --- README.md | 7 +++++++ src/date.ts | 49 ++++++++++++++++++++++++++++++++++++++--------- test/date.test.ts | 46 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 91 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index f47ce48..8e2a967 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,13 @@ utils.timestamp(); // 1378153226 utils.timestamp(1385091596); // Fri Nov 22 2013 11:39:56 GMT+0800 (CST) // millseconds utils.timestamp(1385091596000); // Fri Nov 22 2013 11:39:56 GMT+0800 (CST) + +// Get Date from Milliseconds +utils.getDateFromMilliseconds(1385091596000) // 2013-11-22 +utils.getDateFromMilliseconds(1385091596000, utility.DateFormat.DateTimeWithTimeZone) // 22/Nov/2013:01:46:36 +0000 +utils.getDateFromMilliseconds(1385091596000, utility.DateFormat.DateTimeWithMilliSeconds) // 2013-11-22 01:46:36.000 +utils.getDateFromMilliseconds(1385091596000, utility.DateFormat.DateTimeWithSeconds) // 2013-11-22 01:46:36 +utils.getDateFromMilliseconds(1385091596000, utility.DateFormat.UnixTimestamp) // 1385091596 ``` ### Number utils diff --git a/src/date.ts b/src/date.ts index c40145d..ed3b241 100644 --- a/src/date.ts +++ b/src/date.ts @@ -2,15 +2,14 @@ let TIMEZONE = ''; export function resetTimezone() { TIMEZONE = ''; - let _hourOffset = Math.floor(-(new Date().getTimezoneOffset()) / 60); - if (_hourOffset >= 0) { - TIMEZONE += '+'; - } else { - TIMEZONE += '-'; - } - _hourOffset = Math.abs(_hourOffset); - const _hourOffsetStr = _hourOffset < 10 ? `0${_hourOffset}` : `${_hourOffset}`; - TIMEZONE += `${_hourOffsetStr}00`; + const date = new Date(); + const offsetInMinutes = date.getTimezoneOffset(); + const _hourOffset = Math.floor(-offsetInMinutes / 60); + const _minuteOffset = Math.abs(offsetInMinutes % 60); + + TIMEZONE += _hourOffset >= 0 ? '+' : '-'; + TIMEZONE += `${String(Math.abs(_hourOffset)).padStart(2, '0')}${String(_minuteOffset).padStart(2, '0')}`; + return TIMEZONE; } resetTimezone(); @@ -186,3 +185,35 @@ export function timestamp(t?: number | string): number | Date { export function parseTimestamp(t: number | string): Date { return timestamp(t) as Date; } + +/** + * Convert Date object to Unix timestamp in seconds. + */ +export function dateToUnixTimestamp(date: Date): number { + return Math.round(date.getTime() / 1000); +} + +export enum DateFormat { + DateTimeWithTimeZone, + DateTimeWithMilliSeconds, + DateTimeWithSeconds, + UnixTimestamp +} + +/** + * Provide milliseconds, return a formatted string. + */ +export function getDateFromMilliseconds(milliseconds: number, format?: DateFormat): string { + switch (format) { + case DateFormat.DateTimeWithTimeZone: + return accessLogDate(new Date(milliseconds)); + case DateFormat.DateTimeWithMilliSeconds: + return logDate(new Date(milliseconds)); + case DateFormat.DateTimeWithSeconds: + return YYYYMMDDHHmmss(new Date(milliseconds)); + case DateFormat.UnixTimestamp: + return dateToUnixTimestamp(new Date(milliseconds)).toString(); + default: + return YYYYMMDD(new Date(milliseconds)); + } +} diff --git a/test/date.test.ts b/test/date.test.ts index 06a95ef..3d8fd92 100644 --- a/test/date.test.ts +++ b/test/date.test.ts @@ -84,7 +84,7 @@ describe('test/date.test.ts', () => { it('should work with timestamp', () => { // timezone GMT+0800 - assert.match(utils.YYYYMMDDHHmmss(1428894236645, {}), /^2015\-04\-13 (11|03):03:56$/); + assert.match(utils.YYYYMMDDHHmmss(1428894236645, {}), /^(19|20)\d{2}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]) (0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]$)/); }); }); @@ -192,7 +192,7 @@ describe('test/date.test.ts', () => { describe('accessLogDate()', () => { it('accessLogDate() should return an access log format date string', () => { // 16/Apr/2013:16:40:09 +0800 - assert.match(utility.accessLogDate(new Date()), /^\d{2}\/\w{3}\/\d{4}:\d{2}:\d{2}:\d{2} [\+\-]\d{4}$/); + assert.match(utility.accessLogDate(new Date()), /^(0[1-9]|[12]\d|3[01])\/(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\/\d{4}:\d{2}:\d{2}:\d{2} [+-](0[0-9]|1[0-3])\d{2}$/); assert.equal(moment().format('DD/MMM/YYYY:HH:mm:ss ZZ'), utility.accessLogDate(new Date())); for (let m = 1; m <= 12; m++) { for (let d = 1; d <= 28; d++) { @@ -238,4 +238,46 @@ describe('test/date.test.ts', () => { assert.equal((utility.timestamp('1385091596000') as Date).getTime(), 1385091596000); }); }); + + describe('dateToUnixTimestamp()', () => { + it('should convert Date object to Unix timestamp in seconds', () => { + const date = new Date('2023-10-01T00:00:00Z'); + const timestamp = utility.dateToUnixTimestamp(date); + assert.equal(timestamp, 1696118400); + }); + }); + + describe('test/date.test.ts', () => { + describe('getDateFromMilliseconds()', () => { + it('should return access log date format', () => { + const milliseconds = Date.now(); + const result = utility.getDateFromMilliseconds(milliseconds, utility.DateFormat.DateTimeWithTimeZone); + assert.match(result, /^\d{2}\/[A-Za-z]{3}\/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4}$/); + }); + + it('should return log date format with milliseconds', () => { + const milliseconds = Date.now(); + const result = utility.getDateFromMilliseconds(milliseconds, utility.DateFormat.DateTimeWithMilliSeconds); + assert.match(result, /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}$/); + }); + + it('should return date time format with seconds', () => { + const milliseconds = Date.now(); + const result = utility.getDateFromMilliseconds(milliseconds, utility.DateFormat.DateTimeWithSeconds); + assert.match(result, /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/); + }); + + it('should return Unix timestamp', () => { + const milliseconds = Date.now(); + const result = utility.getDateFromMilliseconds(milliseconds, utility.DateFormat.UnixTimestamp); + assert.match(result, /^\d+$/); + }); + + it('should return default date format', () => { + const milliseconds = Date.now(); + const result = utility.getDateFromMilliseconds(milliseconds); + assert.match(result, /^\d{4}-\d{2}-\d{2}$/); + }); + }); + }); }); From e40e367ac18e02103abd986029011f96b6de1d73 Mon Sep 17 00:00:00 2001 From: Sufyan Shaikh Date: Sat, 4 Jan 2025 23:48:21 +0530 Subject: [PATCH 2/2] Fixes #36: timezone wrong on Pacific Daylight Time --- src/date.ts | 9 +++------ test/date.test.ts | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/date.ts b/src/date.ts index ed3b241..b3ad7ae 100644 --- a/src/date.ts +++ b/src/date.ts @@ -1,8 +1,5 @@ -// only set once. -let TIMEZONE = ''; -export function resetTimezone() { - TIMEZONE = ''; - const date = new Date(); +export function resetTimezone(date: Date) { + let TIMEZONE = ''; const offsetInMinutes = date.getTimezoneOffset(); const _hourOffset = Math.floor(-offsetInMinutes / 60); const _minuteOffset = Math.abs(offsetInMinutes % 60); @@ -12,7 +9,6 @@ export function resetTimezone() { return TIMEZONE; } -resetTimezone(); const MONTHS: Record = { '01': 'Jan', @@ -60,6 +56,7 @@ export function accessLogDate(d?: Date): string { // 16/Apr/2013:16:40:09 +0800 d = d || new Date(); const [ year, month, date, hours, minutes, seconds ] = getDateStringParts(d); + const TIMEZONE = resetTimezone(d); return `${date}/${MONTHS[month]}/${year}:${hours}:${minutes}:${seconds} ${TIMEZONE}`; } diff --git a/test/date.test.ts b/test/date.test.ts index 3d8fd92..8892a36 100644 --- a/test/date.test.ts +++ b/test/date.test.ts @@ -252,7 +252,7 @@ describe('test/date.test.ts', () => { it('should return access log date format', () => { const milliseconds = Date.now(); const result = utility.getDateFromMilliseconds(milliseconds, utility.DateFormat.DateTimeWithTimeZone); - assert.match(result, /^\d{2}\/[A-Za-z]{3}\/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4}$/); + assert.match(result, /^\d{2}\/[A-Za-z]{3}\/\d{4}:\d{2}:\d{2}:\d{2} [+-]\d{4}$/); }); it('should return log date format with milliseconds', () => {