How to get the current date and time for my current timezone?

I am trying to get the current date and time in my timezone to be used as part of a message in a flow. I have created a basic function containing this:

var d = new Date();
msg.payload = d.getTime();
return msg;

and this is how I am using it for testing purposes:

it works but is giving me the wrong time.

image

This is my current flow where I am planning to use such function:

My timezone is EST America/New_York and I have that configured in my configuration.yml file:

homeassistant:
  name: Home
  latitude: !secret latitude_home
  longitude: !secret longitude_home
  elevation: 0
  unit_system: imperial
  temperature_unit: F
  time_zone: America/New_York
  currency: USD
  internal_url: !secret internal_url
  external_url: !secret external_url

what I am missing here? Is there a more easy/proper way to get the current date and time?

Here is the entire flow:

[
    {
        "id": "49ea54fced633ba6",
        "type": "function",
        "z": "b0037499.3da95",
        "name": "Get Current Time",
        "func": "var d = new Date();\nmsg.payload = d.getTime();\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 390,
        "y": 320,
        "wires": [
            [
                "cce7c7f6bb5ec54b"
            ]
        ]
    },
    {
        "id": "cce7c7f6bb5ec54b",
        "type": "moment",
        "z": "b0037499.3da95",
        "name": "",
        "topic": "",
        "input": "payload",
        "inputType": "msg",
        "inTz": "Europe/Oslo",
        "adjAmount": "1",
        "adjType": "hours",
        "adjDir": "add",
        "format": "LLL",
        "locale": "",
        "output": "payload",
        "outputType": "msg",
        "outTz": "Europe/Oslo",
        "x": 620,
        "y": 320,
        "wires": [
            [
                "36dc85d182937076"
            ]
        ]
    },
    {
        "id": "36dc85d182937076",
        "type": "debug",
        "z": "b0037499.3da95",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 810,
        "y": 320,
        "wires": []
    },
    {
        "id": "9f95a86341468825",
        "type": "inject",
        "z": "b0037499.3da95",
        "name": "Timestamp",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 200,
        "y": 320,
        "wires": [
            [
                "49ea54fced633ba6"
            ]
        ]
    }
]

Short answer - you appear to be using the Date/Time formatter node with both input and output time zone set to Europe/Oslo, hence the output will be UTC+2 (CET on DST).

  • You can set the Date/Time formatter input to ‘timestamp’ and cut out the function node input completely
  • You can remove the input & output time zones to blank and the node will pick up the local machine settings. If your machine is set to Europe/Oslo then either change that, or override the settings using America/New_York. The machine time zone settings are quite separate to HA time zone settings!

Longer answer:

Home Assistant and the device you are running it on, like all good computers, runs using UTC. This is great because it is the same time for everyone at the same time, and it does not suffer from DST changes.

Humans are utterly perverse and like to run on ‘local time’, which varies from place to place (and can change with the seasons). Most computer languages know absolutely nothing about time, and it can be quite tricky to get UTC turned into local time.

That said, there are several ways to do this in HA and Node-RED.

Firstly, there are pitfalls. JavaScript, which is built in to every browser programme, has the ability to lift the machine time zone settings and to apply UTC to local-time conversion on the fly. JavaScript has several inbuilt functions that can do this. Node-RED, like much of what we actually see on the screen, uses JavaScript processing for display. Here is the catch - when you look at ‘debug’ in Node-RED, the programme can work out if what you are displaying looks like UTC time, and it can display it as UTC or local (applying the local time zone settings stored in the base computer and accessed by JavaScript - at the point of display).

I have four different ways to get ‘local time’ (I am sure that there are more)

  1. JavaScript in a function node should do it for you. This uses the JavaScript and local machine time zone settings and, as far as I understand these things, is independent of HA or Node-RED settings. You can find details on all the Locale functions as there are different ones for date / time / datetime, and buckets of options for formatting.
const d = new Date();
msg.payload = d.toLocaleString();
return msg;
  1. Use HA.
    HA has a date time integration which can be easily added to YAML config.
    see https://www.home-assistant.io/integrations/time_date/
    This, when set up correctly, adds one or more entities for the date / time, including if you wish for UTC timestamp and ISO (local) timestamp. This is an easy way to get local time into HA and can also be then picked up in Node-RED. I have not tested this, but I presume this uses the HA time zone setting.

  2. Node RED has function nodes to work with date time, and the moment node has the ability to convert any time to any time zone of your choice. I used this a lot to get ‘local time’, and I would probably suggest that this is the easiest way to get ‘local time’
    Go to the bottom of your NR pallet and you will find the ‘date time formatter’ node. This amazing node takes in any timestamp and formats it to any other. The neat thing is, if you leave the input and output time zones blank the node will lift the time zone settings from the machine. Local setting (local formatting such as dd/mm for Europe or mm/dd for USA) can also be blank and defaults then to ‘C’ which means use the local Computer region settings.
    If you set the input field option to ‘timestamp’ and everything else empty, hey presto you get UTC time. However, if you put any format string into the format field, then the node will return local time. ‘LLL’ will, for example, provide a localised local time result. The node documentation gives plenty of help and will point you in the right direction to read up on all the formatting values you can use.
    I like this node as it is very easy to get ‘now’ +/- a fixed time such as getting the next hour.

  3. DIY. I use JSONata quite a lot now rather than function nodes, and to get local time requires a few tricks but is possible. Alternatively there are API services that will return local time zone settings for any given location, so it is possible to get a UTC and local time for a place other than your local machine.

1 Like

I must say this explanation is AWESOME! Thanks a lot!

After posting this I found out that the Date Time Formatter node can take the current timestamp as input. I would not need to carry the value over from another node as I was trying to do initially.

Using it like that fixes my issue and yes, after digging into the node documentation I found out all this information you mentioned above like the timezone being used and so on.