Date and time manipulation causes more n8n workflow errors than almost any other operation. You set up a scheduled workflow that should run at 9 AM, but it fires at 2 PM. You format a date for an API, but the request fails with “invalid date format.” You calculate the difference between two dates and get a number that makes no sense.
These problems share a common root: dates are deceptively complex. They involve timezones, daylight saving time transitions, locale-specific formats, and the gap between how humans read dates versus how computers process them.
The Date & Time node exists to handle this complexity without requiring JavaScript expertise.
The Date Problem in Automation
Every external system you connect to has its own date format expectations. Salesforce wants ISO 8601 strings. Google Sheets prefers locale-specific formats. Stripe uses Unix timestamps. Your database stores dates in one timezone while your API expects another.
Without proper date handling, you end up with:
- Scheduled workflows firing at wrong times
- API requests rejected due to format mismatches
- Reports showing yesterday’s data as today’s
- Off-by-one errors around midnight and DST transitions
What the Date & Time Node Solves
The Date & Time node provides seven operations that handle the most common date manipulation tasks:
- Convert between date formats
- Add or subtract time intervals
- Extract specific parts (year, month, day, hour)
- Round dates to specific boundaries
- Calculate time differences between dates
- Get the current date and time
- Handle timezone conversions
Each operation works through a visual interface. You select inputs, configure options, and the node handles the underlying Luxon library calls that would otherwise require code.
What You’ll Learn
- When to use the Date & Time node versus expressions or the Code node
- How each of the seven operations works with practical examples
- The timezone hierarchy that controls date behavior across your workflow
- Complete Luxon format token reference for custom date formatting
- Five real-world examples you can adapt to your workflows
- How to troubleshoot the most common date-related errors
- Best practices for reliable date handling in production workflows
When to Use the Date & Time Node
Before diving into operations, understand when this node is the right choice versus alternatives.
| Scenario | Best Choice | Why |
|---|---|---|
| Format a date for an API request | Date & Time node | Visual configuration, no code needed |
| Add 7 days to a date field | Date & Time node | Built-in operation handles edge cases |
| Calculate days between two dates | Date & Time node | Direct operation with unit selection |
| Quick inline formatting in an expression | Expressions | Faster for simple cases like $now.toISO() |
| Complex date logic with conditionals | Code node | Full JavaScript control |
| Parse dates from multiple inconsistent formats | Code node | Requires fallback logic the node can’t handle |
| Round to nearest business day | Code node | Business logic beyond node capabilities |
| Get current timestamp | Either | Node or $now expression both work |
Rule of thumb: Use the Date & Time node when you have a single date transformation that maps to one of its seven operations. Use expressions for inline formatting within other nodes. Use the Code node for complex logic involving multiple conditions or custom calculations.
Understanding the Seven Operations
The Date & Time node offers seven distinct operations. Each solves a specific date manipulation problem.
Add to a Date
Purpose: Calculate a future date by adding a time interval.
Parameters:
- Date: The starting date (from a previous node or manual input)
- Duration: The amount to add
- Time Unit: Seconds, minutes, hours, days, weeks, months, or years
Example: Calculate a subscription renewal date 30 days from signup.
Input: 2024-03-15T10:00:00.000Z
Duration: 30
Unit: Days
Output: 2024-04-14T10:00:00.000Z
Common use cases:
- Setting due dates from creation dates
- Calculating expiration dates
- Scheduling follow-up reminders
Subtract From a Date
Purpose: Calculate a past date by subtracting a time interval.
Parameters: Same as Add to a Date.
Example: Find the date 90 days before a deadline for early warning alerts.
Input: 2024-12-31T00:00:00.000Z
Duration: 90
Unit: Days
Output: 2024-10-02T00:00:00.000Z
Common use cases:
- Calculating lookback periods for reports
- Setting reminder dates before deadlines
- Filtering data from a specific period
Format a Date
Purpose: Convert a date to a specific string format.
Parameters:
- Date: The date to format
- Format: The target format using Luxon tokens
- Timezone: Optional timezone for the output
Example: Format a timestamp for a human-readable email.
Input: 2024-03-15T14:30:00.000Z
Format: MMMM d, yyyy 'at' h:mm a
Output: March 15, 2024 at 2:30 PM
This operation is essential when sending dates to APIs or displaying them to users. Different systems expect different formats, and this operation handles the conversion without requiring you to learn Luxon syntax in detail.
Extract Part of a Date
Purpose: Pull out a specific component from a date.
Parameters:
- Date: The source date
- Part: Which component to extract (year, month, day, hour, minute, second, weekday, etc.)
Example: Extract the month number for grouping transactions by month.
Input: 2024-03-15T14:30:00.000Z
Part: Month
Output: 3
Common use cases:
- Grouping data by time periods
- Conditional logic based on day of week
- Building custom date displays
Round a Date
Purpose: Adjust a date to a boundary (start or end of a period).
Parameters:
- Date: The date to round
- Mode: Round down (start), round up (end), or round to nearest
- To Nearest: The unit to round to (hour, day, week, month, year)
Example: Get the start of the month for a report date range.
Input: 2024-03-15T14:30:00.000Z
Mode: Round Down
To Nearest: Month
Output: 2024-03-01T00:00:00.000Z
Common use cases:
- Generating report date ranges
- Aligning schedules to boundaries
- Calculating billing periods
Get Current Date
Purpose: Retrieve the current date and time.
Parameters:
- Include Time: Whether to include the time portion
- Timezone: Which timezone to use for “now”
Example: Stamp a record with the current processing time.
Include Time: Yes
Timezone: America/New_York
Output: 2024-03-15T10:30:00.000-04:00
While you can use $now in expressions, this operation provides explicit timezone control that expressions don’t offer directly.
Get Time Between Dates
Purpose: Calculate the duration between two dates.
Parameters:
- Start Date: The earlier date
- End Date: The later date
- Units: What units to return (days, hours, minutes, etc.)
Example: Calculate how many days until a contract expires.
Start Date: 2024-03-15T00:00:00.000Z
End Date: 2024-12-31T00:00:00.000Z
Units: Days
Output: 291
Common use cases:
- Calculating age from birthdate
- Measuring SLA response times
- Determining subscription duration
Timezone Handling Deep Dive
Timezone problems cause more unexpected behavior than any other date-related issue. Understanding how n8n handles timezones prevents hours of debugging.
The Timezone Hierarchy
n8n uses a three-level hierarchy for timezone settings:
-
Instance Level: Set via the
GENERIC_TIMEZONEenvironment variable. Default isAmerica/New_Yorkfor self-hosted instances. -
Workflow Level: Set in workflow settings. Overrides the instance timezone for that specific workflow.
-
Node Level: The Date & Time node has its own timezone option. Overrides workflow settings for that specific operation.
When you don’t explicitly set a timezone in the node, it inherits from the workflow, which inherits from the instance.
Common Timezone Problems and Fixes
Problem: Schedule Trigger runs at wrong time
The Schedule Trigger uses the workflow timezone. If you set it to run at “9 AM” but your workflow timezone is UTC while you’re in EST, it runs at 9 AM UTC (4 AM or 5 AM EST depending on DST).
Fix: Set the workflow timezone to match your local timezone, or account for the offset in your schedule.
Problem: Date & Time node outputs UTC regardless of settings
Some input date formats don’t carry timezone information. When you pass a date like 2024-03-15 without a time component, n8n interprets it as midnight UTC. The timezone setting only affects how the output is formatted, not how the input is interpreted.
Fix: Ensure input dates include timezone information when possible. Use ISO 8601 format with offset: 2024-03-15T09:00:00-05:00.
Problem: Inconsistent behavior between test and production
The n8n interface may run in your browser’s timezone, while production runs in the server’s timezone. Dates that look correct in testing break in production.
Fix: Always explicitly set timezones at the workflow or node level rather than relying on defaults. Log timezone information during debugging.
Daylight Saving Time Considerations
DST transitions create edge cases that can break workflows:
- A 2 AM schedule might skip or double-run on DST transition days
- Duration calculations spanning DST changes may be off by an hour
- “Same time tomorrow” might mean a different wall-clock time
The Date & Time node handles DST correctly when you work in terms of days, weeks, months, or years. Adding “1 day” to a timestamp gives you the same wall-clock time the next day, even across DST boundaries.
However, adding “24 hours” is a fixed duration that doesn’t account for DST. On a day with a DST transition, “24 hours later” and “1 day later” produce different results.
Best practice: Use calendar units (days, weeks, months) when you mean calendar intervals. Use time units (hours, minutes, seconds) when you mean exact durations.
Environment Variable Configuration
For self-hosted n8n, set the instance timezone in your environment:
export GENERIC_TIMEZONE=Europe/London
Or in Docker Compose:
environment:
- GENERIC_TIMEZONE=Europe/London
Use IANA timezone names like America/New_York, Europe/London, or Asia/Tokyo. Abbreviations like EST or GMT are ambiguous and may not work correctly.
Luxon Format Tokens Reference
The Date & Time node uses Luxon for date formatting. When using the Format operation, you specify the output format using tokens.
Tokens are case-sensitive. MM means month, mm means minute. This is a common source of errors.
Essential Format Tokens
| Token | Meaning | Example Output |
|---|---|---|
yyyy | Four-digit year | 2024 |
yy | Two-digit year | 24 |
MMMM | Full month name | March |
MMM | Abbreviated month name | Mar |
MM | Two-digit month | 03 |
M | Month number | 3 |
dd | Two-digit day | 15 |
d | Day number | 15 |
EEEE | Full weekday name | Friday |
EEE | Abbreviated weekday name | Fri |
HH | Two-digit hour (24-hour) | 14 |
hh | Two-digit hour (12-hour) | 02 |
h | Hour (12-hour) | 2 |
mm | Two-digit minute | 30 |
ss | Two-digit second | 45 |
a | AM/PM marker | PM |
Z | Timezone offset | -05:00 |
ZZZZ | Timezone abbreviation | EST |
Common Format Patterns
| Purpose | Format | Example Output |
|---|---|---|
| ISO 8601 (APIs) | yyyy-MM-dd'T'HH:mm:ssZ | 2024-03-15T14:30:00-05:00 |
| US date | MM/dd/yyyy | 03/15/2024 |
| European date | dd/MM/yyyy | 15/03/2024 |
| Human readable | MMMM d, yyyy | March 15, 2024 |
| With time | MMMM d, yyyy 'at' h:mm a | March 15, 2024 at 2:30 PM |
| Filename safe | yyyy-MM-dd_HH-mm-ss | 2024-03-15_14-30-45 |
| Week of year | 'Week' W 'of' yyyy | Week 11 of 2024 |
| Day of year | o 'of' yyyy | 75 of 2024 |
Literal Text in Formats
To include literal text in your format string, wrap it in single quotes:
Format: 'Created on' MMMM d, yyyy
Output: Created on March 15, 2024
Parsing Non-Standard Input Formats
The Date & Time node expects dates in recognizable formats like ISO 8601. When your source data uses a different format, the node fails with “Invalid DateTime” errors. This section covers how to handle non-standard formats.
When the Node Can’t Parse Your Date
Common formats that cause problems:
| Input Format | Example | Why It Fails |
|---|---|---|
dd-MMM-yyyy | 15-Mar-2024 | Month abbreviation not auto-detected |
MM.dd.yyyy | 03.15.2024 | Dot separators ambiguous |
yyyyMMdd | 20240315 | No separators, could be many formats |
d/M/yy | 15/3/24 | Ambiguous day/month order, two-digit year |
MMMM dd, yyyy | March 15, 2024 | Full month name needs explicit parsing |
Specifying Input Format
In the Date & Time node, you can specify the input format using the From Format option:
- Open the Date & Time node
- Click Add Option
- Select From Format
- Enter the Luxon format string matching your input
Example: Your data contains dates like 15-Mar-2024
From Format: dd-MMM-yyyy
Input: 15-Mar-2024
Output: 2024-03-15T00:00:00.000Z (or your chosen output format)
Format String Examples for Common Patterns
| Input Example | From Format String |
|---|---|
| 15-Mar-2024 | dd-MMM-yyyy |
| March 15, 2024 | MMMM d, yyyy |
| 03.15.2024 | MM.dd.yyyy |
| 20240315 | yyyyMMdd |
| 15/3/24 | d/M/yy |
| 2024-03-15 14:30 | yyyy-MM-dd HH:mm |
| 03/15/2024 2:30 PM | MM/dd/yyyy h:mm a |
Fallback to Code Node for Complex Parsing
When dates come from multiple sources with inconsistent formats, the Date & Time node can’t handle fallback logic. Use the Code node instead:
const { DateTime } = require('luxon');
// Try multiple formats in order
const formats = ['yyyy-MM-dd', 'MM/dd/yyyy', 'dd-MMM-yyyy', 'MMMM d, yyyy'];
let parsed = null;
for (const format of formats) {
const attempt = DateTime.fromFormat($json.dateString, format);
if (attempt.isValid) {
parsed = attempt;
break;
}
}
// Fallback to ISO parsing if custom formats fail
if (!parsed || !parsed.isValid) {
parsed = DateTime.fromISO($json.dateString);
}
return [{
json: {
parsedDate: parsed.isValid ? parsed.toISO() : null,
parseSuccess: parsed.isValid
}
}];
This pattern tries each format until one succeeds, providing robust parsing for inconsistent data sources.
Working with Unix Timestamps
Many APIs use Unix timestamps instead of human-readable dates. Unix timestamps represent seconds (or milliseconds) since January 1, 1970 UTC.
Unix Timestamp Formats
| Type | Example | Common Sources |
|---|---|---|
| Seconds | 1710510600 | Stripe, many REST APIs |
| Milliseconds | 1710510600000 | JavaScript, Firebase, some APIs |
Converting Unix Timestamps to Dates
In the Date & Time node:
The node doesn’t directly accept Unix timestamps. Convert them using expressions first, then pass to the node:
// Seconds to ISO string
{{ DateTime.fromSeconds($json.unixTimestamp).toISO() }}
// Milliseconds to ISO string
{{ DateTime.fromMillis($json.unixTimestampMs).toISO() }}
In the Edit Fields node:
Create a new field with the converted date, then use Date & Time for further manipulation:
// Field: readableDate
// Value (expression mode):
{{ DateTime.fromSeconds($json.created).toISO() }}
Converting Dates to Unix Timestamps
For API requests expecting Unix seconds:
// Current time as Unix seconds
{{ Math.floor($now.toMillis() / 1000) }}
// Specific date as Unix seconds
{{ Math.floor(DateTime.fromISO($json.date).toMillis() / 1000) }}
For APIs expecting Unix milliseconds:
// Current time as Unix milliseconds
{{ $now.toMillis() }}
// Specific date as Unix milliseconds
{{ DateTime.fromISO($json.date).toMillis() }}
Complete Unix Timestamp Conversion Examples
Stripe API integration (uses seconds):
// Convert Stripe timestamp to readable date
{{ DateTime.fromSeconds($json.created).toFormat('MMMM d, yyyy') }}
// Input: 1710510600
// Output: March 15, 2024
// Send date to Stripe as timestamp
{{ Math.floor(DateTime.fromISO($json.scheduledDate).toMillis() / 1000) }}
// Input: 2024-03-15T10:00:00.000Z
// Output: 1710500400
JavaScript/Firebase integration (uses milliseconds):
// Convert milliseconds timestamp to ISO
{{ DateTime.fromMillis($json.timestamp).toISO() }}
// Input: 1710510600000
// Output: 2024-03-15T18:30:00.000Z
// Convert date to milliseconds for Firebase
{{ DateTime.fromISO($json.eventDate).toMillis() }}
// Input: 2024-03-15T18:30:00.000Z
// Output: 1710510600000
Common API Date Format Reference
Different APIs expect specific date formats. This reference table shows the exact format strings for popular integrations.
API Format Cheatsheet
| Service | Expected Format | Luxon Format String | Example Output |
|---|---|---|---|
| Stripe | Unix timestamp (seconds) | N/A (use toMillis()/1000) | 1710510600 |
| Salesforce | ISO 8601 with timezone | yyyy-MM-dd'T'HH:mm:ss.SSSZ | 2024-03-15T14:30:00.000Z |
| HubSpot | Unix timestamp (milliseconds) | N/A (use toMillis()) | 1710510600000 |
| Google Sheets | Locale-dependent or ISO | yyyy-MM-dd or M/d/yyyy | 2024-03-15 or 3/15/2024 |
| Airtable | ISO 8601 | yyyy-MM-dd'T'HH:mm:ss.SSS'Z' | 2024-03-15T14:30:00.000Z |
| Notion | ISO 8601 date only or with time | yyyy-MM-dd or full ISO | 2024-03-15 |
| Slack | Unix timestamp (seconds) | N/A (use toMillis()/1000) | 1710510600 |
| Mailchimp | ISO 8601 | yyyy-MM-dd'T'HH:mm:ssZ | 2024-03-15T14:30:00+00:00 |
| Zendesk | ISO 8601 | yyyy-MM-dd'T'HH:mm:ssZ | 2024-03-15T14:30:00+00:00 |
| Shopify | ISO 8601 | yyyy-MM-dd'T'HH:mm:ssZ | 2024-03-15T14:30:00-04:00 |
| QuickBooks | Date only | yyyy-MM-dd | 2024-03-15 |
| Xero | ISO 8601 or .NET format | yyyy-MM-dd'T'HH:mm:ss | 2024-03-15T14:30:00 |
Platform-Specific Examples
Sending dates to Stripe:
// In HTTP Request node body
{
"trial_end": {{ Math.floor(DateTime.fromISO($json.trialEndDate).toMillis() / 1000) }}
}
Sending dates to Salesforce:
// In HTTP Request node body
{
"CloseDate": "{{ DateTime.fromISO($json.closeDate).toISO() }}"
}
Sending dates to Google Sheets:
// For date-only columns
{
"values": [["{{ DateTime.fromISO($json.date).toFormat('yyyy-MM-dd') }}"]]
}
Sending dates to HubSpot:
// HubSpot uses milliseconds for date properties
{
"properties": {
"closedate": {{ DateTime.fromISO($json.closeDate).toMillis() }}
}
}
Receiving Dates from APIs
When parsing dates from API responses, most return ISO 8601 which n8n handles automatically. For Unix timestamps, convert them first:
// From Stripe webhook
{{ DateTime.fromSeconds($json.data.object.created).toISO() }}
// From HubSpot
{{ DateTime.fromMillis($json.properties.closedate).toISO() }}
For APIs returning non-standard formats, use the parsing techniques from the previous section.
Practical Examples
Example 1: Calculate Days Until Deadline
Scenario: A project management workflow needs to calculate how many days remain until each task’s due date.
Configuration:
- Add a Date & Time node after your data source
- Select operation: Get Time Between Dates
- Set Start Date to expression:
{{ $now.toISO() }} - Set End Date to the due date field:
{{ $json.dueDate }} - Set Units to: Days
Usage in next node:
{{ $json.daysUntilDue }}
// Returns: 14 (if due date is 14 days away)
Use this with the If node to route tasks based on urgency.
Example 2: Format Dates for API Requests
Scenario: You’re sending data to an external API that requires dates in MM-dd-yyyy format, but your source data uses ISO 8601.
Configuration:
- Add Date & Time node before your HTTP Request node
- Select operation: Format a Date
- Set Date to:
{{ $json.createdAt }} - Set Format to:
MM-dd-yyyy
Output:
Input: 2024-03-15T14:30:00.000Z
Output: 03-15-2024
The formatted date is now compatible with the target API’s requirements.
Example 3: Extract Month for Reporting
Scenario: Build a monthly report by grouping transactions by their month.
Configuration:
- Add Date & Time node after fetching transaction data
- Select operation: Extract Part of a Date
- Set Date to:
{{ $json.transactionDate }} - Set Part to: Month
Usage in aggregation:
Use the Aggregate node to group by the extracted month, then calculate totals per month.
Example 4: Round to Business Hours Start
Scenario: When a support ticket arrives, you need to calculate the start of the current business day for SLA calculations.
Configuration:
- Add Date & Time node after your webhook trigger
- Select operation: Round a Date
- Set Date to:
{{ $json.createdAt }} - Set Mode to: Round Down
- Set To Nearest: Day
This gives you midnight of the ticket creation date. For actual business hours, you would combine this with the Add operation to add your business start time (e.g., 9 hours).
Example 5: Handle Multi-Timezone Scheduling
Scenario: A global notification system needs to send messages at 9 AM in each recipient’s local timezone.
Configuration:
For each recipient:
- Use Date & Time node with operation: Get Current Date
- Set Timezone to the recipient’s timezone (from their profile data)
- Use Format operation to check if current hour in their timezone matches the target hour
This requires looping through recipients with the Split In Batches node and checking each timezone individually.
For complex scheduling like this, consider whether the Code node provides cleaner logic.
Troubleshooting Common Errors
”Invalid DateTime” Error
Symptoms: The node returns [invalid DateTime] instead of a formatted date.
Causes and fixes:
-
Malformed input date
- Check that the input field actually contains a date, not null or an empty string
- Use optional chaining in your expression:
{{ $json.date?.toISO?.() ?? 'No date' }}
-
Timezone configuration with extra quotes
- Check environment variables for accidental quotes:
"Europe/Berlin"instead ofEurope/Berlin - Review your Docker or environment configuration
- Check environment variables for accidental quotes:
-
Invalid timezone name
- Use full IANA names:
America/New_YorknotEST - Check spelling and capitalization
- Use full IANA names:
-
Wrong format tokens
- Remember tokens are case-sensitive
MMis month,mmis minute
Timezone Setting Has No Effect
Symptoms: Output remains in UTC regardless of timezone settings.
Causes and fixes:
-
Input date lacks timezone info
- When input is a simple date string like
2024-03-15, n8n interprets it as UTC - Add timezone to input when possible
- When input is a simple date string like
-
Setting timezone after format operation
- Timezone conversion must happen before or during formatting
- Reorder your operations
-
Inheritance confusion
- Check workflow settings for a conflicting timezone
- Explicitly set timezone in the node to override
Format Output Doesn’t Match Expected Pattern
Symptoms: Formatted date shows wrong values or strange characters.
Causes and fixes:
-
Token case sensitivity
MM= month (01-12)mm= minute (00-59)- Double-check your token cases
-
Locale differences
- Month names depend on locale settings
- For consistent output, use numeric formats
-
Literal text not quoted
- Text like “at” or “on” must be in single quotes:
'at' - Otherwise Luxon tries to interpret them as tokens
- Text like “at” or “on” must be in single quotes:
Unexpected UTC Conversion
Symptoms: Dates shift by several hours unexpectedly.
Causes and fixes:
-
Display vs storage confusion
- n8n may display in your browser’s timezone but store in UTC
- Check the raw data, not just the visual display
-
Multiple conversions
- Each Date & Time node applies its timezone setting
- Avoid chaining multiple nodes that each apply timezone changes
-
API returns different timezone than expected
- Check the source API’s documentation for timezone behavior
- Parse explicitly if needed
DST Edge Cases
Symptoms: Calculations are off by one hour around March/November (in US) or other DST transition dates.
Causes and fixes:
-
Using hours instead of days
- “Add 24 hours” differs from “add 1 day” during DST
- Use calendar units when appropriate
-
Hardcoded offsets
- Don’t use
-05:00when you meanAmerica/New_York - Named timezones handle DST automatically
- Don’t use
-
Testing only in summer or winter
- Test workflows with dates that span DST transitions
- Use pinned data with specific edge-case dates
Date & Time Node vs Expressions
Both the Date & Time node and inline expressions can manipulate dates. Choose based on your needs.
Comparison Table
| Factor | Date & Time Node | Expressions |
|---|---|---|
| Learning curve | Lower (visual interface) | Higher (requires Luxon syntax) |
| Timezone control | Explicit per-operation | Inherits from context |
| Debugging | Easier (isolated operation) | Harder (inline in other nodes) |
| Workflow readability | Visible as a separate step | Hidden inside field values |
| Performance | Slight overhead (extra node) | Marginally faster |
| Best for | Complex operations, timezone handling | Simple formatting, quick transformations |
When to Use Each
Use the Date & Time node when:
- You need explicit timezone handling
- The date operation is a significant workflow step
- Team members need to understand and modify the logic
- You’re debugging date-related issues
Use expressions when:
- You need quick inline formatting like
{{ $now.toISO() }} - The transformation is trivial (adding days, basic formatting)
- You want to minimize node count
- The date logic is simple enough to understand at a glance
Hybrid approach:
For complex workflows, use the Date & Time node for critical transformations and expressions for simple inline formatting. This balances readability with efficiency.
Test expressions with our expression validator tool before running the full workflow.
Pro Tips and Best Practices
1. Always Specify Timezones Explicitly
Don’t rely on defaults. Set timezone at the workflow level for consistency, and override at the node level when specific operations need different zones.
2. Use ISO 8601 for Data Storage
When storing dates in databases or passing between systems, use ISO 8601 format (2024-03-15T14:30:00Z). It’s unambiguous and widely supported.
Format dates for human display only at the final output stage.
3. Test with Pinned Data
Before connecting live data sources, pin sample dates to your workflow. Include edge cases:
- Dates around DST transitions
- End-of-month dates (28th, 29th, 30th, 31st)
- Year boundaries
- Dates far in the past or future
4. Log Timezone Information When Debugging
When date problems occur, add a temporary Edit Fields node that outputs:
{
"inputDate": "{{ $json.date }}",
"inputTimezone": "{{ $json.date.zoneName ?? 'unknown' }}",
"workflowTimezone": "{{ Intl.DateTimeFormat().resolvedOptions().timeZone }}"
}
This reveals where timezone mismatches occur.
5. Handle Null Dates Gracefully
Not all records have dates populated. Use the If node to route records with missing dates, or use expressions with fallbacks:
{{ $json.dueDate ?? $now.plus({ days: 7 }).toISO() }}
// Uses current date + 7 days if dueDate is missing
6. Document Date Format Expectations
When building workflows that receive dates from external sources, add a sticky note documenting:
- Expected input format
- Timezone assumptions
- Any transformations applied
This helps teammates understand and maintain the workflow.
For more workflow organization patterns, see our workflow best practices guide.
When to Get Help
The Date & Time node handles most standard date manipulation needs. Some scenarios benefit from expert assistance:
- Complex business day calculations excluding holidays and weekends
- Multi-timezone scheduling with hundreds of recipients
- Financial date calculations with specific settlement rules
- Legacy system integration with unusual date formats
Our consulting services can help design robust date handling for complex requirements.
Frequently Asked Questions
Why does my timezone setting not work for some dates?
The Date & Time node’s timezone setting affects how dates are interpreted and formatted, but only when the input contains timezone information. If your input is a simple date string like 2024-03-15 without a time component, n8n interprets it as midnight UTC. The timezone setting then converts this UTC time to your specified zone, which may shift the date.
To fix this, ensure your source data includes timezone information. If that’s not possible, use the Format operation to first parse the date with an assumed timezone, then perform your operations. Alternatively, use the Code node for complete control over timezone interpretation.
How do I parse non-standard date formats like “15-Mar-2024”?
When the Date & Time node doesn’t recognize your input format, you need to specify it explicitly. In the node’s input field, you can provide a format hint using Luxon syntax. For “15-Mar-2024”, the format would be dd-MMM-yyyy.
If the node still struggles, use the Code node with Luxon directly:
const { DateTime } = require('luxon');
const parsed = DateTime.fromFormat($json.dateString, 'dd-MMM-yyyy');
return [{ json: { parsedDate: parsed.toISO() } }];
For common format issues, check our expressions guide which covers date parsing patterns.
What’s the difference between using the Date & Time node and expressions for dates?
The Date & Time node provides a visual interface for date operations with explicit timezone control and easier debugging. Expressions like {{ $now.plus({ days: 7 }) }} are faster for simple inline transformations but harder to debug and maintain.
Use the node when timezone handling matters, when the operation is a significant workflow step, or when team members need to understand the logic. Use expressions for quick formatting within other nodes where the transformation is trivial. For complex logic with conditionals, the Code node offers the most flexibility.
How do I handle daylight saving time transitions in scheduled workflows?
DST transitions create two types of issues: schedules that skip or double-fire, and duration calculations that are off by an hour.
For schedules, use calendar-based intervals (days, weeks) rather than hour-based intervals. A schedule set to run “every day at 9 AM” handles DST correctly. A schedule set to run “every 24 hours starting at 9 AM” may drift.
For calculations, use the Date & Time node’s Add/Subtract operations with calendar units. Adding “1 day” gives you the same wall-clock time the next day, even across DST. Adding “24 hours” gives you exactly 24 hours, which might be a different wall-clock time.
If your workflow is particularly sensitive to DST, test with dates around March and November transitions (for US timezone) to verify behavior.
Can I calculate business days only, excluding weekends and holidays?
The Date & Time node doesn’t directly support business day calculations. It handles calendar days, hours, and other standard intervals, but lacks awareness of weekends or holidays.
For simple weekend exclusion, use the Code node:
const { DateTime } = require('luxon');
let current = DateTime.fromISO($json.startDate);
let daysToAdd = 5; // Add 5 business days
while (daysToAdd > 0) {
current = current.plus({ days: 1 });
if (current.weekday <= 5) { // Monday = 1, Friday = 5
daysToAdd--;
}
}
return [{ json: { businessDate: current.toISO() } }];
For holiday handling, you need a holiday calendar data source (database, API, or static list) and additional logic to skip those dates. This complexity typically warrants the Code node or a dedicated sub-workflow.