From a36b8e450176956d11c864e54b4a6709c1c00ef1 Mon Sep 17 00:00:00 2001 From: Shubham Thanki Date: Tue, 14 Apr 2026 22:47:57 +0530 Subject: [PATCH 1/4] fix: enhance DateUtil class with time zone handling and method improvements --- src/utils/date/DateUtil.ts | 130 +++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 64 deletions(-) diff --git a/src/utils/date/DateUtil.ts b/src/utils/date/DateUtil.ts index 0477c18..beb00c3 100644 --- a/src/utils/date/DateUtil.ts +++ b/src/utils/date/DateUtil.ts @@ -1,5 +1,20 @@ import { TZDate } from '@date-fns/tz'; -import { add, compareAsc, differenceInCalendarDays, differenceInCalendarMonths, differenceInCalendarYears, differenceInHours, differenceInSeconds, Duration, endOfDay, format, isLeapYear, isValid, parse, startOfDay } from 'date-fns'; +import { + add, + compareAsc, + differenceInCalendarDays, + differenceInCalendarMonths, + differenceInCalendarYears, + differenceInHours, + differenceInSeconds, + Duration, + endOfDay, + format, + isLeapYear, + isValid, + parse, + startOfDay, +} from 'date-fns'; import { IllegalArgumentException } from '../../exceptions'; /** @@ -8,16 +23,28 @@ import { IllegalArgumentException } from '../../exceptions'; */ export class DateUtil { - static readonly ISO_8601_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSxxx" - static readonly TIMEZONE = "UTC" + static readonly ISO_8601_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSxxx"; + static readonly DEFAULT_TIMEZONE = 'UTC'; + + protected static resolveTimeZone(timeZone?: string): string { + return timeZone || this.DEFAULT_TIMEZONE; + } + + protected static normalizeDate(date: Date | number): Date { + return typeof date === 'number' ? new Date(date) : date; + } + + protected static toTZDate(date: Date | number, timeZone?: string): TZDate { + return new TZDate(this.normalizeDate(date), this.resolveTimeZone(timeZone)); + } /** * Gets the current date and time in the specified time zone. - * @param timeZone The IANA time zone identifier. + * @param timeZone The IANA time zone identifier (default: UTC). * @returns Current date and time in the specified time zone. */ - static now(timeZone: string): Date { - return new TZDate(new Date(), timeZone); + static now(timeZone?: string): Date { + return new TZDate(new Date(), this.resolveTimeZone(timeZone)); } /** @@ -32,12 +59,12 @@ export class DateUtil { * Parses a date string into a Date object. * @param dateString The date string to parse. * @param dateFormat The format of the date string (default: ISO_8601_FORMAT). - * @param timeZone The IANA time zone identifier. + * @param timeZone The IANA time zone identifier (default: UTC). * @throws {IllegalArgumentException} If the date string is invalid. * @returns Parsed Date object. */ - static readDate(dateString: string, dateFormat = this.ISO_8601_FORMAT, timeZone: string): Date { - const date = parse(dateString, dateFormat, TZDate.tz(timeZone)); + static readDate(dateString: string, dateFormat: string = this.ISO_8601_FORMAT, timeZone?: string): Date { + const date = parse(dateString, dateFormat, TZDate.tz(this.resolveTimeZone(timeZone))); if (!isValid(date)) { throw new IllegalArgumentException('Invalid date string or date format'); } @@ -47,54 +74,52 @@ export class DateUtil { /** * Formats a Date or timestamp into a string. * @param date The date or timestamp to format. - * @param timeZone The IANA time zone identifier. + * @param timeZone The IANA time zone identifier (default: UTC). * @param dateFormat The desired output format (default: ISO_8601_FORMAT). * @returns Formatted date string. */ - static printDate(date: Date, timeZone: string, dateFormat?: string): string; - static printDate(date: number, timeZone: string, dateFormat?: string): string; - static printDate(date: Date | number, timeZone: string, dateFormat: string = this.ISO_8601_FORMAT): string { - const normalizedDate = this.normalizeDate(date); - return format(new TZDate(normalizedDate, timeZone), dateFormat); + static printDate(date: Date, timeZone?: string, dateFormat?: string): string; + static printDate(date: number, timeZone?: string, dateFormat?: string): string; + static printDate(date: Date | number, timeZone?: string, dateFormat: string = this.ISO_8601_FORMAT): string { + return format(this.toTZDate(date, timeZone), dateFormat); } /** * Gets the start of the day for a given date or timestamp. * @param date The date or timestamp to calculate from. - * @param timeZone The IANA time zone identifier. + * @param timeZone The IANA time zone identifier (default: UTC). * @returns The start of the day as a Date object. */ - static getStartOfDay(date: Date, timeZone: string): Date; - static getStartOfDay(date: number, timeZone: string): Date; - static getStartOfDay(date: Date | number, timeZone: string): Date { - const normalizedDate = this.normalizeDate(date); - return startOfDay(new TZDate(normalizedDate, timeZone)); + static getStartOfDay(date: Date, timeZone?: string): Date; + static getStartOfDay(date: number, timeZone?: string): Date; + static getStartOfDay(date: Date | number, timeZone?: string): Date { + return startOfDay(this.toTZDate(date, timeZone)); } /** * Gets the end of the day for a given date or timestamp. * @param date The date or timestamp to calculate from. - * @param timeZone The IANA time zone identifier. + * @param timeZone The IANA time zone identifier (default: UTC). * @returns The end of the day as a Date object. */ - static getEndOfDay(date: Date, timeZone: string): Date; - static getEndOfDay(date: number, timeZone: string): Date; - static getEndOfDay(date: Date | number, timeZone: string): Date { - const normalizedDate = this.normalizeDate(date); - return endOfDay(new TZDate(normalizedDate, timeZone)); + static getEndOfDay(date: Date, timeZone?: string): Date; + static getEndOfDay(date: number, timeZone?: string): Date; + static getEndOfDay(date: Date | number, timeZone?: string): Date { + return endOfDay(this.toTZDate(date, timeZone)); } /** * Checks if a date string is valid according to the specified format. * @param dateString The date string to validate. * @param dateFormat Optional date format (default: ISO_8601_FORMAT). + * @param timeZone Optional IANA time zone identifier (default: UTC). * @returns True if the date is valid, false otherwise. */ - static isValidDate(dateString: string, dateFormat?: string): boolean { + static isValidDate(dateString: string, dateFormat: string = this.ISO_8601_FORMAT, timeZone?: string): boolean { try { - DateUtil.readDate(dateString, dateFormat, "UTC"); + this.readDate(dateString, dateFormat, timeZone); return true; - } catch (error) { + } catch { return false; } } @@ -112,13 +137,10 @@ export class DateUtil { static daysInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number; static daysInBetween(firstDate: number, secondDate: number, timeZone?: string): number; static daysInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number { - const first = this.normalizeDate(firstDate); - const second = this.normalizeDate(secondDate); - const effectiveTimeZone = timeZone || this.TIMEZONE; return Math.abs( differenceInCalendarDays( - new TZDate(first, effectiveTimeZone), - new TZDate(second, effectiveTimeZone), + this.toTZDate(firstDate, timeZone), + this.toTZDate(secondDate, timeZone), ) ); } @@ -136,13 +158,10 @@ export class DateUtil { static monthsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number; static monthsInBetween(firstDate: number, secondDate: number, timeZone?: string): number; static monthsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number { - const first = this.normalizeDate(firstDate); - const second = this.normalizeDate(secondDate); - const effectiveTimeZone = timeZone || this.TIMEZONE; return Math.abs( differenceInCalendarMonths( - new TZDate(first, effectiveTimeZone), - new TZDate(second, effectiveTimeZone), + this.toTZDate(firstDate, timeZone), + this.toTZDate(secondDate, timeZone), ) ); } @@ -160,13 +179,10 @@ export class DateUtil { static yearsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number; static yearsInBetween(firstDate: number, secondDate: number, timeZone?: string): number; static yearsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number { - const first = this.normalizeDate(firstDate); - const second = this.normalizeDate(secondDate); - const effectiveTimeZone = timeZone || this.TIMEZONE; return Math.abs( differenceInCalendarYears( - new TZDate(first, effectiveTimeZone), - new TZDate(second, effectiveTimeZone), + this.toTZDate(firstDate, timeZone), + this.toTZDate(secondDate, timeZone), ) ); } @@ -182,9 +198,7 @@ export class DateUtil { static hoursInBetween(firstDate: Date, secondDate: Date): number; static hoursInBetween(firstDate: number, secondDate: number): number; static hoursInBetween(firstDate: Date | number, secondDate: Date | number): number { - const first = this.normalizeDate(firstDate); - const second = this.normalizeDate(secondDate); - return Math.abs(differenceInHours(first, second)); + return Math.abs(differenceInHours(this.normalizeDate(firstDate), this.normalizeDate(secondDate))); } /** @@ -198,9 +212,7 @@ export class DateUtil { static secondsInBetween(firstDate: Date, secondDate: Date): number; static secondsInBetween(firstDate: number, secondDate: number): number; static secondsInBetween(firstDate: Date | number, secondDate: Date | number): number { - const first = this.normalizeDate(firstDate); - const second = this.normalizeDate(secondDate); - return Math.abs(differenceInSeconds(first, second)); + return Math.abs(differenceInSeconds(this.normalizeDate(firstDate), this.normalizeDate(secondDate))); } /** @@ -212,10 +224,7 @@ export class DateUtil { static compareDates(firstDate: Date, secondDate: Date): -1 | 0 | 1; static compareDates(firstDate: number, secondDate: number): -1 | 0 | 1; static compareDates(firstDate: Date | number, secondDate: Date | number): -1 | 0 | 1 { - const first = this.normalizeDate(firstDate); - const second = this.normalizeDate(secondDate); - - return compareAsc(first, second) as -1 | 0 | 1; + return compareAsc(this.normalizeDate(firstDate), this.normalizeDate(secondDate)) as -1 | 0 | 1; } /** @@ -231,9 +240,7 @@ export class DateUtil { static addDuration(date: Date, duration: Duration, timeZone?: string): Date; static addDuration(date: number, duration: Duration, timeZone?: string): Date; static addDuration(date: Date | number, duration: Duration, timeZone?: string): Date { - const normalizedDate = this.normalizeDate(date); - const effectiveTimeZone = timeZone || this.TIMEZONE; - return add(new TZDate(normalizedDate, effectiveTimeZone), duration); + return add(this.toTZDate(date, timeZone), duration); } /** @@ -242,10 +249,9 @@ export class DateUtil { * @returns `true` if the year is a leap year, otherwise `false`. */ static isLeapYear(year: number): boolean { - return isLeapYear(DateUtil.readDate(year.toString(), 'yyyy', "UTC")); + return isLeapYear(this.readDate(year.toString(), 'yyyy')); } - /** * Converts a timestamp (in milliseconds) to a Date object. * @param milliseconds The timestamp in milliseconds since the Unix epoch. @@ -255,10 +261,6 @@ export class DateUtil { return new Date(milliseconds); } - protected static normalizeDate(date: Date | number): Date { - return typeof date === 'number' ? this.fromMillis(date) : date; - } - /** * Converts a Date object to a timestamp (in milliseconds). * @param date The Date object to convert. From 2d06c81f113910b642a7cfb5d787eb0768cfaad4 Mon Sep 17 00:00:00 2001 From: Shubham Thanki Date: Tue, 14 Apr 2026 22:48:11 +0530 Subject: [PATCH 2/4] fix: update version to 2.0.7 in package.json and package-lock.json --- package-lock.json | 201 ++++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 107 insertions(+), 96 deletions(-) diff --git a/package-lock.json b/package-lock.json index 39dfcdd..bdf91e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@org-quicko/core", - "version": "2.0.6", + "version": "2.0.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@org-quicko/core", - "version": "2.0.6", + "version": "2.0.7", "license": "ISC", "dependencies": { "@date-fns/tz": "^1.1.2", @@ -1158,9 +1158,9 @@ "license": "MIT" }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -1239,9 +1239,9 @@ "license": "MIT" }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -1479,9 +1479,9 @@ } }, "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", "dev": true, "license": "MIT", "engines": { @@ -1683,9 +1683,9 @@ "license": "MIT" }, "node_modules/@jest/reporters/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -2634,17 +2634,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.1.tgz", - "integrity": "sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ==", + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.2.tgz", + "integrity": "sha512-aC2qc5thQahutKjP+cl8cgN9DWe3ZUqVko30CMSZHnFEHyhOYoZSzkGtAI2mcwZ38xeImDucI4dnqsHiOYuuCw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.58.1", - "@typescript-eslint/type-utils": "8.58.1", - "@typescript-eslint/utils": "8.58.1", - "@typescript-eslint/visitor-keys": "8.58.1", + "@typescript-eslint/scope-manager": "8.58.2", + "@typescript-eslint/type-utils": "8.58.2", + "@typescript-eslint/utils": "8.58.2", + "@typescript-eslint/visitor-keys": "8.58.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -2657,22 +2657,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.58.1", + "@typescript-eslint/parser": "^8.58.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.1.tgz", - "integrity": "sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw==", + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.2.tgz", + "integrity": "sha512-/Zb/xaIDfxeJnvishjGdcR4jmr7S+bda8PKNhRGdljDM+elXhlvN0FyPSsMnLmJUrVG9aPO6dof80wjMawsASg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.58.1", - "@typescript-eslint/types": "8.58.1", - "@typescript-eslint/typescript-estree": "8.58.1", - "@typescript-eslint/visitor-keys": "8.58.1", + "@typescript-eslint/scope-manager": "8.58.2", + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/typescript-estree": "8.58.2", + "@typescript-eslint/visitor-keys": "8.58.2", "debug": "^4.4.3" }, "engines": { @@ -2688,14 +2688,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.1.tgz", - "integrity": "sha512-gfQ8fk6cxhtptek+/8ZIqw8YrRW5048Gug8Ts5IYcMLCw18iUgrZAEY/D7s4hkI0FxEfGakKuPK/XUMPzPxi5g==", + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.2.tgz", + "integrity": "sha512-Cq6UfpZZk15+r87BkIh5rDpi38W4b+Sjnb8wQCPPDDweS/LRCFjCyViEbzHk5Ck3f2QDfgmlxqSa7S7clDtlfg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.58.1", - "@typescript-eslint/types": "^8.58.1", + "@typescript-eslint/tsconfig-utils": "^8.58.2", + "@typescript-eslint/types": "^8.58.2", "debug": "^4.4.3" }, "engines": { @@ -2710,14 +2710,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.1.tgz", - "integrity": "sha512-TPYUEqJK6avLcEjumWsIuTpuYODTTDAtoMdt8ZZa93uWMTX13Nb8L5leSje1NluammvU+oI3QRr5lLXPgihX3w==", + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.2.tgz", + "integrity": "sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.58.1", - "@typescript-eslint/visitor-keys": "8.58.1" + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/visitor-keys": "8.58.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2728,9 +2728,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.1.tgz", - "integrity": "sha512-JAr2hOIct2Q+qk3G+8YFfqkqi7sC86uNryT+2i5HzMa2MPjw4qNFvtjnw1IiA1rP7QhNKVe21mSSLaSjwA1Olw==", + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.2.tgz", + "integrity": "sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A==", "dev": true, "license": "MIT", "engines": { @@ -2745,15 +2745,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.58.1.tgz", - "integrity": "sha512-HUFxvTJVroT+0rXVJC7eD5zol6ID+Sn5npVPWoFuHGg9Ncq5Q4EYstqR+UOqaNRFXi5TYkpXXkLhoCHe3G0+7w==", + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.58.2.tgz", + "integrity": "sha512-Z7EloNR/B389FvabdGeTo2XMs4W9TjtPiO9DAsmT0yom0bwlPyRjkJ1uCdW1DvrrrYP50AJZ9Xc3sByZA9+dcg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.58.1", - "@typescript-eslint/typescript-estree": "8.58.1", - "@typescript-eslint/utils": "8.58.1", + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/typescript-estree": "8.58.2", + "@typescript-eslint/utils": "8.58.2", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -2770,9 +2770,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.1.tgz", - "integrity": "sha512-io/dV5Aw5ezwzfPBBWLoT+5QfVtP8O7q4Kftjn5azJ88bYyp/ZMCsyW1lpKK46EXJcaYMZ1JtYj+s/7TdzmQMw==", + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.2.tgz", + "integrity": "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ==", "dev": true, "license": "MIT", "engines": { @@ -2784,16 +2784,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.1.tgz", - "integrity": "sha512-w4w7WR7GHOjqqPnvAYbazq+Y5oS68b9CzasGtnd6jIeOIeKUzYzupGTB2T4LTPSv4d+WPeccbxuneTFHYgAAWg==", + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.2.tgz", + "integrity": "sha512-ELGuoofuhhoCvNbQjFFiobFcGgcDCEm0ThWdmO4Z0UzLqPXS3KFvnEZ+SHewwOYHjM09tkzOWXNTv9u6Gqtyuw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.58.1", - "@typescript-eslint/tsconfig-utils": "8.58.1", - "@typescript-eslint/types": "8.58.1", - "@typescript-eslint/visitor-keys": "8.58.1", + "@typescript-eslint/project-service": "8.58.2", + "@typescript-eslint/tsconfig-utils": "8.58.2", + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/visitor-keys": "8.58.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -2812,16 +2812,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.1.tgz", - "integrity": "sha512-Ln8R0tmWC7pTtLOzgJzYTXSCjJ9rDNHAqTaVONF4FEi2qwce8mD9iSOxOpLFFvWp/wBFlew0mjM1L1ihYWfBdQ==", + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.2.tgz", + "integrity": "sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.58.1", - "@typescript-eslint/types": "8.58.1", - "@typescript-eslint/typescript-estree": "8.58.1" + "@typescript-eslint/scope-manager": "8.58.2", + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/typescript-estree": "8.58.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2836,13 +2836,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.1.tgz", - "integrity": "sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ==", + "version": "8.58.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.2.tgz", + "integrity": "sha512-f1WO2Lx8a9t8DARmcWAUPJbu0G20bJlj8L4z72K00TMeJAoyLr/tHhI/pzYBLrR4dXWkcxO1cWYZEOX8DKHTqA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/types": "8.58.2", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -3438,9 +3438,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.10.17", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.17.tgz", - "integrity": "sha512-HdrkN8eVG2CXxeifv/VdJ4A4RSra1DTW8dc/hdxzhGHN8QePs6gKaWM9pHPcpCoxYZJuOZ8drHmbdpLHjCYjLA==", + "version": "2.10.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.19.tgz", + "integrity": "sha512-qCkNLi2sfBOn8XhZQ0FXsT1Ki/Yo5P90hrkRamVFRS7/KV9hpfA4HkoWNU152+8w0zPjnxo5psx5NL3PSGgv5g==", "dev": true, "license": "Apache-2.0", "bin": { @@ -3561,9 +3561,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001787", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001787.tgz", - "integrity": "sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==", + "version": "1.0.30001788", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001788.tgz", + "integrity": "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==", "dev": true, "funding": [ { @@ -3912,9 +3912,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.334", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.334.tgz", - "integrity": "sha512-mgjZAz7Jyx1SRCwEpy9wefDS7GvNPazLthHg8eQMJ76wBdGQQDW33TCrUTvQ4wzpmOrv2zrFoD3oNufMdyMpog==", + "version": "1.5.336", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.336.tgz", + "integrity": "sha512-AbH9q9J455r/nLmdNZes0G0ZKcRX73FicwowalLs6ijwOmCJSRRrLX63lcAlzy9ux3dWK1w1+1nsBJEWN11hcQ==", "dev": true, "license": "ISC" }, @@ -3954,6 +3954,16 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.28.0", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", @@ -4183,9 +4193,9 @@ "license": "MIT" }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -5180,9 +5190,9 @@ "license": "MIT" }, "node_modules/jest-config/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -5529,9 +5539,9 @@ "license": "MIT" }, "node_modules/jest-runtime/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -6299,9 +6309,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.3.tgz", - "integrity": "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -6518,12 +6528,13 @@ } }, "node_modules/resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "dev": true, "license": "MIT", "dependencies": { + "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" @@ -6980,9 +6991,9 @@ "license": "MIT" }, "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 67fcf80..906e5ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@org-quicko/core", - "version": "2.0.6", + "version": "2.0.7", "description": "A library in typescript for common entities and utilities across Quicko", "author": "Quicko", "repository": { From e0b0707ced0ad85bfe37bbde9bd89fe600c7935b Mon Sep 17 00:00:00 2001 From: Shubham Thanki Date: Tue, 14 Apr 2026 22:56:15 +0530 Subject: [PATCH 3/4] fix: replace DEFAULT_TIMEZONE with TIMEZONE constant in DateUtil class --- src/utils/date/DateUtil.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/date/DateUtil.ts b/src/utils/date/DateUtil.ts index beb00c3..41fb1a9 100644 --- a/src/utils/date/DateUtil.ts +++ b/src/utils/date/DateUtil.ts @@ -24,10 +24,10 @@ import { IllegalArgumentException } from '../../exceptions'; export class DateUtil { static readonly ISO_8601_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSxxx"; - static readonly DEFAULT_TIMEZONE = 'UTC'; + static readonly TIMEZONE: string = 'UTC'; protected static resolveTimeZone(timeZone?: string): string { - return timeZone || this.DEFAULT_TIMEZONE; + return timeZone || this.TIMEZONE; } protected static normalizeDate(date: Date | number): Date { From a0f0486296ab8f19e4b9ab81135b9d5c42b56a5b Mon Sep 17 00:00:00 2001 From: Shubham Thanki Date: Tue, 14 Apr 2026 22:56:21 +0530 Subject: [PATCH 4/4] test: add UTC handling tests for DateUtil methods --- tests/DateUtil.test.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/DateUtil.test.ts b/tests/DateUtil.test.ts index 4dec031..a34bd22 100644 --- a/tests/DateUtil.test.ts +++ b/tests/DateUtil.test.ts @@ -17,6 +17,15 @@ describe("DateUtil", () => { // Allowing a difference of up to 1 second due to execution time expect(timeDifference).toBeLessThan(1000); }); + + it("should default to UTC timezone when timezone is omitted", () => { + const now = DateUtil.now(); + expect(now).toBeInstanceOf(Date); + + const currentUtcTime = new Date(); + const timeDifference = Math.abs(now.getTime() - currentUtcTime.getTime()); + expect(timeDifference).toBeLessThan(1000); + }); }); describe("nowInMillis()", () => { @@ -28,6 +37,13 @@ describe("DateUtil", () => { }); describe("readDate()", () => { + it("should parse valid date strings with UTC when timezone is omitted", () => { + const dateString = "2024-12-16T14:16:29.793Z"; + const date = DateUtil.readDate(dateString); + expect(date).toBeInstanceOf(Date); + expect(date.toISOString()).toBe("2024-12-16T14:16:29.793+00:00"); + }); + it("should parse valid date strings correctly", () => { const dateString = "2024-12-16T14:16:29.793Z"; const date = DateUtil.readDate(dateString, undefined, TIMEZONE_UTC); @@ -57,6 +73,12 @@ describe("DateUtil", () => { }); describe("printDate()", () => { + it("should format date using UTC when timezone is omitted", () => { + const date = new Date("2023-10-05T04:50:30.000Z"); + const formattedDate = DateUtil.printDate(date); + expect(formattedDate).toBe("2023-10-05T04:50:30.000+00:00"); + }); + it("should format date correctly using default format", () => { const date = new Date("2023-10-05T04:50:30.000Z"); const formattedDate = DateUtil.printDate(date, TIMEZONE_UTC); @@ -72,6 +94,12 @@ describe("DateUtil", () => { }); describe("getStartOfDay()", () => { + it("should return start of the day in UTC when timezone is omitted", () => { + const date = new Date("2023-10-05T12:00:00.000Z"); + const startOfDay = DateUtil.getStartOfDay(date); + expect(startOfDay.toISOString()).toBe("2023-10-05T00:00:00.000+00:00"); + }); + it("should return start of the day in UTC timezone", () => { const date = new Date("2023-10-05T12:00:00.000Z"); const startOfDay = DateUtil.getStartOfDay(date, TIMEZONE_UTC); @@ -80,6 +108,12 @@ describe("DateUtil", () => { }); describe("getEndOfDay()", () => { + it("should return end of the day in UTC when timezone is omitted", () => { + const date = new Date("2023-10-05T12:00:00.000Z"); + const endOfDay = DateUtil.getEndOfDay(date); + expect(endOfDay.toISOString()).toBe("2023-10-05T23:59:59.999+00:00"); + }); + it("should return end of the day in UTC timezone", () => { const date = new Date("2023-10-05T12:00:00.000Z"); const endOfDay = DateUtil.getEndOfDay(date, TIMEZONE_UTC);