Can someone look at this - is there a problem with the `moment` node?

I was about to help someone and while writing a flow and using the moment node I noticed some weird happenings.

Here is a working version:

[{"id":"b036bcbd7e968d27","type":"function","z":"65c9b63cb09879a0","name":"","func":"msg1 = {};\nvar last = context.get(\"last\") || 0;\n//node.warn(\"Last \" + last);\n\nvar now = msg.payload;\n//node.warn(\"Now \" + now);\n\nvar diff = now - last;\n//node.warn(\"Diff \" + diff);\n\ncontext.set(\"last\",now);\nmsg.payload = diff;\nmsg1.payload = last;\nreturn [msg,msg1];","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1690,"y":440,"wires":[["854e8054259d8865"],["29f6c4455848f54b"]]},{"id":"5b1517de26decbd9","type":"inject","z":"65c9b63cb09879a0","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":1530,"y":440,"wires":[["b036bcbd7e968d27","2a950ded67900e92"]]},{"id":"854e8054259d8865","type":"moment","z":"65c9b63cb09879a0","name":"","topic":"","input":"payload","inputType":"msg","inTz":"Australia/Sydney","adjAmount":0,"adjType":"days","adjDir":"add","format":"mm:ss","locale":"en-AU","output":"payload","outputType":"msg","outTz":"Australia/Sydney","x":1870,"y":440,"wires":[["b20ec09a7b4ecb1e"]]},{"id":"29f6c4455848f54b","type":"moment","z":"65c9b63cb09879a0","name":"","topic":"","input":"","inputType":"msg","inTz":"Australia/Sydney","adjAmount":0,"adjType":"days","adjDir":"add","format":"HH:mm:ss","locale":"en-AU","output":"","outputType":"msg","outTz":"Australia/Sydney","x":1870,"y":530,"wires":[["b50cd4588cac6937"]]},{"id":"2a950ded67900e92","type":"moment","z":"65c9b63cb09879a0","name":"","topic":"","input":"","inputType":"msg","inTz":"Australia/Sydney","adjAmount":0,"adjType":"days","adjDir":"add","format":"HH:mm:ss","locale":"en-AU","output":"","outputType":"msg","outTz":"Australia/Sydney","x":1730,"y":350,"wires":[["56370474810d5420"]]},{"id":"b20ec09a7b4ecb1e","type":"debug","z":"65c9b63cb09879a0","name":"diff","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1890,"y":390,"wires":[]},{"id":"b50cd4588cac6937","type":"debug","z":"65c9b63cb09879a0","name":"last","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1890,"y":480,"wires":[]},{"id":"56370474810d5420","type":"debug","z":"65c9b63cb09879a0","name":"Time","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1900,"y":350,"wires":[]}]

I have extra things shown (available) to help me check it is/was working.

Within a second things seem to add up - but for the first time.

So, where's the problem?

The moment node going to the diff debug node.

It is set to show mm:ss Minutes and Seconds.

But!

If I make it HH:mm:ss it ALWAYS shows 10 hours!

Is that a bug?

When I add the HH I get the hours minutes and seconds.

What version of NR and what version of the moment node are you using (check it in the palette manager)

NR 2.0.1
Moment 4.0.0

So HH alone gives you hours, minutes and seconds?

I don't. All I get is the Hours...

Where are you?

I see the various timezones are set to Australia/Sydney, which is currently 10 hours ahead of UTC.

If I change them all to my timezone Europe/London, instead of 10 hours I get 1 hour. Clock time here is currently 1 hour ahead of UTC.

People keep reassuring me that "you dont have to worry about timezones, it just works" but my experience is it just doesn't.

1 Like

Yes, I am in Sydney.

Yikes! That is a problem.
Though I know GMT (Or ZULU) time is a standard.

