Changing the type will of course break existing users…
can you explain that please @dceejay ?
Then maybe a note in the help section may help avoid confusion.
@e1cid suggested changed the output format from the current time object to raw milliseconds - so that users could then convert it how they liked... This would break any existing user of the node that it is working for until they then add the necessary conversion for their application. We don't really want to do that unless we really have to and would mean a major bump to dashboard from version 3 to version 4..
Thank you @dceejay . I totally understand that.
I found a code snippet and modified and added it to the function which I'm developing to process the form data.
var dateTime = msg.payload.Start
var myDate = new Date(msg.payload.Start);
var offset = myDate.getTimezoneOffset() * 60 * 1000;
var withOffset = myDate.getTime();
var withoutOffset = withOffset - offset;
node.warn(withOffset);
node.warn(withoutOffset);
duration = withOffset
milliseconds = parseInt(( duration % 1000) / 100)
seconds = Math.floor((duration / 1000) % 60)
minutes = Math.floor((duration / (1000 * 60)) % 60)
hours = Math.floor((duration / (1000 * 60 * 60)) % 24)
mess = hours + ":" + minutes + ":" + seconds
node.warn(mess)
duration = withoutOffset
milliseconds = parseInt((duration % 1000) / 100)
seconds = Math.floor((duration / 1000) % 60)
minutes = Math.floor((duration / (1000 * 60)) % 60)
hours = Math.floor((duration / (1000 * 60 * 60)) % 24)
mess = hours + ":" + minutes + ":" + seconds
The debug output shows that this works at this moment in time and probably up to 26 March 2023
I'm not sure if there is any way to test whether this really does work until we really have DST and UTC 00.00 but I think I'll use it until then
You should add a comment node to the tab you are using this on and document what you did and why so in March next year if any issue comes up, you have something to jog your memory.
In case anyone is interested I have found the cause of the confusion. In 1968, as I now remember, but had forgotten, the UK trialled year round daylight saving time. This trial lasted until 1971 and meant that London was permanently on DST or UTC+1. Hence, in the UK, the start of the epoch was at 01:00 local time.
Well $toMillis() is wrong as far as I can see. This code gives 57660000, as it should
msg.payload = new Date("1970-01-01T16:01:00.000Z").getTime()
Yes it seems to be the browser returning a date object that includes the time zone UTC+1 (when in uk) The html5 input doesn’t seem to have any options to change that so I’m not sure how we can adjust it.
Do you feel that the solution that I proposed above will stand the test of time and still work when we do have DST in effect and that the solution can only be applied at a developer level?
I think this is a simpler solution. The code
const time = new Date(msg.payload.time)
const msecLocal = time.getTime() - time.getTimezoneOffset() * 60000
gives the milliseconds since the start of the day local time, from which anything else can be calculated. I think that should work for any time zone, provided the server and browser are configured for the same zone. At the moment my brain has not been able to cope with considering the situation where the two timezones are different.
I have to go for the moment, but will think about the most efficient way to get the hours/mins/secs from that.
I think I already mentioned that in post 32 above.
Is it? or is it handling the year round UK DST in 1970 correctly?
If I put, in a Change node, Set msg.payload To JSONata $toMillis("1970-01-01T16:01:00.000Z")
I get 57660000, which agrees with Date.getTime(). Where did you see $toMillis() give 61260000 for that timestamp?
the most efficient way to get the hours/mins/secs from that.
In fact it is easier than I thought. This will give the hours and minutes as entered into the time picker
const time = new Date(msg.payload.Start)
// this is the number of milliseconds into the day, if needed
//const msecLocal = time.getTime() - time.getTimezoneOffset() * 60000
const hours = time.getHours()
const mins = time.getMinutes()
msg.payload = `${hours.toString().padStart(2,"0")}:${mins.toString().padStart(2,"0")}`
return msg;
[Edit] Corrected code to pick up from msg.payload.Start
@Tilerdon does my simpler solution work for you?
Anyone else, can you confirm whether it works ok with a timezone other than uk?
I am pretty sure it will not work if the browser and server timezones are different, and I don't think there is any way to make it work, unless someone can think of anything. The problem is that it is necessary to know the browser timezone.
It would have been better if the node sent the time as received from the browser, including the the TZ information, but there is not much that can be done about that now. I can't think of a way of fixing it and keeping it backwards compatible, other than having a new option to change the format.
@Colin the code works fine with a modification to the first line in order to work with @Tilerdon's flow - msg.payload.time
should be msg.payload.Start
msg.payload.time
should bemsg.payload.Start
Oh yes, I was testing with a reduced example.
I will correct my post.
Thanks.
const time = new Date(msg.payload.time) // this is the number of milliseconds into the day, if needed //const msecLocal = time.getTime() - time.getTimezoneOffset() * 60000 const hours = time.getHours() const mins = time.getMinutes() msg.payload = `${hours.toString().padStart(2,"0")}:${mins.toString().padStart(2,"0")}`
Yes @Colin that works fine thank you. I agree that it does look simpler than the other code that I picked up. Not quite sure about the use of $ however but that is a matter for me to resolve at some other time.
Thank you all for your help and the interesting issues raised by it.
Not quite sure about the use of $ however
msg.payload = `${hours.toString().padStart(2,"0")}:${mins.toString().padStart(2,"0")}`
That is just using string template literals. The above is exactly the same as
msg.payload = hours.toString().padStart(2,"0") + ":" + mins.toString().padStart(2,"0")
but is arguably easier to code and to understand. It doesn't make much difference in this case, but if you are trying to build a string with quotes and double quotes in it then the traditional method can get horribly complex.