Updates TimeUtil Class
- Adds the `date-fns-tz` module to dep. - Moves the `date-fns` module from development dependancies to dependancies. - Removes the depreciated `substr` method usage. - Adds the `pad` method to handle padding time digits. - Dates and times are now standardized UTC. - Adds basic tests for all methods.
This commit is contained in:
parent
262c8a6e83
commit
3ba9e48a3e
@ -29,6 +29,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"atomically": "1.7.0",
|
"atomically": "1.7.0",
|
||||||
|
"date-fns": "^2.30.0",
|
||||||
|
"date-fns-tz": "^2.0.0",
|
||||||
"i18n": "0.15.1",
|
"i18n": "0.15.1",
|
||||||
"json-fixer": "1.6.15",
|
"json-fixer": "1.6.15",
|
||||||
"json5": "2.2.3",
|
"json5": "2.2.3",
|
||||||
@ -59,7 +61,6 @@
|
|||||||
"@vitest/coverage-istanbul": "1.0.0-beta.3",
|
"@vitest/coverage-istanbul": "1.0.0-beta.3",
|
||||||
"@vitest/ui": "1.0.0-beta.3",
|
"@vitest/ui": "1.0.0-beta.3",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"date-fns": "^2.30.0",
|
|
||||||
"eslint": "8.51.0",
|
"eslint": "8.51.0",
|
||||||
"gulp": "4.0.2",
|
"gulp": "4.0.2",
|
||||||
"gulp-execa": "5.0.1",
|
"gulp-execa": "5.0.1",
|
||||||
|
@ -1,41 +1,77 @@
|
|||||||
import { injectable } from "tsyringe";
|
import { injectable } from "tsyringe";
|
||||||
|
import { formatInTimeZone } from "date-fns-tz";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to handle time related problems
|
* Utility class to handle time related operations.
|
||||||
*/
|
*/
|
||||||
@injectable()
|
@injectable()
|
||||||
export class TimeUtil
|
export class TimeUtil
|
||||||
{
|
{
|
||||||
public static readonly oneHourAsSeconds = 3600;
|
public static readonly oneHourAsSeconds = 3600; // Number of seconds in one hour.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pads a number with a leading zero if it is less than 10.
|
||||||
|
*
|
||||||
|
* @param {number} number - The number to pad.
|
||||||
|
* @returns {string} The padded number as a string.
|
||||||
|
*/
|
||||||
|
private pad(number: number): string
|
||||||
|
{
|
||||||
|
return String(number).padStart(2, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the time part of a date as a UTC string.
|
||||||
|
*
|
||||||
|
* @param {Date} date - The date to format in UTC.
|
||||||
|
* @returns {string} The formatted time as 'HH-MM-SS'.
|
||||||
|
*/
|
||||||
public formatTime(date: Date): string
|
public formatTime(date: Date): string
|
||||||
{
|
{
|
||||||
const hours = `0${date.getHours()}`.substr(-2);
|
const hours = this.pad(date.getUTCHours());
|
||||||
const minutes = `0${date.getMinutes()}`.substr(-2);
|
const minutes = this.pad(date.getUTCMinutes());
|
||||||
const seconds = `0${date.getSeconds()}`.substr(-2);
|
const seconds = this.pad(date.getUTCSeconds());
|
||||||
return `${hours}-${minutes}-${seconds}`;
|
return `${hours}-${minutes}-${seconds}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the date part of a date as a UTC string.
|
||||||
|
*
|
||||||
|
* @param {Date} date - The date to format in UTC.
|
||||||
|
* @returns {string} The formatted date as 'YYYY-MM-DD'.
|
||||||
|
*/
|
||||||
public formatDate(date: Date): string
|
public formatDate(date: Date): string
|
||||||
{
|
{
|
||||||
const day = `0${date.getDate()}`.substr(-2);
|
const day = this.pad(date.getUTCDate());
|
||||||
const month = `0${date.getMonth() + 1}`.substr(-2);
|
const month = this.pad(date.getUTCMonth() + 1); // getUTCMonth returns 0-11
|
||||||
return `${date.getFullYear()}-${month}-${day}`;
|
const year = date.getUTCFullYear();
|
||||||
|
return `${year}-${month}-${day}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current date as a formatted UTC string.
|
||||||
|
*
|
||||||
|
* @returns {string} The current date as 'YYYY-MM-DD'.
|
||||||
|
*/
|
||||||
public getDate(): string
|
public getDate(): string
|
||||||
{
|
{
|
||||||
return this.formatDate(new Date());
|
return this.formatDate(new Date());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current time as a formatted UTC string.
|
||||||
|
*
|
||||||
|
* @returns {string} The current time as 'HH-MM-SS'.
|
||||||
|
*/
|
||||||
public getTime(): string
|
public getTime(): string
|
||||||
{
|
{
|
||||||
return this.formatTime(new Date());
|
return this.formatTime(new Date());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get timestamp in seconds
|
* Gets the current timestamp in seconds in UTC.
|
||||||
* @returns
|
*
|
||||||
|
* @returns {number} The current timestamp in seconds since the Unix epoch in UTC.
|
||||||
*/
|
*/
|
||||||
public getTimestamp(): number
|
public getTimestamp(): number
|
||||||
{
|
{
|
||||||
@ -43,36 +79,33 @@ export class TimeUtil
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mail in eft requires time be in a specific format
|
* Gets the current time in UTC in a format suitable for mail in EFT.
|
||||||
* @returns current time in format: 00:00 (hh:mm)
|
*
|
||||||
|
* @returns {string} The current time as 'HH:MM' in UTC.
|
||||||
*/
|
*/
|
||||||
public getTimeMailFormat(): string
|
public getTimeMailFormat(): string
|
||||||
{
|
{
|
||||||
const date = new Date();
|
return formatInTimeZone(new Date(), "UTC", "HH:mm");
|
||||||
const hours = `0${date.getHours()}`.substr(-2);
|
|
||||||
const minutes = `0${date.getMinutes()}`.substr(-2);
|
|
||||||
return `${hours}:${minutes}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mail in eft requires date be in a specific format
|
* Gets the current date in UTC in a format suitable for emails in EFT.
|
||||||
* @returns current date in format: 00.00.0000 (dd.mm.yyyy)
|
*
|
||||||
|
* @returns {string} The current date as 'DD.MM.YYYY' in UTC.
|
||||||
*/
|
*/
|
||||||
public getDateMailFormat(): string
|
public getDateMailFormat(): string
|
||||||
{
|
{
|
||||||
const date = new Date();
|
return formatInTimeZone(new Date(), "UTC", "dd.MM.yyyy");
|
||||||
const day = `0${date.getDate()}`.substr(-2);
|
|
||||||
const month = `0${date.getMonth() + 1}`.substr(-2);
|
|
||||||
return `${day}.${month}.${date.getFullYear()}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert hours into seconds
|
* Converts a number of hours into seconds.
|
||||||
* @param hours hours to convert to seconds
|
*
|
||||||
* @returns number
|
* @param {number} hours - The number of hours to convert.
|
||||||
|
* @returns {number} The equivalent number of seconds.
|
||||||
*/
|
*/
|
||||||
public getHoursAsSeconds(hours: number): number
|
public getHoursAsSeconds(hours: number): number
|
||||||
{
|
{
|
||||||
return hours * 3600;
|
return hours * TimeUtil.oneHourAsSeconds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
122
project/tests/utils/TimeUtil.test.ts
Normal file
122
project/tests/utils/TimeUtil.test.ts
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import "reflect-metadata";
|
||||||
|
import { container } from "tsyringe";
|
||||||
|
import { vi, afterEach, describe, expect, it, beforeEach } from "vitest";
|
||||||
|
|
||||||
|
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
|
||||||
|
|
||||||
|
describe("TimeUtil", () =>
|
||||||
|
{
|
||||||
|
let timeUtil: TimeUtil;
|
||||||
|
let mockedCurrentDate: Date;
|
||||||
|
|
||||||
|
beforeEach(() =>
|
||||||
|
{
|
||||||
|
timeUtil = container.resolve<TimeUtil>("TimeUtil");
|
||||||
|
|
||||||
|
mockedCurrentDate = new Date("2023-01-01T00:00:00Z");
|
||||||
|
vi.useFakeTimers();
|
||||||
|
vi.setSystemTime(mockedCurrentDate);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() =>
|
||||||
|
{
|
||||||
|
vi.useRealTimers();
|
||||||
|
vi.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("pad", () =>
|
||||||
|
{
|
||||||
|
it("should pad a number with a leading zero if it is less than 10", () =>
|
||||||
|
{
|
||||||
|
const paddedNumber = (timeUtil as any).pad(1);
|
||||||
|
expect(paddedNumber).toBe("01");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not pad a number larger than 10", () =>
|
||||||
|
{
|
||||||
|
const paddedNumber = (timeUtil as any).pad(69);
|
||||||
|
expect(paddedNumber).toBe("69");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not pad a number in the hundreds", () =>
|
||||||
|
{
|
||||||
|
const paddedNumber = (timeUtil as any).pad(420);
|
||||||
|
expect(paddedNumber).toBe("420");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatTime", () =>
|
||||||
|
{
|
||||||
|
it("should format the time part of a date as \"HH-MM-SS\"", () =>
|
||||||
|
{
|
||||||
|
const date = new Date("2023-01-01T12:34:56Z");
|
||||||
|
const formattedTime = timeUtil.formatTime(date);
|
||||||
|
expect(formattedTime).toBe("12-34-56");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatDate", () =>
|
||||||
|
{
|
||||||
|
it("should format the date part of a date as \"YYYY-MM-DD\"", () =>
|
||||||
|
{
|
||||||
|
const date = new Date("2023-01-01T12:34:56Z");
|
||||||
|
const formattedDate = timeUtil.formatDate(date);
|
||||||
|
expect(formattedDate).toBe("2023-01-01");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getDate", () =>
|
||||||
|
{
|
||||||
|
it("should get the current date as a formatted UTC string", () =>
|
||||||
|
{
|
||||||
|
const currentDate = timeUtil.getDate();
|
||||||
|
expect(currentDate).toBe("2023-01-01");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getTime", () =>
|
||||||
|
{
|
||||||
|
it("should get the current time as a formatted UTC string", () =>
|
||||||
|
{
|
||||||
|
const currentTime = timeUtil.getTime();
|
||||||
|
expect(currentTime).toBe("00-00-00"); // The mocked date is at midnight UTC.
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getTimestamp", () =>
|
||||||
|
{
|
||||||
|
it("should get the current timestamp in seconds in UTC", () =>
|
||||||
|
{
|
||||||
|
const timestamp = timeUtil.getTimestamp();
|
||||||
|
expect(timestamp).toBe(Math.floor(mockedCurrentDate.getTime() / 1000));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getTimeMailFormat", () =>
|
||||||
|
{
|
||||||
|
it("should get the current time in UTC in a format suitable for mail in EFT", () =>
|
||||||
|
{
|
||||||
|
const timeMailFormat = timeUtil.getTimeMailFormat();
|
||||||
|
expect(timeMailFormat).toBe("00:00"); // The mocked date is at midnight UTC.
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getDateMailFormat", () =>
|
||||||
|
{
|
||||||
|
it("should get the current date in UTC in a format suitable for emails in EFT", () =>
|
||||||
|
{
|
||||||
|
const dateMailFormat = timeUtil.getDateMailFormat();
|
||||||
|
expect(dateMailFormat).toBe("01.01.2023");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getHoursAsSeconds", () =>
|
||||||
|
{
|
||||||
|
it("should convert a number of hours into seconds", () =>
|
||||||
|
{
|
||||||
|
const hours = 5;
|
||||||
|
const seconds = timeUtil.getHoursAsSeconds(hours);
|
||||||
|
expect(seconds).toBe(5 * 3600);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user