Help with checking for a specific time and doing a specific task at that time

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
redskullington
Posts: 1
Joined: 17 Dec 2015 23:26

Help with checking for a specific time and doing a specific task at that time

#1 Post by redskullington » 17 Dec 2015 23:29

Code
------------------------

Code: Select all

@echo off


:start
echo %time%
   if %time% EQU 12:00:00 (

echo.> PLEBLORD.txt

) ELSE (
   goto start

)

-----------------------

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Help with checking for a specific time and doing a specific task at that time

#2 Post by foxidrive » 18 Dec 2015 03:47

A batch file cannot reliably detect a single second, as CPU load etc can make it miss the time window that you've set.

Squashman
Expert
Posts: 4465
Joined: 23 Dec 2011 13:59

Re: Help with checking for a specific time and doing a specific task at that time

#3 Post by Squashman » 18 Dec 2015 07:54

Why not use Windows Task Scheduler?

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Help with checking for a specific time and doing a specific task at that time

#4 Post by thefeduke » 18 Dec 2015 22:55

redskullington wrote: if %time% EQU 12:00:00 (
I tweaked something that I had on the back burner that seems to fit:

Code: Select all

:Delay hh:mm:ss
@Echo Off &SetLOCAL EnableDelayedExpansion &Rem.and keep environment uncluttered.

    If .%~1 NEQ . (
        If "%~1"=="/?" (
            Echo.&Echo.%~n0 has minimal Help for now^^!
            Echo.Argument can be: hh[:mm[:ss]]
            Exit /B 1
        )
        Set "/Until=%~1"
    ) Else (
        Set "/For=16"
    )
    If .%/Until% NEQ . (
        For /F "tokens=1-3* delims=/ " %%i In ("%DATE%") Do (
           Set /A "mm=%%j-1"
           Set "dd=%%k"
           Set "yy=%%l"
        )
        Set "hr=24"
        Set "mn=00"
        Set "sc=00"
        For /F "tokens=1-3* delims=: " %%i In ("%/Until%") Do (
           Set "hr=%%i"
           If .%%j NEQ . Set "mn=%%j"
           If .%%k NEQ . Set "sc=%%k"
        )
        call getTimestamp -d "!yy!,!mm!,!dd!,!hr!,!mn!,!sc!" -f "a target of {hh}:{nn}:{ss}.{fff}" -r until
        call getTimestamp -d "!yy!,!mm!,!dd!,!hr!,!mn!,!sc!" -f {us} -r TimeEnd
rem.    Echo.From: %time%
        call getTimestamp -f {us} -r Timenow
        Set /a left=timeend-timenow
        If !left! lss 0 (
            Set "/For=0"
            Echo.It is not worth the wait.
        ) Else (
            Set "/For=!left!"
        )
        Echo.Wait for: !/For! Seconds from: !time! until !until!
    )

    Timeout /T %/For%
    Echo.&Echo.It is now !time! vs. %until%
    Echo.&Echo.Do Whatever task you want to begin here.

EXIT /b
This has an external dependency on GetTimestamp.bat which was written by Dave Benham and originally posted at http://www.dostips.com/forum/viewtopic.php?f=3&t=4847. Because it is also dependent on 'timeout' it doesn't run on XP.

Here is a version for XP that also runs on Win 7 up. All other called functions are internal but it is not as time-accurate as the one above:

Code: Select all

:Delaying [/Until hh[:mm[:ss]] [/For seconds] 
    @Echo Off &SetLOCAL EnableDelayedExpansion &Rem.Keep environment uncluttered.

:: Define option values
    Set "''Defaults=/Help: /H: -H:"
    Set "''Defaults=%''Defaults% /For:"0" /Until:"" "

:: Set the default option values
    For %%O In (%''Defaults%) Do For /F "tokens=1,* delims=:" %%A In ("%%O") Do Set "%%A=%%~B"

    For /F "delims==" %%a in ('"set ArgArr{ 2>NUL"') do set "%%a="
    Set "ArgArr{0}=0"
:loop
:: Validate and store the options, one at a time, using a loop.
:: Arguments that are not options are streamed to an arguments array.
:: Options start at arg 1. Each SHIFT is done starting at
:: the first option so required args are preserved.
:: This approach allows more than the first arguments specified
:: by <%1> or <%~1> to <%9> to be addressed directly.
::
    If Not ".%~1"=="." (
        Set "testing=!''Defaults:*%~1:=! "
        If "!testing!"=="!''Defaults! " (
            If "%~1" equ "/?" (
                Set "/Help=1"
            ) Else if /I "%~1" equ "/??" (
                Set "/Help=2"
            ) Else (
                Set /A ArgArr{0}+=1
                Set "ArgArr{!ArgArr{0}!}=%~1"
            )
        ) Else (
            Set "retest=%~1"
            If "!retest:~0,1!" NEQ "/" (
                Set /A ArgArr{0}+=1
                Set "ArgArr{!ArgArr{0}!}=%~1"
            ) Else (
                If "!testing:~0,1!"==" " (
                    Set "%~1=1"
                    Set "-Set=1"
                ) Else (
                    Set "%~1=%~2"
                    Shift /1
                )
            )
        )
        Shift /1
        GoTo :loop
    )

:: Default option processing complete

:: To get the value of a single parameter, just remember to include the `-` or `/`

    If .%~1 NEQ . (
        If "%~1"=="/?" (
            Echo.&Echo.%~n0 has minimal Help for now^^!
            Echo.Arguments can be: /Until hh[:mm[:ss]]
            Echo.or /For seconds
            Exit /B 1
        )
        Set "/Until=%~1"
    ) Else (
        Set "/For=16"
    )
    If .%/Until% NEQ . (
        For /F "tokens=1-3* delims=/ " %%i In ("%DATE%") Do (
           Set /A "mm=%%j-1"
           Set "dd=%%k"
           Set "yy=%%l"
        )                     
        Set "hr=24"
        Set "mn=00"
        Set "sc=00"
        For /F "tokens=1-3* delims=: " %%i In ("%/Until%") Do (
           Set "hr=%%i"
           If .%%j NEQ . Set "mn=%%j"
           If .%%k NEQ . Set "sc=%%k"
        )
        call getTimestamp -d "!yy!,!mm!,!dd!,!hr!,!mn!,!sc!" -f "{hh}:{nn}:{ss}.{fff} requested" -r until
        call getTimestamp -d "!yy!,!mm!,!dd!,!hr!,!mn!,!sc!" -f {us} -r TimeEnd
        call getTimestamp -f {us} -r Timenow
        Set /a left=timeend-3-timenow
        If !left! lss 0 (
            Set "/For=0"
            Echo.It is not worth the wait.
        ) Else (
            Set "/For=!left!"
        )
        Echo.Wait for: !/For! Seconds from: !time! until !until!
    )

    Call :Wait %/For%
    Echo.&Echo.It is now !time! vs. %until%
    Echo.&Echo.Do Whatever task you want to begin here.

EXIT /b

:Color
:: v23c
:: Arguments: hexColor text [\n] ...
:: \n -> newline ... -> repeat
:: Supported in windows XP, 7, 8.
:: This version works using Cmd /U
:: In XP extended ascii characters are printed as dots.
:: For print quotes, use empty text.
@Echo Off
SetLocal EnableExtensions EnableDelayedExpansion
Subst `: "!Temp!" >Nul &`: &Cd \
SetLocal DisableDelayedExpansion
Echo(|(Pause >Nul &Findstr "^" >`)
Cmd /A /D /C Set /P "=." >>` <Nul
For /F %%# In (
'"Prompt $H &For %%_ In (_) Do Rem"') Do (
Cmd /A /D /C Set /P "=%%# %%#" <Nul >`.1
Copy /Y `.1 /B + `.1 /B + `.1 /B `.3 /B >Nul
Copy /Y `.1 /B + `.1 /B + `.3 /B `.5 /B >Nul
Copy /Y `.1 /B + `.1 /B + `.5 /B `.7 /B >Nul
)
:__Color
Set "Text=%~2"
If Not Defined Text (Set Text=^")
SetLocal EnableDelayedExpansion
For %%_ In ("&" "|" ">" "<"
) Do Set "Text=!Text:%%~_=^%%~_!"
Set /P "LF=" <` &Set "LF=!LF:~0,1!"
For %%# in ("!LF!") Do For %%_ In (
\ / :) Do Set "Text=!Text:%%_=%%~#%%_%%~#!"
For /F delims^=^ eol^= %%# in ("!Text!") Do (
If #==#! EndLocal
If \==%%# (Findstr /A:%~1 . \` Nul
Type `.3) Else If /==%%# (Findstr /A:%~1 . /.\` Nul
Type `.5) Else (Cmd /A /D /C Echo %%#\..\`>`.dat
Findstr /F:`.dat /A:%~1 .
Type `.7))
If "\n"=="%~3" (Shift
Echo()
Shift
Shift
If ""=="%~1" Del ` `.1 `.3 `.5 `.7 `.dat &Goto :Eof
Goto :__Color

:Wait TimeInSecs
@Echo Off &SetLOCAL EnableDelayedExpansion &Rem.and keep environment uncluttered.
    Set "TimeInSecs=%~1"
    If "%~1"=="/?" Echo.&Echo.%~n0 has no Help for now^^! & Set "TimeInSecs=15"
    call :TestInt %TimeInSecs%
    If ErrorLevel 1 Set "TimeInSecs=15"
    Set "UnitsL2=seconds"
    Set "UnitsL5=mm:secs"
    Set "UnitsL8=h:mm:ss"
    Set /A "ssfff=TimeInSecs*1000"
    Set "CountSecs=%TimeInSecs%"
    call getTimestamp -f {ums} -r Time1st
    call getTimestamp -of %ssfff% -f "{hh}:{nn}:{ss}.{mm}" -r TimeEndHMS
    call getTimestamp -of %ssfff% -f {ums} -r TimeEnd
    Echo(
    <nul Set /p "=Waiting time left is "
    If %TimeInSecs%. GEQ 86400. (
        Set "TimeInSecs=86399"
    )
    If %TimeInSecs%. GEQ 3600. (
        call getTimestamp -d %TimeEnd%-%Time1st% -f "{hh}:{nn}:{ss}" -u -r TimeDSecs
        CALL :Color 7 "!timeDSecs! "
        <nul Set /p "=%UnitsL8%"
        Set "LastLen=8"
    ) Else If %TimeInSecs%. GEQ 60. (
        Call getTimestamp -d %TimeEnd%-%Time1st% -f "{nn}:{ss}" -u      -r TimeDSecs
        CALL :Color 7 "!timeDSecs! "
        <nul Set /p "=%UnitsL5%"
        Set "LastLen=5"
    ) Else (
        call getTimestamp -d %TimeEnd%-%Time1st% -f "{s}" -u           -r TimeDSecs
        CALL :Color 7 "!TimeDSecs! "
        <nul Set /p "=%UnitsL2%"
        If %TimeInSecs%. LSS 10. (
            Set "LastLen=1"
        ) Else (
            Set "LastLen=2"
        )
    )
    For /F "delims=#" %%a in ('"prompt #$H# &echo on &for %%b in (1) do rem"') Do (Set "{bs}=%%a")
    For /L %%s in (%CountSecs%,-1,0) Do (
        If "%%s" EQU "%CountSecs%" (
            Set /A "TimeInSecs=%TimeInSecs%+1000000"
            Set "LastLen=%LastLen%"
        )
        If !TimeInSecs! LSS 1000046 (
            ping -n  2 -w  600 127.0.0.1>NUL
        ) Else (
            ping -n 12 -w 1000 127.0.0.1>NUL
        )
        call getTimestamp -f {ums} -r TimeNow
        <nul set /p "=%{BS}%%{BS}%%{BS}%%{BS}%%{BS}%%{BS}%%{BS}%%{BS}%"
        For /l %%l in (1,1,!LastLen!) do (
            <nul set /p "=%{BS}%"
        )
        If !TimeInSecs! GTR 1000059 (
            call getTimestamp -d %TimeEnd%-!TimeNow! -f "1{hh}{nn}{ss}" -u -r TimeInSecs
        )
        If !TimeInSecs! GTR 1000059 (
            If !TimeInSecs! LSS 1010000 (
                call getTimestamp -d %TimeEnd%-!TimeNow! -f "{nn}:{ss}" -u -r TimeDSecs
            ) Else (
                call getTimestamp -d %TimeEnd%-!TimeNow! -f "{hh}:{nn}:{ss}" -u -r TimeDSecs
            )
            CALL :Color "B" "!TimeDSecs! "
        ) Else (
            Call :SecsLeft "%TimeEndHMS%"  TimeDSecs
            Set /A "TimeInSecs=!TimeDSecs!+1000000"
        )
        If !TimeInSecs! EQU 1000001 (
            <nul set /p "=second."
        ) Else If !TimeInSecs! LSS 1000010 (
            <nul set /p "=%UnitsL2%"
            Set "LastLen=1"
        ) Else If !TimeInSecs! LSS 1000060 (
            <nul set /p "=%UnitsL2%"
            Set "LastLen=2"
        ) Else If !TimeInSecs! LSS 1010000 (
            <nul set /p "=%UnitsL5%"
            Set "LastLen=5"
        ) Else (
            <nul set /p "=%UnitsL8%"
            Set "LastLen=8"
        )
        If !TimeInSecs! EQU 1000000 (
            SetLocal DisableDelayedExpansion
            CALL :Color F ". The wait is over" F "!"
            Echo(
            Exit /B 0
        )
    )
    EXIT /b 0

:Secsleft
    SetLOCAL EnableDelayedExpansion &Rem.and keep environment uncluttered.
    Set "tm2=%~1"
    Set "tm0=%Time%"
    Set "SC=7"
    For /f "tokens=1-8 delims=:.," %%a In ("%tm0: =0%:%tm2: =0%") do (
        set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h+71-1%%c%%d"
    )
    Set /A Spanned_time=a/100
    If %Spanned_time% LEQ 9 (
        If %Spanned_time% LEQ 5 (
            If %Spanned_time% LEQ 0 (
                Set "Spanned_time=0"
                Set "SC=F"
            ) Else (
                Set "SC=C"
            )
            REM.
        ) Else (
            Set "SC=E"
        )
        REM.
    ) Else (
        If %Spanned_time% LEQ 20 (
            Set "SC=A"
        ) Else (
            Set "SC=B"
        )
    )
    If %Spanned_time% GTR 59 Set "Spanned_time=59"
    CALL :Color "%SC%" "%Spanned_time% "
    ( ENDLOCAL & REM RETURN VALUES
        IF "%~2" NEQ "" SET %~2=%Spanned_time%
    )
    Exit /B

:TestInt <string> (Returns non-zero for non-numeric argument)
    @Echo Off
    If .%~1==. Exit /B 2
    for /f "delims=0123456789" %%a in ("%1") do exit /b 1
    exit /b 0
The :Wait subroutine can stand alone and imitates TIMEOUT but needs a well timed <ctrl-Break> to exit early. Acknowledgements to dbenham and Aacini for various parts.
John A.

Post Reply