Working with Dates and Times in Node-RED

Working with dates and times comes up constantly in Node-RED. Whether you're logging events, scheduling tasks, checking business hours, displaying the current time, or pulling historical data, it all relies on handling timestamps correctly. The best part is that you can manage all of this using visual nodes, without writing any code.

This documentation walks you through everything you need to know about working with dates and times in Node-RED. You'll learn how to generate timestamps, format them for display, work with different timezones, and perform time-based calculations.

Getting the Current Time in Node-RED

The most straightforward way to get the current time is with the inject node or change node.

Using Inject and Change Nodes

Both the inject node and change node can generate timestamps. Use inject when you want to trigger a flow with a timestamp, and use change when you need to add a timestamp to a message that's already flowing through.

Basic Timestamp Options (Step-by-Step):

  1. Open an inject or change node configuration window.

  2. Locate the dropdown menu next to msg.payload.

  3. Select timestamp. This setting gives you the current time as milliseconds since the epoch (e.g., 1702310400000).

  4. To see other formats, click the small arrow on the right side to expand more options:

    • milliseconds since epoch - A number representing the timestamp (1702310400000)
    • YYYY-MM-DDTHH:mm:ss.sssZ - An ISO 8601 string ("2024-12-11T15:45:30.000Z")
    • JavaScript Date object - Shows as [object Object] in the debug panel

Tip: For most work, use milliseconds since epoch. It's the simplest format and works everywhere.

Using JSONata:

Both inject and change nodes support JSONata expressions, which gives you more control:

  • $millis() - Gets the current timestamp (Unix Epoch in milliseconds)
  • $now() - Gets the current time as an ISO string
  • $moment() - Gets a date object using the Moment library

In the inject/change node, select JSONata expression from the payload type dropdown, then enter your expression.

This JSONata approach works identically in both nodes—use whichever fits your flow better.

For more advanced date/time operations and formatting, see the JSONata documentation.

Formatting Dates for Display

Raw timestamps like 1702310400000 or ISO strings like 2024-12-11T15:45:30.000Z work great for machines, but people need something readable: "December 11, 2024" or "3:45 PM" or "5 minutes ago."

Node-RED gives you two excellent options: the moment nodes for heavy lifting, and JSONata for quick, built-in one-offs.

The Moment Nodes

The Moment node handles formatting, timezones, relative time, and date math. It is built on the popular Moment.js library.

Installation

  1. Click the menu in the top-right corner (the three horizontal lines).
  2. Select Manage palette from the dropdown.
  3. Open the Install tab.
  4. Search for node-red-contrib-moment.
  5. Click Install next to the package.

Once installed, you’ll see two new nodes in the palette: Date/Time Formatter and Humanizer. For this documentation, we’ll be using the Date/Time Formatter node.

Your First Format

  1. Drag a Date/Time Formatter node onto the canvas and double-click to open its configuration.
  2. Look at the three key fields: Input (where your date lives, usually msg.payload), Output Format (your pattern), and Output (where the result goes, usually msg.payload).
  3. Type this into the Format field: MMMM D, YYYY.
  4. Connect an inject node (set to timestamp) to the Date/Time Formatter node, then connect the Date/Time Formatter node to a debug node.
  5. Click the inject button.

The debug panel will show something like "December 11, 2024".

Format Patterns

The letters in your format string are placeholders that get replaced with parts of the date. You can mix them however you want.

Category Code Example (Dec 11, 2024 at 3:45 PM) Description
Years YYYY 2024 Full year
YY 24 Two-digit year
Months MMMM December Full month name
MMM Dec Short month name
MM 12 Month number (leading zero)
Days DD 11 Day of month (leading zero)
D 11 Day of month (no leading zero)
dddd Wednesday Full day name
Time HH 15 24-hour clock (leading zero)
hh 03 12-hour clock (leading zero)
mm 45 Minutes (leading zero)
A PM AM/PM marker (uppercase)

Common Patterns:

  • YYYY-MM-DD → 2024-12-11 (Good for logs and databases)
  • MMMM D, YYYY → December 11, 2024 (Formal style)
  • h:mm A → 3:45 PM (Standard time)
  • HH:mm:ss → 15:45:30 (24-hour time)

Adding Custom Text

You can include literal text in your format by wrapping it in square brackets. The text inside the brackets will appear exactly as you wrote it.

MMMM D, YYYY [at] h:mm A

This gives you something like "December 11, 2024 at 3:45 PM".

More examples:

  • [Last updated:] MMM D [at] h:mm A → Last updated: Dec 11 at 3:45 PM

Relative Time

Sometimes you want to show how long ago something happened instead of the exact time. If you want "5 minutes ago" instead of a specific time, put this in the Output Format field:

fromNow

The Date/Time Formatter node will calculate the time difference and give you results like:

  • "a few seconds ago"
  • "5 minutes ago"
  • "3 days ago"

This works really well for activity feeds, notifications, or any "last updated" display.

JSONata Formatting

If you don't want to add another node to your flow, you can use JSONata instead. It's already built into the change node, so you don't need to install anything.

  1. Open a change node and set it to modify msg.payload.
  2. In the "to" dropdown, pick JSONata expression.
  3. Use JSONata's date functions to format your timestamp.

Basic syntax for a timestamp in msg.payload:

