Putting timer results into a variable...

#1
First, please excuse me if there is another, better, way to do this and I don't know what that is, but I often have the situation where I want to time something but I want to substantially reformat in some way the result(s) of executing the "Timer" command(s), i.e. putting the result(s) of the "Timer" command(s) into variables.

Well the first and most obvious solution is to do this:
Code:
Set StartTime=%@ExecStr[Timer On /1]
Delay 10
Set EndTime=%@ExecStr[Timer Off /1]
@Echo Start Time: %StartTime
@Echo  End Time: %EndTime
Well this really doesn't work at all. The results of doing the above are:
Code:
Start Time: Timer 1 on: 15:37:30
  End Time: Timer 1 off: 15:37:40
There is obviously no elapsed time at all (although you could figure it out) and I would assume that this is because the timer wasn't "on" when it was turned "off". (I assume that this is because the "Timer" command(s) are being executed in "sub shell(s)").

Well here is a quite easy way that actually works:
Code:
Do Result In /P (Timer On /1) (
  Set StartTime=%@Right[-12,%Result]
)
Delay 10
Do Result In /P (Timer Off /1) (
  Set EndTime=%@Right[-13,%Result]
)
@Echo Start Time: %StartTime
@Echo  End Time: %EndTime
Which produces:
Code:
Start Time: 15:37:40
  End Time: 15:37:50  Elapsed: 0:00:10.21
What you would hope for/expect.
 
#3
Steve, for my purposes "@Timer" (which I had forgotten about) is, as they say, close but no cigar.;) Just because you might not want me to be mysterious here, this is because I basically want exactly the results of the "Timer" command(s) and not do any arithmetic on them, just reformat them quite a bit. I'm a bit obsessive, I suppose, about exactly how I want things to be formatted. And what you suggest is very good to know if I ever actually do want to do arithmetic on them, assuming that I will remember it, of course!
 
#4
Dan, one problem with your solution is that it is dependent on TCC version. It depends on the exact format of the report, which is UNDOCUMENTED - it may change from one build to the next! Unlikely Rex would make such a change, but possible. Another is if the timed interval crosses local midnight - end time could be displayed as earlier than the start time. Saving the _datetime internal variable (which is guaranteed to be consistent) before you start, and when you finish, and the value of @TIMER[], while more elaborate, makes you dependent not on TCC version, just on the documented values of internal variables and functions. Come to think of it, even two _datetime's can give you "reversed times" if they happen to straddle the end of daylight saving time, and an extra hour between start and end instances, if they straddle the start of daylight time. If you never work at those times of day, this is irrelevant...
 
Jan 19, 2011
581
10
Norman, OK
#5
I'm getting different results. I am showing an elapsed time, but it's zero.

Code:
[C:\temp]
09:26:59 $ ver /r
 
TCC  13.04.57   Windows XP [Version 5.1.2600]
TCC Build 57   Windows XP Build 2600  Service Pack 3
Registered to 
 
[C:\temp]
09:27:10 $ timer on /1 %& delay 5 %& timer off /1
Timer 1 on: 09:27:22
Timer 1 off: 09:27:27  Elapsed: 0:00:05.00
 
[C:\temp]
09:27:27 $ type timertest.btm
@echo off
set starttime=%@execstr[timer on /1]
echo %starttime
Delay 5
set endtime=%@execstr[timer off /1]
echo %endtime
 
[C:\temp]
09:27:35 $ timertest.btm
Timer 1 on: 09:27:41
Timer 1 off: 09:27:46  Elapsed: 0:00:00.00
 
#6
John:
As Dan reported in the OP (see short paragraph after 2nd code section) the timer which is run by @EXECSTR is in a temporary process, so the "timer off" command stops a timer which was never started. Naturally it reports 0s elapsed time. That's why he went to the elaborate method of using the /P option of DO to start and stop the timer; apparently it runs in the primary process, at least in the TCC version in which Dan tested it (not documented, hence not guaranteed for future versions or even builds).
 
