Question was interesting so I wrote batch that can do job for you.
Basically it is countdown timer, i did not include shutdown
command to this but leaved it as homework. Calculations is not accurate, this does not care about leap years, length of month, ... this is mainly for readability as I wanted to keep it easy to learn.
There is currently two files doing job together, one starts timer and other, when called, tells how much time elapsed from timer start. These two files can fairly easily combined into one cmd script, this way you can make some lines reusable (like defined methods) too.
Okay, let's take a look at scripts,
Here is StartTimer.cmd
:
@ECHO OFF
FOR /F "skip=1 tokens=1-6" %%a IN ('wmic Path Win32_Localtime GET year^,month^,day^,hour^,minute^,second /format:TABLE ^| findstr /r "."') DO (
SET DateD=%%a
SET TimeH=%%b
SET TimeM=%%c
SET DateM=%%d
SET TimeS=%%e
SET DateY=%%f
)
SET /A EPOCH=((%DateY%-1970)*365*24*60*60)+(%DateM%*30*24*60*60)+(%DateD%*24*60*60)+(%TimeH%*60*60)+(%TimeM%*60)+%TimeS%
ECHO %EPOCH% > Timer.start.state
In line starting with FOR /F "skip=1 ...
:
1. Ask wmic
for current time and date.
2. Skip first line of output, which is headings, by skip=1
3. Read values using tokens=1-6
meaning %%a-%%f
separated by Spaceor
TAB.
4. Store values to variables %DateY%
, ... %TimeH%
, %TimeM%
, ...
After that at line starting SET /A EPOCH=...
we use expression that calculates seconds elapsed from 1.1.1970
(this is simple approximate, not real unix time. See Google if you need accurate).
Then at last line ECHO %EPOCH% > ...
writes calculated time to file called "Timer.start.state
".
And here GetTimerValue.cmd
:
@ECHO OFF
GOTO CHECKFILE
:TIMEOUT
FOR /F "skip=1 tokens=1-6" %%a IN ('wmic Path Win32_Localtime GET year^,month^,day^,hour^,minute^,second /format:TABLE ^| findstr /r "."') DO (
SET DateD=%%a
SET TimeH=%%b
SET TimeM=%%c
SET DateM=%%d
SET TimeS=%%e
SET DateY=%%f
)
SET /P Timer=<"Timer.start.state"
SET /A EPOCH=((%DateY%-1970)*365*24*60*60)+(%DateM%*30*24*60*60)+(%DateD%*24*60*60)+(%TimeH%*60*60)+(%TimeM%*60)+%TimeS%
SET /A Elapsed=%EPOCH%-%Timer%
ECHO "Seconds since timer started: %Elapsed%"
GOTO EOF
:CHECKFILE
IF EXIST "Timer.start.state" (
GOTO TIMEOUT
) ELSE (
ECHO "Timer not started. Start timer by running Timer.cmd"
)
:EOF
Here code flow is not linear from top to bottom. First we GOTO CHECKFILE
label so execution commands really starts at line that says :CHECKFILE
.
Many things here is just same as with StartTimer.cmd
so I only explain new or changed lines.
First we check if state file Timer.start.state
exists, if not then terminate wit message. If timer started and files exists then we continue and do some math:
1. Jump to :TIMEOUT
where we output elapsed seconds. You can choose better label for that...
2. SET /P %Timer% ...
reads start time from file and assign value to %Timer%
variable.
3. SET /A Elapsed ...
calculates seconds between start time and now.
4. ECHO "Seconds ...
echoes out calculated value (seconds since timer startup.
How to get remaining time:
You can substract %Elapsed%
from %MaxTime%
:
@ECHO OFF
GetTimerValue
SET /A TimeLeft=%MaxTime%-%Elapsed%
ECHO "You have %TimeLeft% seconds remaining"
OK, explained enough. Here is full script Timer.cmd
:
At this point, forgot everything already said. This batch file here is working on it's own so there is no separate StartTimer.cmd
or GetTimerValue.cmd
but only this Timer.cmd
. Basically it is still same but code flow is different and usage is also completely different. This however does not save state to file so you cant anymore get timer value after logoff/reboot, if you need this use example above to save/read state to/from file.
Usage/help for Timer.cmd
is printed when run without arguments. I have not fully tested this and there may be some typos etc., args are not foolproof checked.
@ECHO OFF
GOTO TimerUser%1
:: ===================================
:: Operation is start, (re)start timer
:: ===================================
:TimerUserstart
ECHO %2 | FINDSTR /R "^[1-9]"
IF %ERRORLEVEL%==0 (
SET Timer.max=%2
GOTO TimerStart
) ELSE (
ECHO.
ECHO !! ERROR !!
ECHO You must specify maximum value.
ECHO ===============================
GOTO TimerUser
)
:: =============================================
:: Operation is get, get values if timer running
:: =============================================
:TimerUserget
IF DEFINED Timer.start.state (
GOTO TIMEOUT
) ELSE (
ECHO.
ECHO !! ERROR !!
ECHO Timer is not started, start timer first.
ECHO ========================================
GOTO TimerUser
)
:: ============
:: Usage / Help
:: ============
:TimerUser
ECHO.
ECHO Timer.cmd Usage: Timer.cmd operation [options]
ECHO.
ECHO - Operations
ECHO start Start new timer, n must be specified.
ECHO get Get current value of started timer.
ECHO.
ECHO - Options:
ECHO n Max value in seconds, used to calculate remaining time.
ECHO.
GOTO EOF
:: =============================
:: Update %Timer.epoch% variable
:: =============================
:TimerUpdateEpoch
FOR /F "skip=1 tokens=1-6" %%a IN ('wmic Path Win32_Localtime GET year^,month^,day^,hour^,minute^,second /format:TABLE ^| findstr /r "."') DO (
SET DateD=%%a
SET TimeH=%%b
SET TimeM=%%c
SET DateM=%%d
SET TimeS=%%e
SET DateY=%%f
)
SET /A Timer.epoch=((%DateY%-1970)*365*24*60*60)+(%DateM%*30*24*60*60)+(%DateD%*24*60*60)+(%TimeH%*60*60)+(%TimeM%*60)+%TimeS%
GOTO %Timer.Callback%
:: ===========================================
:: Start new timer destoying/resetting old one
:: ===========================================
:TimerStart
SET Timer.Callback=TimerStartC1
GOTO TimerUpdateEpoch
:TimerStartC1
SET Timer.start.state=%Timer.epoch%
GOTO EOF
:: =============================
:: Echo out current timer values
:: =============================
:TIMEOUT
SET Timer.Callback=TimerEchoJ1
GOTO TimerUpdateEpoch
:TimerEchoJ1
SET /A Timer.elapsed=%Timer.epoch%-%Timer.start.state%
SET /A Timer.remaining=%Timer.max%-%Timer.elapsed%
ECHO "Seconds since timer started: %Timer.elapsed% Time remaining %Timer.remaining%"
GOTO EOF
:EOF
Integrate with shutdown
or any other command:
File poweroff.cmd
:
@ECHO OFF
Timer start %1
shutdown -t %1 -s
Usage: poweroff <wait_seconds>
to start timed shutdown and Timer get
to get elapsed/remaining time.
http://superuser.com/a/317062/117590 looked promising, however, it is preferred/required that the shutdown command is not modified as adding a comment (
/c <time>
) does. – Bob – 2012-04-19T11:16:55.590I think a batch file wouldn't be hard to write.. Prompt for the time, and every 5 minutes or so it could respond with a time, IE "10 minutes remaining".. and when it gets to 1, count down by seconds or something. – cutrightjm – 2012-04-25T02:00:20.643
I don't need a countdown, I need some method to get the time remaining at <this> moment. The shutdown command is being called by an external program. – Bob – 2012-04-25T02:26:15.867