But I am ... kind of lazy. I don't use it enough to look at that.
('T would be nice if the time zone was a drop down pick option)
What do I enter to make it ZULU?

No not alone but if I put just HH in, right now I get 08 (I’m on the east coast of the US)

I'm not exactly sold on that though.

This is the maths which determines the difference:

msg1 = {};
var last = context.get("last") || 0;
//node.warn("Last " + last);

var now = msg.payload;
//node.warn("Now " + now);

var diff = now - last;
//node.warn("Diff " + diff);

context.set("last",now);
msg.payload = diff;
msg1.payload = last;
return [msg,msg1];

(Yeah, with a bit of debugging output)

It is spitting out the correct value.

Ok, so the moment node gets that value (say only seconds passed)

It shouldn't (by my thinking) be adding 10 hours.

If that is true (correct) it makes living in any other time zone painful if doing time calculations.

So to clarify:
timestamp is ALWAYS ZULU time?
Which I can kind of understand.

But allowing time zones to tweak the value is confusing and can catch better people than I out, I am sure.

Sorry. I was not sure what you meant by you saying:

In retrospect - now - if I make it HH:mm:ss and take away 10 hours I get the right answer.

But to me that is confusing the situation.

Agreed.
I just posted if I subtract 10 hours in the moment node I get the right answer.

But I am thrown because it is including the timezone in something which is nothing to do with time zones.

It is "how long between these two time stamps".

If you look at the Help for the inject node it says

The default payload is a timestamp of the current time in millisecs since January 1st, 1970.

I don’t know if you know this, but if you click on the timestamp in the debug sidebar, it will rotate thre different formats of the timestamp

And again: I agree.

But that the moment node includes the time zone when the timezone isn't part of the equation is annoying.

I shall really have to write myself a big note about this if/when doing time calculations in the future that I need to -10 hours in the node.

(I am also confused: to whom do I give credit for solving this problem?)
I goofed by forgetting to include the TIMEZONE offset and subtract it.

Note to anyone reading this who has a similar problem:

If you are wanting TIME BETWEEN values, you MUST adjust the output by adding/subtracting the timezone value in the moment node, or you will be getting weird hour values returning.

I am lucky in that all my stuff is local and I am not exposing it to external places.

That scenario is (still) beyond my understanding of how to handle it.
And probably will be forever in a day.

To me that is/should be handled at a higher level.

But that would make it easier to fall off!!!

Sorry, that isn't helping.

I am guessing it is ironic (or sarcastic?).

I am wanting to get the difference between two time stamps sent into the function node - which it does quite happily.

It then displays the difference formatted as HH:mm:ss.
The fact I have to -10 hours to allow for my offset is confusing.

It caught me out. And probably not the first time. I'll admit that.
But I am (I really hope) that it won't catch me again.

Hang on.....

I'm now even more confused.

inject node....----> moment node.....--->debug node.

Nothing added.

Press the inject and I get/see the time.. ZULU TIME.
The input and OUTPUT timezones are set to Sydney.

So, if the TIMEZONE is set to SYDNEY: why am I getting ZULU time?
(Moving on)

If I change the output FORMAT to HH:mm:ss why does it suddenly change it to LOCAL TIME?

To me that is a big problem.
Could someone help me get my head around that?

FORMAT (to me) is nothing to do with time zone.

  1. If the input value is a timestamp then the node ignores the Input Timezone, since a timestamp is by definition UTC.
  2. If you don't specify a format then note that the format field shows the default which is 'ISO8601 (UTC)'. So you have specified there that you want the output in UTC, which implies that the Output Timezone is again ignored.

Because with that output format it is possible for it to apply the output timezone.

Much better is to always work internally in UTC, only converting to local time for display and user input. Then you don't need to make any adjustments when calculating time between.

You could always raise an issue with the author :wink:

Honestly, the moment node hasn't had much love recently as I'm focused on uibuilder and it needs rewriting anyway since momentjs is a dead project.

The moment node was designed to handle date/time formatting and timezone inputs/outputs. Anything else is icing on the cake. So yes, you should be paying attention to timezones.

And yes, if you don't live in Greenwich, London, you have a time problem :rofl:

Rule number 1 for computing and date/time computations is to keep all data in UTC and only use local time for user inputs and outputs. Any other approach WILL eventually bite you somewhere you don't want to be bitten. Date/Time calculations are hellishly complex and have dozens of edge-cases that few people know about. One of the things that I learned early on in my IT career (40+ years ago now!).

1 Like

I've still got to read Paul's reply.

AFAIK, that is exactly what I am/was doing.

Input a timestamp.
That goes into a function node that stores it. (First time)
Next time (or when a previous value is stored: Subtracts the two and gives the time between the messages.
That is then sent to the moment node to convert it to user friendly format.

But there is confusion that I have to -10 hours to offset the timezone.

If the code is ONLY on this machine: anyone from anywhere can read it and get the right answer (given I -10 hours).

But it makes the code not universal because if I give it to anyone in another timezone, they have to edit the value.