mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(core)!: Make date extensions outputs match inputs (#6435)
This commit is contained in:
parent
632ea275b7
commit
85372aabdf
|
@ -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 = {
|
||||||
|
|
|
@ -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(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue