Subtraction of two strings

Found my own bug. Try either of the two statements below instead …

Q: (((it /60) as string & " hour" & (if ((it/60) > 1) then ("s ") else (" ")) & (if ((it mod 60) > 0) THEN ((it mod 60) as string & " minute" & (if ((it mod 60) > 1) then ("s") else (""))) ELSE (""))) of ((((substring (0,2) of it) as Integer * 60 + ((substring (2,2) of it) as Integer)) of (value "WindowEnd" of key "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registry as string)) as integer - (((substring (0,2) of it) as Integer * 60 + ((substring (2,2) of it) as Integer)) of (value "WindowStart" of key "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registry as string)) as integer))
A: 3 hours 10 minutes
T: 0.286 ms

or

Q: (((IF (it > 60) THEN ((it /60) as string & " hour" & (if ((it/60) > 1) then ("s ") else (" "))) ELSE ("")) & (if ((it mod 60) > 0) THEN ((it mod 60) as string & " minute" & (if ((it mod 60) > 1) then ("s") else (""))) ELSE (""))) of ((((substring (0,2) of it) as Integer * 60 + ((substring (2,2) of it) as Integer)) of (value "WindowEnd" of key "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registry as string)) as integer - (((substring (0,2) of it) as Integer * 60 + ((substring (2,2) of it) as Integer)) of (value "WindowStart" of key "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registry as string)) as integer))
A: 3 hours 10 minutes
T: 0.312 ms
1 Like

:slight_smile: trying to check again.

Working . Thanks a lot.

Hi Tim,

Q: (((it /60) as string & " hour" & (if ((it/60) > 1) then (“s “) else (” “)) & (if ((it mod 60) > 0) THEN ((it mod 60) as string & " minute” & (if ((it mod 60) > 1) then (“s”) else (”"))) ELSE (""))) of ((((substring (0,2) of it) as Integer * 60 + ((substring (2,2) of it) as Integer)) of (value “WindowEnd” of key “HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot” of native registry as string)) as integer - (((substring (0,2) of it) as Integer * 60 + ((substring (2,2) of it) as Integer)) of (value “WindowStart” of key “HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot” of native registry as string)) as integer))
A: 0 hour 30 minutes
T: 990

I am there in situation to provide the input value as hhmm method and also I don’t want hour & minutes statement while returning the answer.

I have changed as follows and tried .

Q: (((it /60) as string & “” & (if ((it/60) > 1) then (“s “) else (” “)) & (if ((it mod 60) > 0) THEN ((it mod 60) as string & “” & (if ((it mod 60) > 1) then (“s”) else (””))) ELSE (""))) of ((((substring (0,2) of it) as Integer * 60 + ((substring (2,2) of it) as Integer)) of (value “WindowEnd” of key “HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot” of native registry as string)) as integer - (((substring (0,2) of it) as Integer * 60 + ((substring (2,2) of it) as Integer)) of (value “WindowStart” of key “HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot” of native registry as string)) as integer))
A: 0 30s
T: 941

Instead of 0 30s , I need output as 0030.

something I written as follows now .

last 4 of (“0000” & ((it / 60) as string & last 2 of (“00” & ((it mod 60) as string))) of ((((substring (0,2) of it) as Integer * 60 + ((substring (2,2) of it) as Integer)) of (value “WindowEnd” of key “HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot” of native registry as string)) as integer - (((substring (0,2) of it) as Integer * 60 + ((substring (2,2) of it) as Integer)) of (value “WindowStart” of key “HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot” of native registry as string)) as integer))

yet to test . May be , I need various testing. Let me know your input . Thanks.

I got another challenge

Q: last 4 of (“0000” & ((it / 60) as string & last 2 of (“00” & ((it mod 60) as string))) of ((((substring (0,2) of it) as Integer * 60 + ((substring (2,2) of it) as Integer)) of (value “WindowEnd” of key “HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot” of native registry as string)) as integer - (((substring (0,2) of it) as Integer * 60 + ((substring (2,2) of it) as Integer)) of (value “WindowStart” of key “HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot” of native registry as string)) as integer))
A: 0130
T: 669

Here 01 is Hour and 30 is minutes .

This above values , I am passing to another tool as input.

However that tool is not able to understand hour input . It expecting me to convert all the values in minutes format.

meaning instead of 1 hour 30 mins , I need 90 minutes in total.

How we can plan now ? any idea ?

So you want the output to be returned as just the number of Minutes between the Start and End times?

Yes Tim. I want to calculate only minutes . The another tool not able to understand hours basically .

OK, Last one. I have to get work done for MY employer now! :grinning:

Q: (((((((substring (0,2) of (value "WindowEnd" of it as string)) as Integer) * 60) + ((substring (2,2) of (Value "WindowEnd" of it as string)) as Integer)) of key "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registry as string)) as Integer) - (((((((substring (0,2) of (value "WindowStart" of it as string)) as Integer) * 60) + ((substring (2,2) of (Value "WindowStart" of it as string)) as Integer)) of key "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registry as string)) as Integer)
A: 90
T: 0.371 ms
2 Likes

Oh. Congrats. Let me test the code Tim

Working as expected now . Thanks a lot for your support Tim.

I like your method. Another might be to convert into time interval objects:

q: (it/minute) of ((first 2 of it as integer * hour + last 2 of it as integer * minute) of (value "WindowEnd" of it as string) - (first 2 of it as integer * hour + last 2 of it as integer * minute) of (value "WindowStart" of it as string)) of  key "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registry 
A: 90

Essentially I converted the times into “Minutes since Midnight” and performing the requisite math to get the delta.

The method I used breaks if the time window spans midnight, but from the way the original question was posed, it didn’t seem like that was a big risk at the time.

1 Like

Spanning midnight… nice edge case! You got me going now. I think the edge case prefers an if/then/else to subtract 1 day from the start time if the start time is after the end time.

q:  (if item 0 of it <= item 1 of it then (item 1 of it - item 0 of it) else (item 1 of it - (item 0 of it - day))) of (((first 2 of it as integer * hour + last 2 of it as integer * minute) of (value "WindowStart" of it as string)),((first 2 of it as integer * hour + last 2 of it as integer * minute) of (value "WindowEnd" of it as string))) of  key "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registry

Thanks Brolly. I got a new challenge again .

The user ( server owner ) suppose to update in the following format of WindowStart time in HH:MM format . That is 0800. See below.

G1

But some users, not updating the same way :slight_smile:

they are also updating in the following way . Meaning , in HH:MM format , they use normal format as H:MM method . Basically they are missing 0. See below.

G2

tried to pass one 0 as dummy value. But failing to work . How we can address this ?

Try padding the string like this:

if (length of it = 4) then (it) else (last 4 of "0000"&it)

q:  (if item 0 of it <= item 1 of it then (item 1 of it - item 0 of it) else (item 1 of it - (item 0 of it - day))) of (((first 2 of it as integer * hour + last 2 of it as integer * minute) of ((if (length of it = 4) then (it) else (last 4 of "0000"&it)) of (value "WindowStart" of it as string))),((first 2 of it as integer * hour + last 2 of it as integer * minute) of ((if (length of it = 4) then (it) else (last 4 of "0000"&it)) of (value "WindowEnd" of it as string)))) of  key "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registry
A: 23:59:00

Thanks for your response Brolly. But here I am getting different stuff . Example as follows .

Here the reboot length is 1 hour and 30 mins . See below pic for your reference .

br1

So it has to return the result as 90 mins ( I need results only in mints)

See the QNA result

Q: (if item 0 of it <= item 1 of it then (item 1 of it - item 0 of it) else (item 1 of it - (item 0 of it - day))) of (((first 2 of it as integer * hour + last 2 of it as integer * minute) of ((if (length of it = 4) then (it) else (last 4 of “0000”&it)) of (value “WindowStart” of it as string))),((first 2 of it as integer * hour + last 2 of it as integer * minute) of ((if (length of it = 4) then (it) else (last 4 of “0000”&it)) of (value “WindowEnd” of it as string)))) of key “HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot” of native registry
A: 00:30:00
T: 2003

Q:

I changed bit in order to print only mints value as follows .

(if item 0 of it <= item 1 of it then (item 1 of it - item 0 of it) else (item 1 of it - (item 0 of it - day))) of (((first 2 of it as integer + last 2 of it as integer) of ((if (length of it = 4) then (it) else (last 4 of “0000”&it)) of (value “WindowStart” of it as string))),((first 2 of it as integer + last 2 of it as integer) of ((if (length of it = 4) then (it) else (last 4 of “0000”&it)) of (value “WindowEnd” of it as string)))) of key “HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot” of native registry
A: 30
T: 1633

Need your assistance to fix this . Thanks .

Order of operations tripped me up.

q: last 4 of ("0000"&"900")
A: 0900
I: singular substring

q: last 4 of "0000"&"900"
A: 0000900
I: singular string

Just need some parenthesis in there…

q:  (if item 0 of it <= item 1 of it then (item 1 of it - item 0 of it) else (item 1 of it - (item 0 of it - day))) of (((first 2 of it as integer * hour + last 2 of it as integer * minute) of ((if (length of it = 4) then (it) else (last 4 of ("0000"&it))) of (value "WindowStart" of it as string))),((first 2 of it as integer * hour + last 2 of it as integer * minute) of ((if (length of it = 4) then (it) else (last 4 of ("0000"&it))) of (value "WindowEnd" of it as string)))) of  key "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registry
A: 01:30:00

Thanks for your support Brolly.

When I test , I got it as follows . ( I have removed hours & min in order to get the result only as min. Seems, some calculation error coming) Something is messup here . Not able to narrow down .

Q: (if item 0 of it <= item 1 of it then (item 1 of it - item 0 of it) else (item 1 of it - (item 0 of it - day))) of (((first 2 of it as integer + last 2 of it as integer) of ((if (length of it = 4) then (it) else (last 4 of (“0000”&it))) of (value “WindowStart” of it as string))),((first 2 of it as integer + last 2 of it as integer) of ((if (length of it = 4) then (it) else (last 4 of (“0000”&it))) of (value “WindowEnd” of it as string)))) of key “HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot” of native registry
A: 31
T: 4797

Q:

Converting back to Minutes needs to happen outside…

q:  ((if item 0 of it <= item 1 of it then (item 1 of it - item 0 of it) else (item 1 of it - (item 0 of it - day))) of (((first 2 of it as integer * hour + last 2 of it as integer * minute) of ((if (length of it = 4) then (it) else (last 4 of ("0000"&it))) of (value "WindowStart" of it as string))),((first 2 of it as integer * hour + last 2 of it as integer * minute) of ((if (length of it = 4) then (it) else (last 4 of ("0000"&it))) of (value "WindowEnd" of it as string)))) of  key "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registry) / minute
A: 90

This check isn’t needed if you force it to have more characters, then take last 4:

(last 4 of ("0000" & item 0 of it), last 4 of ("0000" & item 1 of it)) of ( ("800", "930"); ("1430", "1500") )

This is adapted from @brolly33 's answer, but keeping more right to left relevance, slightly more plurals, and simplified IF/THEN/ELSE:

(if it < 0 * minute then it + 1 * day else it) of (item 1 of it - item 0 of it) of ( ( (it as integer * hour) of first 2 of it + (it as integer * minute) of last 2 of it ) of lasts 4 of ("0000" & item 0 of it), ( (it as integer * hour) of first 2 of it + (it as integer * minute) of last 2 of it ) of lasts 4 of ("0000" & item 1 of it)) of ( ("800", "930"); ("1430", "1500"); ("2300", "0100") )

Then, using this to get the raw data from the registry: (this part could be swapped out for session relevance to read client properties with the same values in a web report or dashboard)

((it as string) of values "WindowStart" of it, (it as string) of values "WindowEnd" of it) of keys "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registries

That then should be:

(if it < 0 * minute then it + 1 * day else it) of (item 1 of it - item 0 of it) of ( ( (it as integer * hour) of first 2 of it + (it as integer * minute) of last 2 of it ) of lasts 4 of ("0000" & item 0 of it), ( (it as integer * hour) of first 2 of it + (it as integer * minute) of last 2 of it ) of lasts 4 of ("0000" & item 1 of it)) of ((it as string) of values "WindowStart" of it, (it as string) of values "WindowEnd" of it) of keys "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registries

Then to convert into minutes, just add (it / minute) of to it:

(it / minute) of (if it < 0 * minute then it + 1 * day else it) of (item 1 of it - item 0 of it) of ( ( (it as integer * hour) of first 2 of it + (it as integer * minute) of last 2 of it ) of lasts 4 of ("0000" & item 0 of it), ( (it as integer * hour) of first 2 of it + (it as integer * minute) of last 2 of it ) of lasts 4 of ("0000" & item 1 of it)) of ((it as string) of values "WindowStart" of it, (it as string) of values "WindowEnd" of it) of keys "HKEY_LOCAL_MACHINE\SOFTWARE\CRQ\Maintenance\Reboot" of native registries

The advantage to structuring the relevance this way is that you can actually use this as session relevance if you have client properties that report the start and end and swap that out for reading from the registry. Plus you can switch between reporting the values as minutes or as duration just by adding or removing (it/minute) of from the front.

In the case of a web report, you might even want to display both the duration as hours:minutes as well as duration in minutes, with the addition of (it, it/minute) of

(it, it / minute) of (if it < 0 * minute then it + 1 * day else it) of (item 1 of it - item 0 of it) of ( ( (it as integer * hour) of first 2 of it + (it as integer * minute) of last 2 of it ) of lasts 4 of ("0000" & item 0 of it), ( (it as integer * hour) of first 2 of it + (it as integer * minute) of last 2 of it ) of lasts 4 of ("0000" & item 1 of it)) of ( ("800", "930"); ("1430", "1500"); ("2300", "0100") )

There is really 3 parts to this kind of relevance: first, to read the raw data, second, to parse it, third, to display it in a final form. Ideally you can swap out any of these parts separately from the others in order to read the same data from a different source (cross platform, or session relevance, or hard coded test values) or to parse the same data differently, or to display it differently. If the relevance is structured the way I have done it, then the reading of the raw data is always on the right side, the parsing in the middle, and the changing the values for display(or use) on the left (turning duration into minutes). This is a (complicated) example of why I recommend that relevance always flow from right to left.

Also, these 2 relevances are equivalent:

  • ( it whose(it > 0 * minute) | (it + 1 * day) ) of
  • (if it < 0 * minute then it + 1 * day else it) of

For no real reason, this relevance will take a start time and a duration and return an end time:

(it whose(it < 1*day) | (it - 1*day) ) of ( item 1 of it as integer * minute + ( (it as integer * hour) of first 2 of it + (it as integer * minute) of last 2 of it ) of last 4 of ("0000" & item 0 of it) ) of ( ("800", "30") ; ("2300", "90") )