#8
Steve, there would be some truth to what you say for me if I was doing anything more than reformatting the result(s) of the "Timer" command(s) in exactly the way(s) I went them formatted, and I am not. Not only that, I've got very simple (and in the environment) built-in functions that I wrote (and could be easily changed if the exact format of the results returned by the "Timer" commands changed, which I think is rather unlikely, anyway) in "extracting" the different time fields (start and end times, elapsed time if relevant) from those commands. And finally, Steve, it is your code that could have a problem with crossing midnight and daylight saving time although that is very unlikely; whereas mine could not (depending on the exact implementation of the "Timer Off" command, at least; but if there is an issue there, which I highly doubt, it is Rex's "issue" and not mine). That is simply because the "@Timer" function only returns the elapsed time and not the end time, and one would have to either do time arithmetic (a bit of a pain - could certainly be possible and not too difficult using the "age" functions if I knew the exact format of "ages" and I do not) or separately query the value of the "%_Time" variable at the same time as getting the value of "@Timer" function. That probably is a somewhat easier solution than mine, and honestly, at this point I would recommend your solution for new code rather than my solution negating my suggestion (because the time difference is very unlikely to be inconsistent with the elapsed time reported by "@Timer") but my code is very simple "boilerplate" code (the Do's can be implemented in a single line which I do; the multi-line version I posted was just to make the whole thing a little bit more readable in my opinion) that I've been using for quite a long time (couldn't tell you exactly how long, however - bad memory) and does work perfectly for my needs (although, in the future, I may consider your solution if I remember to :)). However, I'm not going to bother to go through and change existing code because there is absolutely no need to.

- Dan
 
#9
Steve, I'm putting this in a separate posting because even for me the whole point of this got lost in the shuffle, as the saying goes. My suggestion really had nothing at all to do with re-formatting (although that is certainly possible, of course), it was simply a demonstration of how to put these thing(s) into variable(s) so that they can then be displayed at later times, such as the bottom of the "report" as "summary" information, for instance. And yes, your solution would allow that and it wouldn't be all that difficult to implement (although you would have to use two separate variables to store the current values of "%_Time" and "@Time" or combine them into one variable formatted as you like), but my solution also allows that (of course), and it isn't really all that difficult, either.

- Dan
 
#10
Dan:
In answer to the earlier of your responses to my post:
- AGE is a simple 64-bit integer, the number of 100ns clockticks since 1601-01-01 @ 00:00:00 GMT (Gregorian calendar; at age=0 most countries of the world were still on the Julian calendar, including Great Britain and her colonies throughout the world) to the event of interest, e.g., last modification of a file.
- Indeed it is possible for the timer to be read (at the end of the event being measured) using @TIMER just before midnight, but get the date and time of the endpoint just after midnight. But if you always display both the date and the time of the start and end points, that will be clear, and the elapsed time would always be measured using @TIMER, which has 10ms resolution, rather than by a difference in clock times, which have only 1s = 1000ms resolution. It would not be relevant. @TIMER and _DATETIME report different quantities. To be sure there is no misunderstanding, the results should always include the value of _tzn at the start and end points of the timer run, at least if they are not the same.
- remember that the process to be measured may take more than a day, so just reporting times of day without date is limiting. Of course, you may not be interested in measuring such long events or those that take place in the middle of the night, the events for which date and DST status could be relevant.
 
#11
Steve, I agree with you (as much as I fully understand you ;) - there's really no point in me trying to "stretch my brain" to "deeply" think about it), but as I've said what I have works; and longer than a day would never really be an issue (and in the very unlikely event that was the case I would have a very good idea as to how many days it took), and finally and again, I trust Rex's results to be accurate disregarding the number of days issue (since I have never timed anything that lasted anything more than a day I don't really know if and how Rex's code handles it; it very well might handle it and I wouldn't be at all surprised if it did given the quality of Rex's code).

And I sincerely thank you for telling me exactly what an "age" is; I couldn't find anything in the docs that really said what it was (just out of curiosity, where did you find it?). But given what it actually is, I really doubt if I would want to write the code to parse it myself in almost any circumstances. (And, as humorous (at least to me) aside, because of the almost total absence of limits to numerical values and precision in Rex's code, the very concept of a "64-bit integer" is quite foreign in these circumstances and it makes me laugh - I'm smiling as I type this.)
 
#12
Dan:
Up through TCC 9 the HELP contained a section called GLOSSARY, and it was documented there from V6 through V9. Incidentally, the age can be in local time or in UTC, the 0 instant is based accordingly. However, NTFS saves file timestamps internally as UTC ages. As to the 64b integer, that's how NTFS stores the information in the file control block. Once you retrieve it TCC manipulates it differently, but to force an age it must fit into a 64b integer; I do not recall whether it's signed or unsigned. If you do not have access to the V9 version of tcmd.chm, you can download the V9 installer from (IIRC) ftp.jpsoft.com/oldver/ and extract it.
 
#13
Steve,

Thank you again. Of course the 64 bits is because of the way it is stored in the NTFS file system (I'm not at all immune to stupidity at this point in my life if I ever was! :)). It's not important enough (particularly since you've given the simple and rather obviously correct in hindsight answer) to take the time to go and retrieve old documentation...

- Dan