Using date-fns-tz additional module

Hi all, first time poster here.
Node-RED version: v3.1.9
Node.js version: v18.20.4
Linux 5.15.0-119-generic x64 LE
I'm trying to get my feet wet with node-red as home automation software and thus far am enjoying the possibilities.

I'm trying to use the date-fns-tz module so that times that are entered for when a particular event happens can by entered in local time (America/New_York) but internally everything happens in UTC (which my Linux system runs as).

I have installed date-fns and date-fns-tz using npm from the .node-red directory and have set them up in settings.js like this:

functionExternalModules: true,

and

    functionGlobalContext: {
        os:require('os'),
        tplinkApiModule: require('tplink-smarthome-api'),
        dateFns: require('date-fns'),
        dateFnsTz: require('date-fns-tz')
    },

but from there things are a bit fuzzy for me.
I have tried a function node with


and then have code like:

const date = new Date();
const timeZone = env.get("TZ");
const zonedDate = utcToZonedTime(date, timeZone);
const offset = zonedDate.getTimezoneOffset();
node.warn(`${date} - ${zonedDate} - ${offset}`);

but I get this error:
image

I feel like I'm close but can't seem to get the right combination of directives.

Perhaps there is another way to do what I'm trying to do, but I'd like to be able to use additional modules in any case.

Any help greatly appreciated.

Here is one way you could do it using a function node

[{"id":"95c1661d8a920cb7","type":"inject","z":"cc74683187f0b740","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":960,"y":140,"wires":[["589790794cc1c8ab","514e4da892286197"]]},{"id":"589790794cc1c8ab","type":"debug","z":"cc74683187f0b740","name":"Raw time value","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1180,"y":120,"wires":[]},{"id":"0a96e628c5d41ec1","type":"debug","z":"cc74683187f0b740","name":"Converted date/time","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1200,"y":240,"wires":[]},{"id":"514e4da892286197","type":"function","z":"cc74683187f0b740","name":"convert time to local date/time","func":"let now_time = msg.payload\nlet d = new Date(now_time);\nmsg.payload = d.toLocaleString(\"en-US\")\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1230,"y":180,"wires":[["0a96e628c5d41ec1"]]}]

From the date-fns-tz docs

Usage with Node.js

Node.js supports the Intl API and ships with full ICU data included in the binary since v13, so this library works by default.

You should also be able to use moments in a change node. or a function node Search results for 'format date with moment' - Node-RED Forum

Or there is a moment node node-red-contrib-moment (node) - Node-RED

I see that I've not clearly described what I am trying to do.
I have a local time value in that I wish to get the timestamp of. It is not that I need to display it in local time, I need to convert it to UTC for a proper timestamp.

You still have not clearly described your issue, how about some examples of what you have and what you want.

Built in moment can do this in a change node.

Alternatively in a function node with


const d = new Date(msg.payload)
msg.payload = {}

// Get UTC ms since epoch
msg.payload.ts= d.valueOf()

// Get iso time
msg.payload.iso = d.toISOString()

return msg

(Assumes the time to convert is in msg.payload)

Ref: Date.prototype.toISOString() - JavaScript | MDN

I assume you mean an iso string because I associate timestamp with the numeric Epoch in JavaScript.

Exactly what form do you have the date and time in, and exactly what form do you want it in?

Thanks for helping me.

The Linux system runs at UTC, but the node-red TZ environmental variable is set to America/New_York, which I want entered times to be based on (it could change).

I have the entered time as "19:00" or "06:30" from a configuration table and I would like to get an epoch timestamp of those times with the currently set TZ timezone.

I am not using date on the entries because these times happen daily.

Do you want the UTC time for that time on the current date?

What exactly do you mean by epoch timestamp? A javascript ticks since epoch (milliseconds)? A javascript Date object? A Unix timestamp (seconds)?

Yes, I want the UTC time for that time on the current date.

By epoch timestamp, I mean the javascript ticks since epoch (milliseconds).

My program is trying to determine where the current time fits in a list of possible time slots in the current day.

valueOf as offered in my post: Using date-fns-tz additional module - #6 by Steve-Mcl

As said moment in a change node using JSONata can do this

[{"id":"27f922a45cfb6ed9","type":"inject","z":"0df28c03098e1a7f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"06:30","payloadType":"str","x":170,"y":520,"wires":[["3311096d42d8d652"]]},{"id":"3311096d42d8d652","type":"change","z":"0df28c03098e1a7f","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$number($moment($$.payload, \"HH:mm\").format(\"x\"))","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":520,"wires":[["27e213a1e3bfa8a4"]]},{"id":"27e213a1e3bfa8a4","type":"debug","z":"0df28c03098e1a7f","name":"debug 2567","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":550,"y":520,"wires":[]}]
$number($moment($$.payload, "HH:mm").format("x"))

Where msg.payload holds the string 06:30
This will output

1724650200000

or this

$moment($$.payload, "HH:mm").utc().format()

will output

"2024-08-26T06:30:00Z"

or this

$moment($$.payload, "HH:mm").format()

will output

"2024-08-26T06:30:00+01:00"