The situation you describe is correct and expected.
HA internally stores all time and timestamps as UTC in Unix time as (milli-)seconds since Jan 1, 1970 midnight UTC. Here in the UK, UTC is the same as GMT during the winter months, but 1 hour behind during the summer daylight saving BST (UTC+1).
Fortunately HA does a very good job of displaying these times as local times, but it does this at the point of display. Therefore, when looking at ‘last_changed’ and ‘last_reset’ and ‘last_updated’ times from within HA, what you see is UTC time, but adjusted according to your machine / HA local time zone setting.
When pulling data out of HA to Node-RED, some of this is going to be the raw UTC time, and it is not going to get automatically modified into ‘local time’.
I assume that you are using a current-state node, to pull the entity details for an HA entity, and then to show this using the debug node.
HA is going to hold the ‘last_changed’ time stamp in UTC.
The Node-RED HA current-state node is going to pull this from HA, as it is held.
Here I have a current-state node, with the output of the entity shown in the Node-RED debug window. This entity state was very recently changed / updated.
- Note that the debug window at the top shows the time as 11:24:25, which is my local time (based on my machine time / settings). So Node-RED is working in ‘local time’
- HA stores historic data as strings, so the ‘last_changed’ field is actually a string representation of a timestamp.
- The string is 2023-04-08T10:25:38.932Z. The ‘T’ and the ‘Z’ show that this is an ISO format timestamp with the UTC (timezone Z) suffix.
- This is currently, for me, 1 hour behind my local time. It is correct, but stored and shown as UTC time.
I have, as you will see from the current state node edit page, added a ‘changed’ field to the output, which uses some JSONata. The $entity() function just gets the entity, the $toMillis() function converts a correctly formatted timestamp string to Unix millisecond time (which is an integer).
In the debug window you will see this value is shown as 1680949539932. This is the Unix timestamp for Saturday, 08-Apr-23 10:25:39 UTC (Unix time is based on seconds only).
So HA is working correctly, Node-RED is working correctly, and your machine (and thus both HA and Node-RED) know all about your local time zone.
And here is the clever part.
As my ‘change’ field is a number, and this number looks like a Unix milli-second timestamp, Node-RED can show it to you in several different formats (it can’t do this with just the ‘string’ time as that is just a string).
Clicking on the ‘timestamp’ rotates through decimal UTC time, local time, Hex, and back to decimal.
Without any setting in Node-RED settings file, it will use your local machine time zone by default.
To change UTC timestamps to local time in my flows, or if I just want ‘now’ in local time, I use the ‘date/time formatter’ node from the node-red-contrib-moment nodes that I added to my pallet. https://flows.nodered.org/node/node-red-contrib-moment
The formatter node can take any (well formatted) string/number timestamp and convert to either computer local time or a given time zone (neatly dealing with local and DST) and avoids any need to use the function node and JavaScript code.