Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Form Time picker gives incorrect time #787

Open
6 tasks
colinl opened this issue Nov 27, 2022 · 5 comments
Open
6 tasks

Form Time picker gives incorrect time #787

colinl opened this issue Nov 27, 2022 · 5 comments

Comments

@colinl
Copy link
Contributor

colinl commented Nov 27, 2022

What are the steps to reproduce?

Import this flow, deploy, enter a time in the time field and hit submit

[{"id":"8ad125f0fadc86a3","type":"ui_form","z":"2fbaad6f2b46c829","name":"","label":"","group":"343f7063521c327e","order":1,"width":0,"height":0,"options":[{"label":"time","value":"time","type":"time","required":true,"rows":null}],"formValue":{"time":""},"payload":"","submit":"submit","cancel":"cancel","topic":"topic","topicType":"msg","splitLayout":"","className":"","x":250,"y":500,"wires":[["613f8766710ffb29"]]},{"id":"613f8766710ffb29","type":"debug","z":"2fbaad6f2b46c829","name":"debug 42","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":400,"y":500,"wires":[]},{"id":"343f7063521c327e","type":"ui_group","name":"test","tab":"62712bbf.888b94","order":3,"disp":true,"width":"6","collapse":false,"className":""},{"id":"62712bbf.888b94","type":"ui_tab","name":"test","icon":"dashboard","disabled":false,"hidden":false}]

What happens?

The payload in the debug window shows an incorrect time. I am in the UK in UTC (not DST) so it should show exactly the time I enter, instead it shows an hour earlier. If I enter 10:00 then payload.time shows "1970-01-01T09:00:00.000Z"
The same issue has been seen by others, but not all. See https://discourse.nodered.org/t/time-picker-in-ui-form-node-sends-wrong-time-in-output-payload/71296

An inject timestamp direct into a debug node correctly shows the current time and cycles through the formats.
image
image

Please tell us about your environment:

  • Node-RED-Dashboard version: 3.2.3
  • Node-RED version: 3.0.2
  • node.js version: 16.18.1
  • npm version: 8.19.2
  • Platform/OS: Ubuntu, Pi OS and Mac (see discourse thread)
  • Browser: Chrome and FF on Ubuntu, Chrome on Android
@colinl
Copy link
Contributor Author

colinl commented Nov 27, 2022

A pattern appears to be emerging in the linked thread. So far all those on UTC see the 1 hour shift, all others show the correct time.

@dceejay
Copy link
Member

dceejay commented Nov 27, 2022

Is it UTC or GMT(UK) ?

@colinl
Copy link
Contributor Author

colinl commented Nov 28, 2022

That is indeed a relevant question, I was wrong to state that my timezone is UTC, it is GMT(UK). So currently I am in UTC+0, and in the summer UTC+1.

The discussion has moved ahead in the linked forum post, I suggest leaving this issue for the moment till that discussion has run its course and possibly come to a conclusion. Probably I opened this too early.

@dceejay
Copy link
Member

dceejay commented Dec 2, 2022

@colin - so where are we with this... is it something we can fix - or a discrepancy with the way javascript handles UK timezone around 1970 ?

@colinl
Copy link
Contributor Author

colinl commented Dec 2, 2022

I don't think it can be fixed and retain backwards compatibility, unless we add a new option. The problem is that the node gets a time back from the browser which includes the time zone for 1st Jan 1970. It then converts that to a UTC time and returns that. Since, in the UK, in 1970, we were on permanent UTC+1 the answer appears to be 1 hour later than it should be, when we are not using DST. What the node should do is either to return the time exactly as received from the browser (including the timezone) so that it is possible to work out what the answer is, but possibly a better solution would be to return the number of milliseconds since the start of day, or something similar. So 01:00 would always return 1 hour in milliseconds, whatever the timezone.

I suppose one change that would keep backwards compatibility would be to return, in addition to the property named after the field (startTime or whatever), would be to add something like startTime_msec which contains the milliseconds offset, but that doesn't seem a very attractive solution.

If the browser and the server are configured to the same timezone then the flow below provides a workaround, which I think works for anybody. If, however, timezone of the server and the browser are different then I don't think that there is any workaround that will determine what the user has entered. That is unless one can interrogate the timezone of the browser and make use of that.

Workaround flow, which assumes that the field is called Start and (I believe) only works if the timezone of the server and browser are the same. It works because recreating it as a Date object makes the timezone offset on 1st Jan 1970 available again, provided browser and server are the same.

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;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants