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

Incorrect Date Conversion in nodered, moment.js works fine. #20

Closed
brmo opened this issue Jun 1, 2018 · 4 comments
Closed

Incorrect Date Conversion in nodered, moment.js works fine. #20

brmo opened this issue Jun 1, 2018 · 4 comments

Comments

@brmo
Copy link

brmo commented Jun 1, 2018

From Home Assistant, I get the following data:

entity_id: "binary_sensor.garage_camera_motion"
last_changed: "2018-06-01T18:13:03.909192+00:00"

Then using this project, i am taking that last_changed value and converting to "dddd, MMMM Do YYYY, h:mm:ss a" the result I get is Tuesday, June 19th 2018, 11:13:03 am. Which is off by 18 days. The time is correct as I have it converting from UTC to US/Pacific time.

If I take that exact time string and use https://codepen.io/widmoser/pen/NNOQEx?editors=1111 to test moment.js using the following, its correct.

const time = moment('2018-06-01T18:13:03.909192+00:00').format("dddd, MMMM Do YYYY, h:mm:ss a");
alert(time);

Am I doing something wrong using the plugin?

@shrickus
Copy link
Contributor

shrickus commented Jun 1, 2018

Well, it's definitely not a problem in the output (formatting) -- even if I use the default ISO-8601 formatting, the UTC "timestamp" returned is 2018-06-19T18:13:03.909Z

However, if I use plain JavaScript to parse that date string, it is correctly interpreted:

> new Date("2018-06-01T18:13:03.909192+00:00")
2018-06-01T18:13:03.909Z

So what is happening inside the moment node? Well, here's the relevant section of code:

  default: 
        node.log(node.inTz.split('/')[0]); 
        var prefOrder = {preferredOrder: {'/': 'DMY', '.': 'DMY', '-': 'YMD'} }; 
        if ( (node.locale.toLowerCase().replace('-','_') === 'en_US') || (node.inTz.split('/')[0] === 'America') ) { 
          prefOrder = {preferredOrder: {'/': 'MDY', '.': 'DMY', '-': 'YMD'} }; 
        } 
        inpFmt = parseFormat(inp, prefOrder); 

So the next question is... what input format is being determined by the moment-parseformat library?

> var parseFormat = require('moment-parseformat');
> parseFormat("2018-06-01T18:13:03.909192+00:00"):
'YYYY-MM-DDTHH:mm:ss.SSSD2Z'

Interesting -- but also clearly wrong! So the six digits representing microseconds were interpreted as 3-digits (SSS), followed by the day of the month (D), followed by a literal number (2), followed by the UTC timezone (Z). Removing the extra 3 decimals of precision does fix the problem:

> parseFormat('2018-06-01T18:13:03.909+00:00')
'YYYY-MM-DDTHH:mm:ss.SSSZ'

So this is clearly a bug in the underlying dependent library, which according to package.json is version 2.2.1 -- let's see if the new version 3.0.0 from 11 days ago has the same issue:

C:\NODE\node_red>npm install moment-parseformat@3
+ moment-parseformat@3.0.0
added 1 package and updated 1 package in 1.907s

C:\NODE\node_red>node
> var parseFormat = require('moment-parseformat')
> parseFormat('2018-06-01T18:13:03.909192+00:00')
'YYYY-MM-DDTHH:mm:ss.SSSD2Z'

Yep, no better -- time to open an issue against that library. As you are the one who found the bug, I'll leave that up to you. Good catch!
--Steve

@brmo
Copy link
Author

brmo commented Jun 1, 2018

Steve,

Thanks for that excellent diagnosis. I will get this issue created on the library.

--Brian

@TotallyInformation
Copy link
Owner

Guys, many thanks for sorting this without my input!! :) 💯

@chimpy
Copy link

chimpy commented Feb 27, 2019

This issue is going to come up again as the Home Assistant/Node Red combo becomes more and more popular I think.

I have a relative time moment node converting my timestamps to "fromNow". Mostly they work, occasionally they are in the future, and sometimes they are way too far in the past. Some examples:

"2019-02-27T11:02:04.709227+00:00" --> "2019-02-27T11:02:52.887109+00:00"
These dates were considered "5 days" apart.

"2019-02-27T11:04:23.209098+00:00" --> "2019-02-27T11:05:40.271300+00:00"
This was "in a month".

"2019-02-27T11:03:06.609682+00:00" --> "2019-02-27T11:03:09.012704+00:00"
This was correctly interpreted as "a few seconds ago".

I will strip the precision from the timestamp and hopefully the issue will be resolved.

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

4 participants