Help with Date/Time Formatter node

Hello,
I'm trying to send a timestamp of local time including daylight saving to a remotes ESP32. I've attached the flow of my attempt, but there is no 'translation' of the timestamp from UTC to local Date/Time. The remote ESP32 is expecting a timestamp in local time. Can someone advise me on why this does not work? Cheers

[
    {
        "id": "56ca8adc78641e82",
        "type": "tab",
        "label": "Test date-time",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "20a17f5c17fe994c",
        "type": "inject",
        "z": "56ca8adc78641e82",
        "name": "RTC_Update",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "RTC_Update",
        "payload": "",
        "payloadType": "date",
        "x": 130,
        "y": 620,
        "wires": [
            [
                "6b22699e6e182f2c",
                "f420e201ee57a541"
            ]
        ]
    },
    {
        "id": "127d320435079b7d",
        "type": "mqtt out",
        "z": "56ca8adc78641e82",
        "name": "",
        "topic": "Security/Environment/RTC_Update",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "caada23d7349b8b3",
        "x": 900,
        "y": 480,
        "wires": []
    },
    {
        "id": "d95f85658d1ab5bf",
        "type": "debug",
        "z": "56ca8adc78641e82",
        "name": "debug 5",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 740,
        "y": 680,
        "wires": []
    },
    {
        "id": "6b22699e6e182f2c",
        "type": "debug",
        "z": "56ca8adc78641e82",
        "name": "debug 6",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 380,
        "y": 680,
        "wires": []
    },
    {
        "id": "74b05786c00fde1d",
        "type": "moment",
        "z": "56ca8adc78641e82",
        "name": "",
        "topic": "/Security/Environment/RTC_Update",
        "input": "",
        "inputType": "date",
        "inTz": "Europe/London",
        "adjAmount": 0,
        "adjType": "days",
        "adjDir": "add",
        "format": "",
        "locale": "en-US",
        "output": "CurrentDateTime",
        "outputType": "global",
        "outTz": "Australia/Adelaide",
        "x": 540,
        "y": 500,
        "wires": [
            [
                "127d320435079b7d",
                "d95f85658d1ab5bf"
            ]
        ]
    },
    {
        "id": "f420e201ee57a541",
        "type": "ui_button",
        "z": "56ca8adc78641e82",
        "name": "",
        "group": "3512e6ac9e794606",
        "order": 8,
        "width": 0,
        "height": 0,
        "passthru": true,
        "label": "RTC_Update",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "date",
        "topic": "topic",
        "topicType": "msg",
        "x": 270,
        "y": 500,
        "wires": [
            [
                "74b05786c00fde1d"
            ]
        ]
    },
    {
        "id": "caada23d7349b8b3",
        "type": "mqtt-broker",
        "name": "MQTT Broker",
        "broker": "192.168.68.102",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthRetain": "false",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closeRetain": "false",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willRetain": "false",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    },
    {
        "id": "3512e6ac9e794606",
        "type": "ui_group",
        "name": "Environment",
        "tab": "52741c56e347aec9",
        "order": 4,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "52741c56e347aec9",
        "type": "ui_tab",
        "name": "Security",
        "icon": "dashboard",
        "order": 1,
        "disabled": false,
        "hidden": false
    }
]

What format is it expecting?

Throw a debug node on the output of the moment node to see what the payload is.

The timestamp expected by the ESP32 is the same as a timestamp that is issued when an inject node is triggered EXCEPT it needs to be in local time (not UTC). As an aside, could you please advise if the flow I attached was readable (I've never attached a flow before). Cheers

I'd hoped the flow I attached was readable (I've never attached one before) and it would have shown that a debug was attached to the output of the moment node. And the result is that the input timestamp is the same as the output of the moment node (plus several ms of processing).
One thing I didn't account for was that I couldn't get the moment node to successfully deploy until I set the 'output to' to a global variable - and I had no idea how to 'use' that global variable (if indeed I needed to) further 'down the string'

Yes it is, and it revealed that you are using the original dashboard which is now deprecated.
Unless you already have a significant investment in your dashboard code, it might be wise to switch to @flowfuse/node-red-dashboard.

For me, the word "timestamp" indicates exactly what your flow injects, the number of seconds or milliseconds since 1st Jan 1970.

What does milliseconds since 1970-01-01T00:00:00.000Z in Australian daylight saving time even mean?

It is readable. However, some of us don't care to load random flows into our systems. Yours left me with a couple of extra unwanted config nodes for example:

Best to also include a screenshot of the flow or to use flows after your opening triple backticks to get the flow visualised automatically.

The error you have made is not to tell the moment node to use a different output format.

The default output is always going to end up in UTC as that is the way that JavaScript does things.

Change the "Output Format" field to output a different format as shown in the help.

Julian,

Thanks for the rapid reply. As you could imagine, I'm not in any way experienced with Node-Red - but willing and trying to improve!

To clarify, my intention is to take the output from the inject node which is UTC - in GMT time (London) - and change the output of the moment node to be UTC in Adelaide South Australia time (with daylight saving).

That's my intention.

Is that what the moment node should do for me?

I read the help when I set this up, and it says the default output format (IOS8601 (UTC)) is what I need - you're suggesting I might need to change the format (which is not what I want). What am I not understanding?" And, if I use the default output format, I have to set the 'output to' to a global variable (and I have no idea about where or how that is used!

I hope you can see where I might need to make any changes!

Hi Julian,

I didn't read the most important part of the 'output format' help - that the output to is always in GMT (Z) time if the default format is used.

I hope I'm excused for an unrealistic expectation that the moment node should be able to manipulate a UTC from (Z) to the UTC of the output timezone!

I hadn't seen any forum traffic that might have needed or suggested this functionality - could be wrong - I have missed things before (sheepish look)!

So, if moment node is not suitable, can you suggest a workaround?

Cheers

UTC is universal time and is the same no matter what timezone you are in. so that statement makes little sense.

You can format timezones in the moment node or in a change node using $moment() and JSONnata.
Example of change node here Formatting times & dates with moment.js examples

Clearly, UTC is UTC (AKA GMT, AKA Zulu time) so it can only ever be a time at the Greenwich meridian.

The moment node uses the Moment library, the same as does $moment in JSONata in a change node, just a bit more friendly.

To output a local time, you must use the formatting option to something appropriate.

Please note that the moment node has some convenient example flows built-in to help you:

Use Node-RED's Import function and go to Examples and expand the moment node to see all of these, try importing the last of the examples which gives you this:

You need an output format something like this to get a localised time output:

image

Converted outputs are a STRING, not a Date object.


For the sake of completeness, I should also point out that modern JavaScript has lots of international date/time conversion tools built in. Check out the INTL object for details. There isn't a specific node that exposes these but they can be used in a function node.

The moment node wraps the moment library in a more friendly node than JSONata in a change node. They both use the same library. :wink:

Please clarify what you mean by that. The default output of the inject node is just a number representing the number of milliseconds since the start of 1970. Are you perhaps confused by the way that a debug node will convert that to a formatted date for you?

What software are you running in the ESP?
Is there any documentation for that s/w that will tell us what it expects?
If you have written the s/w yourself then what are you doing with the timestamp?

By the way, I should have said that it is best practice to use UTC throughout and only use local date/times at the point of user contact. E.g. user inputs and user displays.

If you are using the Arduino IDE to program your ESP's, you will find at least one date/time library which should be able to manage this locally for you.

Hi TotallyInformation,
I loaded the example flow you recommended and I can see the result, However, I'm unable to make any changes at all - as soon as I edit one of the Date/Time Formatter nodes, I get two errors - Invalid properties - Invalid property expression: zero-length, and Invalid property expression: zero-length. I made no changes during the edit to the node and the errors appear on what ever node I edit.
What could be the problem?

Just seen that, if you open the settings you will see that 2 of the fields are highlighted in red. You will need to put something in there, not sure why that doesn't work automatically, I'm sure it used to. Anyway, simply add "payload" into both.

You're a champion! I thought that because payload was shown in both that is was using that - but now I realise they were greyed out.