$fromMillis(payload, '[M]/[D]/[Y]')

This takes the timestamp in msg.payload and converts it to "12/11/2024".

JSONata Codes

JSONata uses square brackets, but the codes are different from the Date/Time Formatter node.

  • [Y] or [Y0001] → 2024 (Year)
  • [M] or [M01] → 12 (Month; use [M01] to force a leading zero)
  • [D] or [D01] → 11 (Day of month; use [D01] to force a leading zero)
  • [h] or [h01] → 3 (12-hour)
  • [m01] → 45 (Minutes, with leading zero for 0–9)
  • [P] → AM or PM

Common Patterns:

  • $fromMillis(payload, '[M]/[D]/[Y]') → 12/11/2024
  • $fromMillis(payload, '[h]:[m01] [P]') → 3:45 PM

Handling Time Zones

When you're working inside Node-RED, the timezone for any operation follows the system timezone of the machine running Node-RED. If your server is in New York, timestamps will show Eastern time. If it's in London, you'll see GMT/BST.

But what if you need to display times in a different timezone? The Date/Time Formatter node handles all of this.

Converting to a Different Timezone

Open your Date/Time Formatter node and you'll see two timezone fields:

  • Input Timezone - The timezone your timestamp is currently in.
  • Output Timezone - The timezone you want to convert to.

Type in the timezone you want—like America/New_York or Asia/Tokyo.

Finding Timezone Names:

The Date/Time Formatter node uses the IANA timezone database. These are names like:

  • America/New_York (Eastern time)
  • Europe/London (GMT/BST)
  • Asia/Tokyo (Japan time)

You can find the complete list at wikipedia.org/wiki/List_of_tz_database_time_zones.

Working Example

Let's display the current time in three different timezones:

  1. Add an Inject node (set to timestamp).
  2. Add three Date/Time Formatter nodes after it.
  3. Set a common Output Format in all three: MMMM D, YYYY h:mm A z
  4. Set the Output Timezone in each:
    • First node: America/New_York
    • Second node: Europe/London
    • Third node: Asia/Tokyo
  5. Connect a debug node to each Date/Time Formatter node.

When you click Inject, you’ll see the formatted time in three different timezones.

JSONata Timezone Handling

JSONata can also handle timezones by providing the offset in the third parameter of $fromMillis():

$fromMillis(payload, '[M]/[D]/[Y] [h]:[m01] [P]', '-0500')

The offset is a string like -0500 (5 hours behind UTC). This works, but you have to know the offset and manage daylight saving time yourself. The Date/Time Formatter node handles all of that automatically.

Doing Math with Dates

You'll need date calculations for things like historical dashboards showing the last 7 days of data or checking how many days until a deadline.

Adding and Subtracting Time

Open the Date/Time Formatter node and you'll see the Adjustment field. This lets you modify the incoming date by a specific unit of time.

  • On the left, there's a dropdown for + or -.
  • On the right, there's a dropdown with units: days, hours, minutes, weeks, months, years, etc.

Adjustment Examples:

Goal Operation Value Unit
Tomorrow + 1 days
Yesterday - 1 days
2 hours ago - 2 hours
Next week + 7 days

How to Set it Up:

  1. Drag an Inject node onto the workspace (set payload to timestamp).
  2. Connect a Date/Time Formatter node and double-click to open it.
  3. Configure your desired adjustment (e.g., + 1 days).
  4. Set the Output Format field, maybe to YYYY-MM-DD.
  5. Connect the Formatter to a Debug node and Deploy the flow.

Hit the Inject button to see the adjusted date.

There’s a lot more you can do with the Moment node, including advanced formatting options and additional date/time transformations. For more information, read the node’s README documentation.

Calculating Time Differences

Sometimes you need to know the duration between two timestamps. The moment node doesn't directly calculate differences, so for this, you'll want to use a Change node with JSONata.

JSONata can calculate differences with simple subtraction, as timestamps are in milliseconds.

JSONata Difference Formula

The basic formula is to subtract the earlier timestamp from the later one, then divide to convert the result into your desired unit.

Unit Division Value (ms) Example Formula
Seconds 1000 (ts1 - ts2) / 1000
Minutes 60000 (ts1 - ts2) / 60000
Hours 3600000 (ts1 - ts2) / 3600000
Days 86400000 (ts1 - ts2) / 86400000

Working Example (Difference in Days)

This example calculates the difference between a timestamp seven days ago and the current time (7 days).

  1. Drag an Inject node onto the workspace (set payload to timestamp).

  2. Drag a Change node and connect it. Use this node to set up our two reference times (msg.start_time and msg.end_time).

    • Rule 1:
      • Action: Move
      • From: msg.payload
      • To: msg.end_time
    • Rule 2:
      • Action: Set
      • Property: msg.start_time
      • To: JSONata expression
      • Expression: msg.end_time - (7 * 86400000) (This calculates a timestamp exactly 7 days earlier).
  3. Drag a second Change node and connect it. This node performs the final calculation.

    • Action: Set

    • Property: msg.days_difference

    • To: JSONata expression

    • Expression:

      (msg.end_time - msg.start_time) / 86400000
      
  4. Connect this second Change node to a Debug node and Deploy the flow.

Hit the Inject button. The Debug tab will show the number of days difference (7).