diff --git a/packages/nodes-base/nodes/DateTime/V2/DateTimeV2.node.ts b/packages/nodes-base/nodes/DateTime/V2/DateTimeV2.node.ts
index 74bb1e9ee7..adc8b44483 100644
--- a/packages/nodes-base/nodes/DateTime/V2/DateTimeV2.node.ts
+++ b/packages/nodes-base/nodes/DateTime/V2/DateTimeV2.node.ts
@@ -9,8 +9,6 @@ import type {
} from 'n8n-workflow';
import { deepCopy, NodeOperationError } from 'n8n-workflow';
-import set from 'lodash.set';
-
import moment from 'moment-timezone';
function parseDateByFormat(this: IExecuteFunctions, value: string, fromFormat: string) {
@@ -58,322 +56,41 @@ export class DateTimeV2 implements INodeType {
inputs: ['main'],
outputs: ['main'],
properties: [
- {
- displayName:
- "More powerful date functionality is available in expressions, e.g. {{ $now.plus(1, 'week') }}
",
- name: 'noticeDateTime',
- type: 'notice',
- default: '',
- },
{
displayName: 'Action',
name: 'action',
type: 'options',
options: [
{
- name: 'Calculate a Date',
- description: 'Add or subtract time from a date',
- value: 'calculate',
- action: 'Add or subtract time from a date',
+ name: 'Add to a Date',
+ value: 'addToDate',
+ },
+ {
+ name: 'Extract Part of a Date',
+ value: 'extractDate',
},
{
name: 'Format a Date',
- description: 'Convert a date to a different format',
- value: 'format',
- action: 'Convert a date to a different format',
- },
- ],
- default: 'format',
- },
- {
- displayName: 'Value',
- name: 'value',
- displayOptions: {
- show: {
- action: ['format'],
- },
- },
- type: 'string',
- default: '',
- description: 'The value that should be converted',
- required: true,
- },
- {
- displayName: 'Property Name',
- name: 'dataPropertyName',
- type: 'string',
- default: 'data',
- required: true,
- displayOptions: {
- show: {
- action: ['format'],
- },
- },
- description: 'Name of the property to which to write the converted date',
- },
- {
- displayName: 'Custom Format',
- name: 'custom',
- displayOptions: {
- show: {
- action: ['format'],
- },
- },
- type: 'boolean',
- default: false,
- description: 'Whether a predefined format should be selected or custom format entered',
- },
- {
- displayName: 'To Format',
- name: 'toFormat',
- displayOptions: {
- show: {
- action: ['format'],
- custom: [true],
- },
- },
- type: 'string',
- default: '',
- placeholder: 'YYYY-MM-DD',
- description: 'The format to convert the date to',
- },
- {
- displayName: 'To Format',
- name: 'toFormat',
- type: 'options',
- displayOptions: {
- show: {
- action: ['format'],
- custom: [false],
- },
- },
- // eslint-disable-next-line n8n-nodes-base/node-param-options-type-unsorted-items
- options: [
- {
- name: 'MM/DD/YYYY',
- value: 'MM/DD/YYYY',
- description: 'Example: 09/04/1986',
- },
- {
- name: 'YYYY/MM/DD',
- value: 'YYYY/MM/DD',
- description: 'Example: 1986/04/09',
- },
- {
- name: 'MMMM DD YYYY',
- value: 'MMMM DD YYYY',
- description: 'Example: April 09 1986',
- },
- {
- name: 'MM-DD-YYYY',
- value: 'MM-DD-YYYY',
- description: 'Example: 09-04-1986',
- },
- {
- name: 'YYYY-MM-DD',
- value: 'YYYY-MM-DD',
- description: 'Example: 1986-04-09',
- },
- {
- name: 'Unix Timestamp',
- value: 'X',
- description: 'Example: 513388800.879',
- },
- {
- name: 'Unix Ms Timestamp',
- value: 'x',
- description: 'Example: 513388800',
- },
- ],
- default: 'MM/DD/YYYY',
- description: 'The format to convert the date to',
- },
- {
- displayName: 'Options',
- name: 'options',
- displayOptions: {
- show: {
- action: ['format'],
- },
- },
- type: 'collection',
- placeholder: 'Add Option',
- default: {},
- options: [
- {
- displayName: 'From Format',
- name: 'fromFormat',
- type: 'string',
- default: '',
- description: 'In case the input format is not recognized you can provide the format',
- },
- {
- displayName: 'From Timezone Name or ID',
- name: 'fromTimezone',
- type: 'options',
- typeOptions: {
- loadOptionsMethod: 'getTimezones',
- },
- default: 'UTC',
- description:
- 'The timezone to convert from. Choose from the list, or specify an ID using an expression.',
- },
- {
- displayName: 'To Timezone Name or ID',
- name: 'toTimezone',
- type: 'options',
- typeOptions: {
- loadOptionsMethod: 'getTimezones',
- },
- default: 'UTC',
- description:
- 'The timezone to convert to. Choose from the list, or specify an ID using an expression.',
- },
- ],
- },
- {
- displayName: 'Date Value',
- name: 'value',
- displayOptions: {
- show: {
- action: ['calculate'],
- },
- },
- type: 'string',
- default: '',
- description: 'The date string or timestamp from which you want to add/subtract time',
- required: true,
- },
- {
- displayName: 'Operation',
- name: 'operation',
- displayOptions: {
- show: {
- action: ['calculate'],
- },
- },
- type: 'options',
- noDataExpression: true,
- options: [
- {
- name: 'Add',
- value: 'add',
- description: 'Add time to Date Value',
- action: 'Add time to Date Value',
- },
- {
- name: 'Subtract',
- value: 'subtract',
- description: 'Subtract time from Date Value',
- action: 'Subtract time from Date Value',
- },
- ],
- default: 'add',
- required: true,
- },
- {
- displayName: 'Duration',
- name: 'duration',
- displayOptions: {
- show: {
- action: ['calculate'],
- },
- },
- type: 'number',
- typeOptions: {
- minValue: 0,
- },
- default: 0,
- required: true,
- description:
- 'E.g. enter “10” then select “Days” if you want to add 10 days to Date Value.',
- },
- {
- displayName: 'Time Unit',
- name: 'timeUnit',
- description: 'Time unit for Duration parameter above',
- displayOptions: {
- show: {
- action: ['calculate'],
- },
- },
- type: 'options',
- // eslint-disable-next-line n8n-nodes-base/node-param-options-type-unsorted-items
- options: [
- {
- name: 'Quarters',
- value: 'quarters',
- },
- {
- name: 'Years',
- value: 'years',
- },
- {
- name: 'Months',
- value: 'months',
- },
- {
- name: 'Weeks',
- value: 'weeks',
- },
- {
- name: 'Days',
- value: 'days',
- },
- {
- name: 'Hours',
- value: 'hours',
- },
- {
- name: 'Minutes',
- value: 'minutes',
- },
- {
- name: 'Seconds',
- value: 'seconds',
- },
- {
- name: 'Milliseconds',
- value: 'milliseconds',
- },
- ],
- default: 'days',
- required: true,
- },
- {
- displayName: 'Property Name',
- name: 'dataPropertyName',
- type: 'string',
- default: 'data',
- required: true,
- displayOptions: {
- show: {
- action: ['calculate'],
- },
- },
- description: 'Name of the output property to which to write the converted date',
- },
- {
- displayName: 'Options',
- name: 'options',
- type: 'collection',
- placeholder: 'Add Option',
- default: {},
- displayOptions: {
- show: {
- action: ['calculate'],
- },
- },
- options: [
- {
- displayName: 'From Format',
- name: 'fromFormat',
- type: 'string',
- default: '',
- description:
- 'Format for parsing the value as a date. If unrecognized, specify the format for the value.',
+ value: 'formatDate',
+ },
+ {
+ name: 'Get Current Date',
+ value: 'getCurrentDate',
+ },
+ {
+ name: 'Get Time Between Dates',
+ value: 'getTimeBetweenDates',
+ },
+ {
+ name: 'Round a Date',
+ value: 'roundDate',
+ },
+ {
+ name: 'Subtract From a Date',
+ value: 'subtractFromDate',
},
],
+ default: 'getCurrentDate',
},
],
};
@@ -398,159 +115,5 @@ export class DateTimeV2 implements INodeType {
},
};
- async execute(this: IExecuteFunctions): Promise {
- const items = this.getInputData();
- const length = items.length;
- const returnData: INodeExecutionData[] = [];
-
- const workflowTimezone = this.getTimezone();
- let item: INodeExecutionData;
-
- for (let i = 0; i < length; i++) {
- try {
- const action = this.getNodeParameter('action', 0) as string;
- item = items[i];
-
- if (action === 'format') {
- const currentDate = this.getNodeParameter('value', i) as string;
- const dataPropertyName = this.getNodeParameter('dataPropertyName', i);
- const toFormat = this.getNodeParameter('toFormat', i) as string;
- const options = this.getNodeParameter('options', i);
- let newDate;
-
- if (currentDate === undefined) {
- continue;
- }
- if (
- options.fromFormat === undefined &&
- !moment(currentDate as string | number).isValid()
- ) {
- throw new NodeOperationError(
- this.getNode(),
- 'The date input format could not be recognized. Please set the "From Format" field',
- { itemIndex: i },
- );
- }
-
- if (Number.isInteger(currentDate as unknown as number)) {
- newDate = moment.unix(currentDate as unknown as number);
- } else {
- if (options.fromTimezone || options.toTimezone) {
- const fromTimezone = options.fromTimezone || workflowTimezone;
- if (options.fromFormat) {
- newDate = moment.tz(
- currentDate,
- options.fromFormat as string,
- fromTimezone as string,
- );
- } else {
- newDate = moment.tz(currentDate, fromTimezone as string);
- }
- } else {
- if (options.fromFormat) {
- newDate = moment(currentDate, options.fromFormat as string);
- } else {
- newDate = moment(currentDate);
- }
- }
- }
-
- if (options.toTimezone || options.fromTimezone) {
- // If either a source or a target timezone got defined the
- // timezone of the date has to be changed. If a target-timezone
- // is set use it else fall back to workflow timezone.
- newDate = newDate.tz((options.toTimezone as string) || workflowTimezone);
- }
-
- newDate = newDate.format(toFormat);
-
- let newItem: INodeExecutionData;
- if (dataPropertyName.includes('.')) {
- // Uses dot notation so copy all data
- newItem = {
- json: deepCopy(item.json),
- pairedItem: {
- item: i,
- },
- };
- } else {
- // Does not use dot notation so shallow copy is enough
- newItem = {
- json: { ...item.json },
- pairedItem: {
- item: i,
- },
- };
- }
-
- if (item.binary !== undefined) {
- newItem.binary = item.binary;
- }
-
- set(newItem, `json.${dataPropertyName}`, newDate);
-
- returnData.push(newItem);
- }
-
- if (action === 'calculate') {
- const dateValue = this.getNodeParameter('value', i) as string;
- const operation = this.getNodeParameter('operation', i) as 'add' | 'subtract';
- const duration = this.getNodeParameter('duration', i) as number;
- const timeUnit = this.getNodeParameter('timeUnit', i) as moment.DurationInputArg2;
- const { fromFormat } = this.getNodeParameter('options', i) as { fromFormat?: string };
- const dataPropertyName = this.getNodeParameter('dataPropertyName', i);
-
- const newDate = fromFormat
- ? parseDateByFormat.call(this, dateValue, fromFormat)
- : parseDateByDefault.call(this, dateValue);
-
- operation === 'add'
- ? newDate.add(duration, timeUnit).utc().format()
- : newDate.subtract(duration, timeUnit).utc().format();
-
- let newItem: INodeExecutionData;
- if (dataPropertyName.includes('.')) {
- // Uses dot notation so copy all data
- newItem = {
- json: deepCopy(item.json),
- pairedItem: {
- item: i,
- },
- };
- } else {
- // Does not use dot notation so shallow copy is enough
- newItem = {
- json: { ...item.json },
- pairedItem: {
- item: i,
- },
- };
- }
-
- if (item.binary !== undefined) {
- newItem.binary = item.binary;
- }
-
- set(newItem, `json.${dataPropertyName}`, newDate.toISOString());
-
- returnData.push(newItem);
- }
- } catch (error) {
- if (this.continueOnFail()) {
- returnData.push({
- json: {
- error: error.message,
- },
- pairedItem: {
- item: i,
- },
- });
- continue;
- }
- throw error;
- }
- }
-
- return this.prepareOutputData(returnData);
- }
+ async execute(this: IExecuteFunctions): Promise {}
}