N8n: Добавление дней к дате. Полное руководство по работе с датами в автоматизациях
N8n — это платформа для автоматизации рабочих процессов с открытым исходным кодом, которая позволяет соединять различные приложения и сервисы. Одной из наиболее частых задач в бизнес-процессах является манипуляция датами: расчет сроков, определение дат выполнения задач, смещение временных интервалов. Операция добавления определенного количества дней к заданной дате является фундаментальной для таких сценариев, как отсрочка уведомлений, расчет дат оплаты, планирование событий и многое другое. В N8n эта задача решается с помощью встроенных функций узлов, в частности, узла «Code» (JavaScript) и узла «Date & Time».
Основные методы добавления дней к дате в N8n
В N8n существует несколько основных подходов для выполнения операции добавления дней к дате. Выбор метода зависит от исходного формата данных, сложности вычислений и личных предпочтений пользователя.
1. Использование узла «Code» (JavaScript)
Узел «Code» предоставляет максимальную гибкость, позволяя использовать весь спектр возможностей JavaScript для работы с датами. Это наиболее мощный и рекомендуемый метод для сложных операций.
Базовый пример: Добавление 10 дней к текущей дате.
- Добавьте узел «Code» в ваш workflow.
- В настройках узла выберите режим «JavaScript».
- В поле «Code» введите следующий скрипт:
const inputDate = new Date(); // Текущая дата и время
const daysToAdd = 10; // Количество дней для добавления
// Создаем новую дату на основе исходной
const resultDate = new Date(inputDate);
// Добавляем дни
resultDate.setDate(resultDate.getDate() + daysToAdd);
// Возвращаем результат в формате ISO строки
return [{json: {originalDate: inputDate.toISOString(), newDate: resultDate.toISOString()}}];
Этот код создаст новый объект даты, основанный на текущем моменте, прибавит к нему 10 дней и вернет оба значения в формате ISO.
Работа с датами из предыдущих узлов: Чаще всего исходная дата приходит из другого узла (например, из Google Sheets, базы данных или формы).
// Предположим, что из предыдущего узла пришел элемент с полем `startDate`
const inputDateString = $input.first().json.startDate; // Например, "2023-12-01"
const daysToAdd = parseInt($input.first().json.delayDays) || 5; // Берем количество дней из данных или используем по умолчанию 5
// Преобразуем строку в объект Date
const inputDateObj = new Date(inputDateString);
// Проверка на валидность даты
if (isNaN(inputDateObj.getTime())) {
throw new Error('Некорректный формат даты');
}
const resultDate = new Date(inputDateObj);
resultDate.setDate(resultDate.getDate() + daysToAdd);
// Форматируем результат в нужном формате (например, YYYY-MM-DD)
const formattedResult = resultDate.toISOString().split('T')[0];
return [{json: {
originalDate: inputDateString,
addedDays: daysToAdd,
calculatedDate: formattedResult
}}];
2. Использование узла «Date & Time»
Узел «Date & Time» предлагает визуальный, менее гибкий, но часто более простой способ работы с датами. Он позволяет преобразовывать и форматировать даты, но для непосредственного добавления дней часто требуется комбинация с другими узлами.
Метод расчета: Чтобы добавить дни с помощью этого узла, необходимо использовать функцию «Calculate a date».
- Добавьте узел «Date & Time».
- В поле «Value» укажите исходную дату (например,
{{ $json.dateFromPreviousNode }}). - В поле «Operation» выберите «Add».
- В поле «Duration» укажите количество дней (например,
7). - В поле «Time Unit» выберите «Days».
Узел вернет новую дату в формате timestamp. Для получения строки в нужном формате можно добавить второй узел «Date & Time» и выбрать операцию «Format a date».
3. Использование функций в полях выражений (Expression)
Во многих узлах N8n (например, «Set», «IF») есть поля, поддерживающие выражения. Там можно использовать функцию $now и методы JavaScript напрямую.
Пример в узле «Set»:
- Добавьте узел «Set».
- В режиме «Add Value → String» создайте новое поле, например,
futureDate. - В значении используйте выражение:
{{ new Date($now).setDate(new Date($now).getDate() + 14) }}
Однако это вернет timestamp. Для форматирования можно обернуть выражение в функцию форматирования или использовать следующий подход:
{{ new Date(new Date($now).setDate(new Date($now).getDate() + 14)).toISOString().split('T')[0] }}
Детальное описание работы с объектом Date в JavaScript (в контексте N8n)
Понимание объекта Date критически важно для надежной работы с датами в узле «Code».
| Метод/Свойство | Описание | Пример использования в N8n |
|---|---|---|
new Date() |
Создает объект Date с текущей датой и временем. | const now = new Date(); |
new Date(dateString) |
Создает объект Date из строки (ISO 8601, RFC 2822 и др.). | const specificDate = new Date("2023-12-25"); |
getDate() |
Возвращает день месяца (1-31). | const day = inputDate.getDate(); |
setDate(day) |
Устанавливает день месяца. Ключевой метод для добавления дней. Автоматически корректирует месяц и год. | resultDate.setDate(resultDate.getDate() + 10); |
getTime() |
Возвращает количество миллисекунд с 1 января 1970 года (Unix Timestamp). | Используется для проверки валидности: if (isNaN(dateObj.getTime())) |
toISOString() |
Возвращает строку в формате ISO 8601 (YYYY-MM-DDTHH:mm:ss.sssZ). | Для хранения и передачи: const iso = resultDate.toISOString(); |
Практические примеры и сценарии использования
Сценарий 1: Автоматизация напоминаний о платежах (срок +7 дней)
Workflow: Google Sheets (список счетов) → Code (добавить 7 дней к дате счета) → Email (отправить напоминание).
// В узле Code
const invoiceDate = new Date($input.first().json.invoiceDate);
const dueDate = new Date(invoiceDate);
dueDate.setDate(dueDate.getDate() + 7);
// Форматируем для письма
const formattedDueDate = dueDate.toLocaleDateString('ru-RU'); // DD.MM.YYYY
return [{
json: {
...$input.first().json,
dueDate: formattedDueDate,
dueDateISO: dueDate.toISOString()
}
}];
Сценарий 2: Планирование цепочки задач (последовательное добавление дней)
Необходимо рассчитать даты для нескольких этапов проекта: начало +2 дня, +5 дней, +10 дней.
const startDate = new Date($input.first().json.projectStart);
const milestones = [];
const offsets = [2, 5, 10];
offsets.forEach(offset => {
const milestoneDate = new Date(startDate);
milestoneDate.setDate(milestoneDate.getDate() + offset);
milestones.push({
milestone: `Этап +${offset} дней`,
date: milestoneDate.toISOString().split('T')[0]
});
});
return [{ json: { startDate: startDate.toISOString().split('T')[0], milestones } }];
Сценарий 3: Обработка рабочих дней (исключение выходных)
Добавление рабочих дней — более сложная операция. Требуется алгоритм, пропускающий субботу и воскресенье.
function addBusinessDays(startDate, daysToAdd) {
const result = new Date(startDate);
let addedDays = 0;
while (addedDays < daysToAdd) {
result.setDate(result.getDate() + 1);
// Проверяем, не является ли день субботой (6) или воскресеньем (0)
if (result.getDay() !== 0 && result.getDay() !== 6) {
addedDays++;
}
}
return result;
}
const start = new Date($input.first().json.start);
const businessDaysToAdd = 5;
const newDate = addBusinessDays(start, businessDaysToAdd);
return [{ json: { start, businessDaysToAdd, newDate: newDate.toISOString() } }];
Обработка ошибок и валидация данных
При работе с пользовательскими или внешними данными всегда необходима проверка.
- Проверка формата: Используйте
isNaN(dateObj.getTime())для проверки, что объект Date валиден. - Проверка типа: Убедитесь, что количество дней для добавления является числом.
- Обработка null/undefined: Задавайте значения по умолчанию.
const rawDate = $input.first().json.someDateField;
const rawDays = $input.first().json.daysToAdd;
// Значения по умолчанию
const defaultDate = new Date();
const defaultDays = 1;
const inputDate = rawDate ? new Date(rawDate) : defaultDate;
const daysToAdd = parseInt(rawDays) || defaultDays;
if (isNaN(inputDate.getTime())) {
// Можно отправить данные в узел "Error Trigger" или записать в лог
throw new Error(`Неверный формат даты: ${rawDate}`);
}
// ... дальнейшие вычисления
Форматирование результата
После вычисления даты ее часто нужно привести к нужному строковому формату для дальнейшего использования (в письмах, базах данных, календарях).
| Целевой формат | Метод JavaScript | Пример результата |
|---|---|---|
| ISO 8601 (дата и время) | date.toISOString() |
«2023-12-25T14:30:00.000Z» |
| Только дата (YYYY-MM-DD) | date.toISOString().split('T')[0] |
«2023-12-25» |
| Локализованный формат (русский) | date.toLocaleDateString('ru-RU') |
«25.12.2023» |
| Локализованный формат (США) | date.toLocaleDateString('en-US') |
«12/25/2023» |
| Timestamp (миллисекунды) | date.getTime() |
1703511000000 |
Интеграция с другими узлами N8n
Результат вычисления даты обычно передается дальше по workflow. Важно обеспечить совместимость формата.
- Базы данных (PostgreSQL, MySQL): Используйте ISO строку или объект Date.
- Календари (Google Calendar, Cal.com): Требуют строго определенного формата (обычно ISO).
- Таблицы (Google Sheets, Airtable): Подходит как ISO, так и локализованные строки, в зависимости от региональных настроек таблицы.
- Шаблоны сообщений (Email, Telegram): Используйте удобочитаемый строковый формат, например, полученный через
toLocaleDateString().
Ответы на часто задаваемые вопросы (FAQ)
Как добавить не дни, а рабочие дни (без выходных)?
Необходимо реализовать алгоритм, который прибавляет дни по одному, пропуская субботу и воскресенье. Пример функции addBusinessDays приведен выше в разделе «Сценарий 3». Для учета праздников потребуется интеграция со справочником праздничных дат через API или отдельную таблицу.
Почему при добавлении дней меняется месяц и год?
Метод setDate() объекта Date в JavaScript автоматически корректирует более высокие части даты (месяц, год) при выходе за границы текущего месяца. Это не ошибка, а ожидаемое поведение. Например, 31 января + 1 день = 1 февраля.
Как обрабатывать временные зоны в N8n?
N8n по умолчанию работает в часовом поясе UTC. При создании даты из строки без указания времени (new Date("2023-12-01")) она интерпретируется как UTC. Чтобы учесть локальный пояс, можно использовать toLocaleString с параметром timeZone или явно добавлять смещение к строке. Для сложных операций рекомендуется хранить все даты в UTC, а конвертировать только на этапе отображения.
Можно ли вычитать дни из даты?
Да, для вычитания дней используется тот же метод setDate(), но с передачей отрицательного значения: resultDate.setDate(resultDate.getDate() - 5);.
Как добавить часы или месяцы к дате?
Для добавления часов используйте метод setHours(): date.setHours(date.getHours() + 3);. Для добавления месяцев — метод setMonth(): date.setMonth(date.getMonth() + 2);. Учтите, что прибавление месяцев также автоматически корректирует год при необходимости.
Что надежнее: узел «Code» или «Date & Time»?
Узел «Code» надежнее и гибче, так как дает полный контроль над логикой, обработкой ошибок и форматами. Узел «Date & Time» проще для базовых операций форматирования и конвертации, но для арифметических действий с датами (особенно сложных) он может быть менее удобен.
Как избежать ошибок при парсинге дат из разных источников?
Рекомендуется:
- По возможности договориться об использовании единого формата на входе (предпочтительно ISO 8601: YYYY-MM-DD).
- Использовать библиотеку moment.js или date-fns в узле «Code» для сложных парсингов (их можно установить через npm в настройках проекта N8n).
- Всегда оборачивать парсинг в try-catch и добавлять валидацию результата.
Как протестировать workflow с датами?
Создайте узел «Manual Trigger» или «Schedule Trigger» и с помощью узла «Set» сформируйте тестовые данные с разными датами (корректными, некорректными, пограничными значениями — например, конец месяца, високосный год). Запустите workflow и проверьте результаты в каждом узле, используя панель выполнения.
Добавить комментарий