Understanding how to print time in local timezone

I thought I understand how datetime works in Javascript, but I sometimes I run into issues and I question myself over-and-over again. I know that the timestamp is stored in UTC and we should only do a conversion to local timezone when we want to print the information on the screen. And I know the timezone on the machine where Node-Red is running should be set correctly according to the local timezone.

I am working on machine in Finland, Node-Red is running on an IoT gateway also in Findland which is configured like this:

I assume this is all correct, since Finland in UTC+3 and GMT+2 because of the DST now.

If I do a simple toLocaleString it just converts the timestamp into a time format, in this case UK but the time is the UTC time:


The local time is 23:50 as shown currectly first header of the debug message, but I assume this only validates that the browser is running in the correct local timezone.

Now if I print the getTimezoneOffset, I get -180 which is the UTC offset in the Summer (DST active).


That again is correct, so it means that Node-Red knows that the local timezone is Finland.

I created this simple function to convert the UTC time to Finnish local time:

This code works, as I get the time in local time, and matches the time in the computer I work on. Everything looks good.

Did I do something fundamentally wrong? Will this code work once the DST goes away?
To be honest I still don't understand why I had to offset my timestamp the the value of getTimezoneOffset but also the additional 2 hours in tzOffset. I thought it should be able to create a code which always works assuming the timezone on the machine which Node-Red runs on is set up correctly.

Sorry if this has been discussed before, but the other topics I looked were caused by the incorrect timezone setting on the PI, which as I understand is not the case here.

Hi @nygma2004

I really dislike the Date object in javascript - I have always seen it being frowned upon by the intermaweb

But, this is where I think the confusion lies (maybe)

toLocaleString IS NOT correcting for the timezone, its only representing the date object in a format you specify ('en-GB')

So it's taking the time (which is UTC) and formatting it out, to a format (not timezone) for the language you specify. YYYY-MM-DD vs DD-MM-YYYY etc etc

if I may,
You should use a change Node to create a custom formatted string, that does all the heavy lifting for you.

$moment().tz('Europe/London').format('DD/MM/YYYY HH:mm')

[{"id":"74d5b1184da4a405","type":"change","z":"96cd84ddf6640294","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$moment().tz('Europe/London').format('DD/MM/YYYY HH:mm')","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":240,"wires":[["557a0b72e5e9d275"]]},{"id":"eb8aad5bae50df51","type":"inject","z":"96cd84ddf6640294","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":220,"y":240,"wires":[["74d5b1184da4a405"]]},{"id":"557a0b72e5e9d275","type":"debug","z":"96cd84ddf6640294","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":580,"y":240,"wires":[]}]

I apologies if I have not locked on to the correct issue (I am not good at how JS manages its Date object)

EDIT


I Could be wrong about the behaviour of toLocaleString - hence my use of JSONata for this stuff :sweat_smile:

Thanks. For the time being, I try to do this without moments, as I sometimes work in environments where I cannot install moments.