KEEP LEARNING
Build the bigger picture.
The Workflow Engineer connects individual n8n concepts to testing, deployment and running a complete workflow.
Tips > Building Workflows
n8n's built-in expression language supports Luxon for dates, but complex operations like business day calculations, timezone-aware scheduling windows
For date math beyond what Luxon expressions handle -- business-day counts, timezone-aware scheduling windows, or fiscal-quarter logic -- use a Code node instead. It can hold reusable helper functions and loops that would take an unreasonable number of IF and DateTime nodes to replicate on the canvas. The example below finds the next business day at least 30 days out, skipping weekends and US federal holidays.
n8n's built-in expression language supports Luxon for dates, but complex operations like business day calculations, timezone-aware scheduling windows, or fiscal quarter logic are easier and more maintainable in a Code node.
Real-world example: A contract renewal workflow needs to calculate the next business day that is at least 30 days out, skipping US federal holidays and weekends.
// Mode: Run Once for Each Item
// US federal holidays for the current year (update annually or fetch dynamically)
const holidays2025 = new Set([
'2025-01-01', '2025-01-20', '2025-02-17', '2025-05-26',
'2025-06-19', '2025-07-04', '2025-09-01', '2025-10-13',
'2025-11-11', '2025-11-27', '2025-12-25',
]);
function isBusinessDay(date) {
const day = date.getDay();
if (day === 0 || day === 6) return false; // Weekend
const iso = date.toISOString().slice(0, 10);
return !holidays2025.has(iso);
}
function addBusinessDays(start, days) {
const result = new Date(start);
let added = 0;
while (added < days) {
result.setDate(result.getDate() + 1);
if (isBusinessDay(result)) added++;
}
return result;
}
const contractEnd = new Date($input.item.json.contractEndDate);
const minDate = new Date(contractEnd);
minDate.setDate(minDate.getDate() + 30);
// Find next business day on or after the 30-day mark
let renewalDate = new Date(minDate);
while (!isBusinessDay(renewalDate)) {
renewalDate.setDate(renewalDate.getDate() + 1);
}
// Also calculate 5-business-day reminder window
const reminderDate = addBusinessDays(renewalDate, -5);
return [{
json: {
...$input.item.json,
renewalDate: renewalDate.toISOString().slice(0, 10),
reminderDate: reminderDate.toISOString().slice(0, 10),
daysUntilRenewal: Math.ceil(
(renewalDate - new Date()) / (1000 * 60 * 60 * 24)
),
}
}];This logic would require an unreasonable number of IF and DateTime nodes to replicate on the canvas.
Related: Use Edit Fields in "Map Each" Mode for Simple Renames · Configure Payload Size and Binary Data Mode for Large Files
KEEP LEARNING
The Workflow Engineer connects individual n8n concepts to testing, deployment and running a complete workflow.
APPLY IT TO YOUR SYSTEM
Bring the process, the tools involved and an example of where the current workflow gets stuck.