Calculate time difference

image
Hey, how can I calculate the difference between two time inputs. Thanks

It sort of depends on what style of time those nodes are outputting.

Irrespective of what you see, the nodes can output in a few different ways.
I'm hoping they are timestamp format. Then they are simply numbers.

How much have you used node-red?
How good are you with it? eg: Importing nodes
Do you mind using foreign (non-standard) nodes?

I am new to node red .. I didn't mean how timestamp format mean :sweat_smile:
I am looking for any kind of solution that allow me to calculate the difference between two times in the form (HH:MM). Thanks

No problems.

I just wanted to check what you were wanting to do.

Alas the easiest way is to put the times into a timestamp format. That is that they are magic numbers that can be used easily.

Alas this will need some foreign nodes to be used.

First off: Put a debug node on the output of one of the nodes and show what it gets when you press the button.

(If posting a screen shot, please crop so the debug output is the main part of the picture.)

(Sorry)

Although you are talking HH:MM stuff, it becomes difficult - not impossible - to calculate.
It depends on how you want to do it.

At the base level, there is a magic number for every millisecond since a specific date.
Somewhat overkill for what you are doing I know, but this is where I am going with why I am mentioning it.

When you use the node you used and enter the HH:MM values, the computer sees that very differently to how you see it.

I have tried to use that node for that thing and had no end of problems.

But the reasoning behind what I am saying is that rather than outputting some HH:MM format you output a very specific number which is for that which you input.

Then it is merely a task of taking one away from the other.

I tried to make an example flow but as said: I have had nothing but problems when I wanted to do just that.

So I can't help you much more than this.

