Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 59 additions & 1 deletion src/datetime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,65 @@ export class DateTime<T extends Time | undefined> {
return DateTime.create(year, month, day, hour, minute, second, true);
}

/**
* Creates a new UTC DateTime object from a JavaScript Date object.
*
* The resulting DateTime will have `utc` set to `true` and will represent
* the same moment in time as the input Date object.
*
* @param date - A JavaScript Date object
* @returns A DateTime instance with UTC time
*
* @example
* ```typescript
* const jsDate = new Date('2024-01-15T14:30:00.000Z');
* const datetime = DateTime.fromDate(jsDate);
* console.log(datetime.year); // 2024
* console.log(datetime.month); // 1
* console.log(datetime.day); // 15
* console.log(datetime.time.hour); // 14
* console.log(datetime.time.minute); // 30
* console.log(datetime.time.second); // 0
* console.log(datetime.time.utc); // true
* ```
*/
public static fromDate(date: Date): DateTime<Time> {
return DateTime.utc(
date.getUTCFullYear(),
date.getUTCMonth() + 1,
date.getUTCDate(),
date.getUTCHours(),
date.getUTCMinutes(),
date.getUTCSeconds(),
);
}

/**
* Creates a new UTC DateTime object from a Unix timestamp in milliseconds.
*
* The resulting DateTime will have `utc` set to `true` and will represent
* the moment in time corresponding to the given timestamp.
*
* @param timestamp - Unix timestamp in milliseconds since January 1, 1970 00:00:00 UTC
* @returns A DateTime instance with UTC time
*
* @example
* ```typescript
* const timestamp = Date.UTC(2024, 0, 15, 14, 30, 0); // 1705329000000
* const datetime = DateTime.fromTimestamp(timestamp);
* console.log(datetime.year); // 2024
* console.log(datetime.month); // 1
* console.log(datetime.day); // 15
* console.log(datetime.time.hour); // 14
* console.log(datetime.time.minute); // 30
* console.log(datetime.time.second); // 0
* console.log(datetime.time.utc); // true
* ```
*/
public static fromTimestamp(timestamp: number): DateTime<Time> {
return DateTime.fromDate(new Date(timestamp));
}

/**
* Creates a new DateTime object from a plain object representation.
*
Expand Down Expand Up @@ -310,7 +369,6 @@ export class DateTime<T extends Time | undefined> {
* const utc = DateTime.fromString("20240115T143000Z");
* ```
*/
// TODO: add template expression
public static fromString(str: string): DateTime<Time> | DateTime<undefined> {
if (!(str.length === 8 || (str.length <= 16 && str.length >= 15))) {
throw new TypeError('Invalid date time string');
Expand Down
111 changes: 111 additions & 0 deletions tests/unit/datetime.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,117 @@ describe(DateTime, () => {
});
});

describe('fromDate', () => {
it.each([
{
year: 2024,
month: 1,
day: 15,
hour: 14,
minute: 30,
second: 0,
},
{
year: 2005,
month: 9,
day: 4,
hour: 9,
minute: 1,
second: 2,
},
{
year: 1970,
month: 1,
day: 1,
hour: 0,
minute: 0,
second: 0,
},
])(
'should create UTC datetime from Date $input',
({ year, month, day, hour, minute, second }) => {
const datetime = DateTime.fromDate(
new Date(Date.UTC(year, month - 1, day, hour, minute, second)),
);

expect(datetime.year).toBe(year);
expect(datetime.month).toBe(month);
expect(datetime.day).toBe(day);
expect(datetime.time.hour).toBe(hour);
expect(datetime.time.minute).toBe(minute);
expect(datetime.time.second).toBe(second);
expect(datetime.time.utc).toBe(true);
},
);

it('should be convertible back to Date', () => {
const originalDate = new Date(Date.UTC(2024, 5, 20, 10, 30, 45));
const datetime = DateTime.fromDate(originalDate);
const convertedDate = datetime.toDate();

expect(convertedDate.getTime()).toBe(originalDate.getTime());
});
});

describe('fromTimestamp', () => {
it.each([
{
timestamp: Date.UTC(2024, 0, 15, 14, 30, 0),
expected: {
year: 2024,
month: 1,
day: 15,
hour: 14,
minute: 30,
second: 0,
},
},
{
timestamp: Date.UTC(2005, 8, 4, 9, 1, 2),
expected: {
year: 2005,
month: 9,
day: 4,
hour: 9,
minute: 1,
second: 2,
},
},
{
timestamp: 0,
expected: {
year: 1970,
month: 1,
day: 1,
hour: 0,
minute: 0,
second: 0,
},
},
])(
'should create UTC datetime from timestamp $input',
({ timestamp, expected }) => {
const datetime = DateTime.fromTimestamp(timestamp);

expect(datetime.year).toBe(expected.year);
expect(datetime.month).toBe(expected.month);
expect(datetime.day).toBe(expected.day);
expect(datetime.time.hour).toBe(expected.hour);
expect(datetime.time.minute).toBe(expected.minute);
expect(datetime.time.second).toBe(expected.second);
expect(datetime.time.utc).toBe(true);
},
);

it('should be convertible back to timestamp', () => {
const originalTimestamp = Date.UTC(2024, 5, 20, 10, 30, 45);
const datetime = DateTime.fromTimestamp(originalTimestamp);
const convertedTimestamp = datetime.toTimestamp();

expect(convertedTimestamp).toBe(originalTimestamp);
});
});

describe('fromPlain', () => {
it.each([
{
Expand Down
Loading