fix(core)!: Make date extensions outputs match inputs (#6435)

This commit is contained in:
Iván Ovejero 2023-06-15 10:07:47 +02:00 committed by कारतोफ्फेलस्क्रिप्ट™
parent 632ea275b7
commit 85372aabdf
2 changed files with 66 additions and 46 deletions

View file

@ -70,57 +70,54 @@ const DATETIMEUNIT_MAP: Record<string, DateTimeUnit> = {
ms: 'millisecond', ms: 'millisecond',
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any function isDateTime(date: unknown): date is DateTime {
function isDateTime(date: any): date is DateTime { return date ? DateTime.isDateTime(date) : false;
if (date) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
return DateTime.isDateTime(date);
}
return false;
} }
function generateDurationObject(durationValue: number, unit: DurationUnit) { function generateDurationObject(durationValue: number, unit: DurationUnit): DurationObjectUnits {
const convertedUnit = DURATION_MAP[unit] || unit; const convertedUnit = DURATION_MAP[unit] || unit;
return { [`${convertedUnit}`]: durationValue } as DurationObjectUnits; return { [`${convertedUnit}`]: durationValue };
} }
function beginningOf(date: Date | DateTime, extraArgs: DurationUnit[]): Date { function beginningOf(date: Date | DateTime, extraArgs: DurationUnit[]): Date | DateTime {
const [unit = 'week'] = extraArgs; const [rawUnit = 'week'] = extraArgs;
if (isDateTime(date)) { const unit = DATETIMEUNIT_MAP[rawUnit] || rawUnit;
return date.startOf(DATETIMEUNIT_MAP[unit] || unit).toJSDate();
} if (isDateTime(date)) return date.startOf(unit);
const dateTime = DateTime.fromJSDate(date);
return dateTime.startOf(DATETIMEUNIT_MAP[unit] || unit).toJSDate(); return DateTime.fromJSDate(date).startOf(unit).toJSDate();
} }
function endOfMonth(date: Date | DateTime): Date { function endOfMonth(date: Date | DateTime): Date | DateTime {
if (isDateTime(date)) { if (isDateTime(date)) return date.endOf('month');
return date.endOf('month').toJSDate();
}
return DateTime.fromJSDate(date).endOf('month').toJSDate(); return DateTime.fromJSDate(date).endOf('month').toJSDate();
} }
function extract(inputDate: Date | DateTime, extraArgs: DatePart[]): number | Date { function extract(date: Date | DateTime, args: DatePart[]): number {
let [part = 'week'] = extraArgs; let [part = 'week'] = args;
let date = inputDate;
if (isDateTime(date)) {
date = date.toJSDate();
}
if (part === 'yearDayNumber') { if (part === 'yearDayNumber') {
date = isDateTime(date) ? date.toJSDate() : date;
const firstDayOfTheYear = new Date(date.getFullYear(), 0, 0); const firstDayOfTheYear = new Date(date.getFullYear(), 0, 0);
const diff = const diff =
date.getTime() - date.getTime() -
firstDayOfTheYear.getTime() + firstDayOfTheYear.getTime() +
(firstDayOfTheYear.getTimezoneOffset() - date.getTimezoneOffset()) * 60 * 1000; (firstDayOfTheYear.getTimezoneOffset() - date.getTimezoneOffset()) * 60 * 1000;
return Math.floor(diff / (1000 * 60 * 60 * 24)); return Math.floor(diff / (1000 * 60 * 60 * 24));
} }
if (part === 'week') { if (part === 'week') part = 'weekNumber';
part = 'weekNumber';
}
return DateTime.fromJSDate(date).get((DATETIMEUNIT_MAP[part] as keyof DateTime) || part); const unit = (DATETIMEUNIT_MAP[part] as keyof DateTime) || part;
if (isDateTime(date)) return date.get(unit);
return DateTime.fromJSDate(date).get(unit);
} }
function format(date: Date | DateTime, extraArgs: unknown[]): string { function format(date: Date | DateTime, extraArgs: unknown[]): string {
@ -178,30 +175,46 @@ function isWeekend(date: Date | DateTime): boolean {
return WEEKEND_DAYS.includes(weekday); return WEEKEND_DAYS.includes(weekday);
} }
function minus(date: Date | DateTime, extraArgs: unknown[]): Date | DateTime { function minus(
if (isDateTime(date) && extraArgs.length === 1) { date: Date | DateTime,
return date.minus(extraArgs[0] as DurationLike); args: [DurationLike] | [number, DurationUnit],
): Date | DateTime {
if (args.length === 1) {
const [arg] = args;
if (isDateTime(date)) return date.minus(arg);
return DateTime.fromJSDate(date).minus(arg).toJSDate();
} }
const [durationValue = 0, unit = 'minutes'] = extraArgs as [number, DurationUnit]; const [durationValue = 0, unit = 'minutes'] = args;
if (isDateTime(date)) { const duration = generateDurationObject(durationValue, unit);
return date.minus(generateDurationObject(durationValue, unit)).toJSDate();
} if (isDateTime(date)) return date.minus(duration);
return DateTime.fromJSDate(date).minus(generateDurationObject(durationValue, unit)).toJSDate();
return DateTime.fromJSDate(date).minus(duration).toJSDate();
} }
function plus(date: Date | DateTime, extraArgs: unknown[]): Date | DateTime { function plus(
if (isDateTime(date) && extraArgs.length === 1) { date: Date | DateTime,
return date.plus(extraArgs[0] as DurationLike); args: [DurationLike] | [number, DurationUnit],
): Date | DateTime {
if (args.length === 1) {
const [arg] = args;
if (isDateTime(date)) return date.plus(arg);
return DateTime.fromJSDate(date).plus(arg).toJSDate();
} }
const [durationValue = 0, unit = 'minutes'] = extraArgs as [number, DurationUnit]; const [durationValue = 0, unit = 'minutes'] = args;
if (isDateTime(date)) { const duration = generateDurationObject(durationValue, unit);
return date.plus(generateDurationObject(durationValue, unit)).toJSDate();
} if (isDateTime(date)) return date.plus(duration);
return DateTime.fromJSDate(date).plus(generateDurationObject(durationValue, unit)).toJSDate();
return DateTime.fromJSDate(date).plus(duration).toJSDate();
} }
endOfMonth.doc = { endOfMonth.doc = {

View file

@ -16,6 +16,10 @@ describe('Data Transformation Functions', () => {
test('.beginningOf("week") should work correctly on a date', () => { test('.beginningOf("week") should work correctly on a date', () => {
expect(evaluate('={{ DateTime.local(2023, 1, 20).beginningOf("week") }}')).toEqual( expect(evaluate('={{ DateTime.local(2023, 1, 20).beginningOf("week") }}')).toEqual(
DateTime.local(2023, 1, 16, { zone: TEST_TIMEZONE }),
);
expect(evaluate('={{ new Date(2023, 0, 20).beginningOf("week") }}')).toEqual(
DateTime.local(2023, 1, 16, { zone: TEST_TIMEZONE }).toJSDate(), DateTime.local(2023, 1, 16, { zone: TEST_TIMEZONE }).toJSDate(),
); );
}); });
@ -49,6 +53,9 @@ describe('Data Transformation Functions', () => {
test('.endOfMonth() should work correctly on a date', () => { test('.endOfMonth() should work correctly on a date', () => {
expect(evaluate('={{ DateTime.local(2023, 1, 16).endOfMonth() }}')).toEqual( expect(evaluate('={{ DateTime.local(2023, 1, 16).endOfMonth() }}')).toEqual(
DateTime.local(2023, 1, 31, 23, 59, 59, 999, { zone: TEST_TIMEZONE }),
);
expect(evaluate('={{ new Date(2023, 0, 16).endOfMonth() }}')).toEqual(
DateTime.local(2023, 1, 31, 23, 59, 59, 999, { zone: TEST_TIMEZONE }).toJSDate(), DateTime.local(2023, 1, 31, 23, 59, 59, 999, { zone: TEST_TIMEZONE }).toJSDate(),
); );
}); });