(Sorry # 2)

I'll redact that which I just said. I'm used to 24 hour formats and the node wants this AM/PM malarkey.

From the node's notes:

The time input type returns a number of milliseconds from midnight.

So if you do something like this:

[{"id":"3d7fce2fd807c484","type":"ui_text_input","z":"3a01457a.3b59aa","name":"TIME INPUT","label":"Time input","tooltip":"","group":"5e4e9e67d081f578","order":3,"width":0,"height":0,"passthru":true,"mode":"time","delay":300,"topic":"topic","topicType":"msg","x":360,"y":1760,"wires":[["6f21d1adb67cb343"]]},{"id":"6f21d1adb67cb343","type":"debug","z":"3a01457a.3b59aa","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":560,"y":1760,"wires":[]},{"id":"5e4e9e67d081f578","type":"ui_group","name":"group2","tab":"9e1ed5e519ff655f","order":2,"disp":true,"width":"6","collapse":true},{"id":"9e1ed5e519ff655f","type":"ui_tab","name":"TEST","icon":"dashboard","order":39,"disabled":false,"hidden":false}]

And enter as shown:

Screenshot from 2022-05-20 09-38-38

(the need to put the am had me really stumped.)

You will get this in the debug node.

So you have your two nodes where you enter the time (don't forget the AM/PM bit)
and you then have 2 values you can manipulate.

More on that when you are at this stage.

Oh, very important question: Are these both in the same day?

Here is a very good write up with some of the background information from one of our regulars !

Craig

Try this -

[{"id":"52d808ed7ae6c2d4","type":"ui_text_input","z":"c01a7b7726485741","name":"","label":"start","tooltip":"","group":"365f6b900be3a1a6","order":7,"width":0,"height":0,"passthru":false,"mode":"time","delay":"0","topic":"start","sendOnBlur":false,"className":"","topicType":"str","x":550,"y":260,"wires":[["2f94d0d4f3a0ddeb"]]},{"id":"0d44203a93b85f91","type":"ui_text_input","z":"c01a7b7726485741","name":"","label":"end","tooltip":"","group":"365f6b900be3a1a6","order":6,"width":0,"height":0,"passthru":false,"mode":"time","delay":"0","topic":"end","sendOnBlur":false,"className":"","topicType":"str","x":550,"y":300,"wires":[["2f94d0d4f3a0ddeb"]]},{"id":"2f94d0d4f3a0ddeb","type":"join","z":"c01a7b7726485741","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":710,"y":280,"wires":[["51617b33891cc989"]]},{"id":"042f179a09985d49","type":"ui_text","z":"c01a7b7726485741","group":"365f6b900be3a1a6","order":8,"width":0,"height":0,"name":"","label":"difference","format":"{{msg.payload}}","layout":"row-spread","className":"","x":980,"y":280,"wires":[]},{"id":"51617b33891cc989","type":"function","z":"c01a7b7726485741","name":"","func":"let date = new Date(msg.payload.end - msg.payload.start)\nlet hours = date.getUTCHours();\nlet minutes = \"0\" + date.getUTCMinutes();\nlet seconds = \"0\" + date.getUTCSeconds();\nmsg.payload = hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);\nmsg.topic=\"difference\"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":280,"wires":[["042f179a09985d49"]]},{"id":"365f6b900be3a1a6","type":"ui_group","name":"Group","tab":"dc50fb1.77df988","order":null,"disp":true,"width":6},{"id":"dc50fb1.77df988","type":"ui_tab","name":"Home Page","icon":"","order":1,"disabled":false,"hidden":false}]

Thank u for your help. I appreciate it. I get to what exactly I want . Thank u for saving me :sweat_smile:

Thank u for ur help.

Excuse me, but what if I want to display it with HH:MM form. Meaning, transform that time in HH:MM form that make the difference. Is there any other solutions?

May you find my flow with change nodes and moments library useful:

[
    {
        "id": "c38cc5bf.7f7f38",
        "type": "inject",
        "z": "6e170384.60c96c",
        "name": "jetzt + 8 Tagen + 3 Stunden + 47 Minuten +28 Sekunden",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "x",
                "v": "{\"days\":8,\"hours\":3,\"minutes\":47,\"seconds\":28}",
                "vt": "json"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 1090,
        "y": 3040,
        "wires": [
            [
                "f6e8d65f.929de8"
            ]
        ]
    },
    {
        "id": "f6e8d65f.929de8",
        "type": "change",
        "z": "6e170384.60c96c",
        "name": "timeA = payload; timeB =payload +x; diff timeB-timeA",
        "rules": [
            {
                "t": "set",
                "p": "timeA",
                "pt": "msg",
                "to": "$moment(payload,['DD.MM.YYYY HH:mm:ss','x'],'de').format('DD.MM.YYYY HH:mm:ss')",
                "tot": "jsonata"
            },
            {
                "t": "set",
                "p": "timeB",
                "pt": "msg",
                "to": "(\t    $x := x;\t    $moment(payload,['DD.MM.YYYY HH:mm:ss','x'],'de').add($x).format('DD.MM.YYYY HH:mm:ss');\t    )",
                "tot": "jsonata"
            },
            {
                "t": "delete",
                "p": "x",
                "pt": "msg"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "(\t    $b := $moment(timeB,['DD.MM.YYYY HH:mm:ss','x'],'de');\t    $a := $moment(timeA,['DD.MM.YYYY HH:mm:ss','x'],'de');\t    \t    /* $b.diff($a) */\t    /* $moment.duration($b.diff($a)); */\t    \t        /* Kein Zugriff auf duration  - also manuell berechnen*/\t        \t    $days := $b.diff($a, 'days');\t    $hours := $b.diff($a, 'hours') - 24 * $b.diff($a, 'days');\t    $minutes := $b.diff($a, 'minutes') - 60 * $b.diff($a, 'hours');\t    $seconds := $b.diff($a, 'seconds') - 60 * $b.diff($a, 'minutes');\t    \t    $sec := $b.diff($a)/1000;\t    \t\t    \t    $difference := {\t        \"days\": $days,\t        \"hours\":$hours,\t        \"minutes\": $minutes,\t        \"seconds\": $seconds\t    }; \t    \t\t)",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1540,
        "y": 3040,
        "wires": [
            [
                "fb984b77.f03568"
            ]
        ],
        "info": "akzeptiert Datumsformate ('DD.MM.YYYY HH:mm:ss') oder timestamps('x')"
    },
    {
        "id": "fb984b77.f03568",
        "type": "debug",
        "z": "6e170384.60c96c",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1830,
        "y": 3040,
        "wires": []
    }
]

It depends. It can be whether in the same day or not

The general method I use when calculating time differences (in almost any programming language):

  1. convert each time into epoch time (the number of seconds which has elapsed since 00:00:00 UTC on 1 January 1970)
  2. subtract one from the other
  3. and the absolute value of that answer is the time difference in seconds

Then convert the answer from step 3 to whatever format you need. This page should have all of the functions you will need to convert to and from different formats in JavaScript.

The reason I like this is it lets me compare decimal numbers. For example:

  • Comparing "April" with "May" requires a lookup table.
  • 1 am is later than 12 am, even though 12 is a larger number. But 2 am is later than 1 am.

Most date libraries handle all of that for you, and that's fine. But if you need to do any manual comparisons, you can make simple mistakes very easily with most date and time formats. In epoch time, those mistakes are rare because a later time is always a larger number.

Notes:

  1. It is important to ensure the times are either in the same time zone, or to convert them to the same time zone prior to converting to epoch time.
  2. This applies to the international date line as well.
  3. If the first timestamp and second timestamp have a daylight savings time change between them (e.g. January and June), that change must be accounted for.

Relevant XKCD.