I want to add some seconds to the current PC time. But I am a beginner in batch script coding and don't know how to modify the current time by adding some seconds.
This is the code I have so far:
Set "tijd=%time%"
echo %tijd%
echo %time%-%tijd%
pause
But the third command line does not output the expected result of current time increased by some seconds.
Here is a commented batch script to get current time without date and add 30 seconds to this time.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Get current time independent on region (country).
for /F "tokens=4-6 delims=/: " %%I in ('%SystemRoot%\System32\robocopy.exe "%SystemDrive%\|" . /NJH') do set "CurHour=%%I" & set "CurMinute=%%J" & set "CurSecond=%%K" & goto AddSeconds
rem The second value to add must be less than 60 for this code!
rem The code below adds 30 seconds to current time.
rem As second 08 and second 09 would be interpreted as invalid octal
rem numbers and so interpreted with value 0 in an arithmetic expression,
rem there is inserted the character 1 left to the second value to change
rem the second range to 100 to 159 (or 160 on leap second) and adding 30
rem is done by subtracting 70. The same method is used for the minutes 08
rem and 09 and the hours 08 and 09 on incrementing them by one if that is
rem necessary at all.
:AddSeconds
set "NewHour=%CurHour%"
set "NewMinute=%CurMinute%"
set /A NewSecond=1%CurSecond% - 70
if %NewSecond% LSS 60 goto TimeOutput
set /A NewSecond-=60
set /A NewMinute=1%NewMinute% - 99
if %NewMinute% LSS 60 goto TimeOutput
set /A NewMinute-=60
set /A NewHour=1%NewHour% - 99
if %NewHour% LSS 24 goto TimeOutput
set /A NewHour-=24
rem Before the new time is output, the second, minute and hour values are
rem formatted to have always two digits by first inserting 0 at beginning
rem and next use only the last two characters of the second, minute and
rem hour strings assigned to the three environment variables.
:TimeOutput
set "NewSecond=0%NewSecond%"
set "NewSecond=%NewSecond:~-2%"
set "NewMinute=0%NewMinute%"
set "NewMinute=%NewMinute:~-2%"
set "NewHour=0%NewHour%"
set "NewHour=%NewHour:~-2%"
echo Current time: %CurHour%:%CurMinute%:%CurSecond%
echo The new time: %NewHour%:%NewMinute%:%NewSecond%
endlocal
For the command line to get current time read either this answer written by Compo or third part of my answer on same question.
The Windows command processor cmd.exe has no support for time calculations. For that reason it is necessary on using just internal commands of cmd.exe to add 30 seconds to current time with using several arithmetic expressions and IF conditions.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
for /?
goto /?
if /?
rem /?
robocopy /?
set /?
setlocal /?
See also:
Single line with multiple commands using Windows batch file for an explanation of & operator.
Microsoft documentation for the Windows Commands
SS64.com - A-Z index of Windows CMD commands
Related
This question already has an answer here:
Variables are not behaving as expected
(1 answer)
Closed 5 years ago.
The variables _dd and _mm hold current day and month. 3 must be added to current day and if the day is greater than 27, 1 must be added to month (to change it to a month ahead).
Set /A _dd=%_dd%+3
REM **Set /A _mm=%_mm%+1**
echo %_dd%
IF %_dd% LSS 10 Set _dd=0%_dd%
IF %_dd% GTR 27 (
Set _dd=01
Set /A _mm=%_mm%+1
Set _mm=0%_mm%
Echo !_mm%! )
Set /A _mm=%_mm%+1 is working when ran outside IF statement, but not in action of IF statement.
Why is SET /A command line not working as expected after IF statement?
All occurrences of %_mm% are replaced during preprocessing the entire command block starting with ( and ending with matching ) before the IF condition is executed at all by Windows command interpreter. This behavior can be seen by running the batch file from within a command prompt window without #echo off at top to get output also the command lines and entire command blocks after preprocessing before execution.
It looks like delayed environment variable expansion as needed on accessing an environment variable within a command block being modified in same command block is not completely unknown as the line Echo !_mm%! indicates although being syntactically wrong. Open a command prompt window, run set /? and read the help output into the window carefully and completely. Delayed environment variable expansion is explained by help of command SET on an IF and a FOR example on which command blocks are most often used. The help of SET explains also arithmetic expression in detail.
Here is a solution not using delayed environment variable expansion by using a different process flow and which handles correct also month values 08 and 09. See second comment block for details.
rem This integer increment is problematic in case of value is 08 or 09.
rem See the month increment below how to handle such values also correct.
set /A _dd+=3
echo %_dd%
if %_dd% LEQ 27 goto MakeTwoDigitDay
set "_dd=01"
rem 08 and 09 would be interpreted as invalid octal numbers. Therefore do a
rem string concatenation with 1 if the first character is a leading zero for
rem month to change month value from 01-09 to 101-109 to get the month value
rem with a leading 0 interpreted as decimal number and add 1. Otherwise add
rem 101 to months 1-12 with no leading 0. Then assign to month variable
rem just the last two digits of the month value being greater than 100.
if "%_mm:~0,1%" == "0" ( set /A "_mm=1%_mm% + 1" ) else ( set /A "_mm+=101" )
set "_mm=%_mm:~-2%"
echo %_mm%
:MakeTwoDigitDay
if "%_dd:~1%" == "" set "_dd=0%_dd%"
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
goto /?
if /?
rem /?
set /?
Few issues here. You are trying to use delayed expansion without setlocal enableDelayedExpansion clause. With the given test data you'll never enter the last IF. You are setting value inside brackets block without proper usage of delayed variable expansion.It's better to have setlocal/endlocal blocks. CHeck this:
#echo off
:: to use variable expansion with ! you need delayed expansion
setlocal enableDelayedExpansion
Set /A _dd=%_dd%+3
REM **Set /A _mm=%_mm%+1**
echo %_dd%
IF %_dd% LSS 10 Set _dd=0%_dd%
echo %_dd%
::set another value to _dd to match the last if condition
set /a _dd=30
::::
IF %_dd% GTR 27 (
Set _dd=01
Set /A _mm=_mm+1
Set _mm=0!_mm!
Echo !_mm%!
)
endlocal
The problem, (as it appears you have almost realised), is that variable expansion requires delaying in the If block.
Set /A _dd +=3
:: Set /A _mm +=1
Echo %_dd%
If %_dd% Lss 10 Set "_dd=0%_dd%"
IF %_dd% Gtr 27 (
Set "_dd=01"
Set /A _mm +=1
Set "_mm=0!_mm!"
Echo !_mm! )
Prior to using delayed expansion, you need to ensure that it has been enabled using:
SetLocal EnableDelayedExpansion
Unfortunately I'm unable to add comments to an existing StackOverflow article as my rep isn't high enough, so I'll reference the link here:
runonce-to-rename-a-computername-with-a-random-name-on-reboot
Why does the batch sample code that LotPings provided always prefix the randomly generated part with the first letter from the character list, e.g. "A"?
Sample code:
#Echo off&SetLocal EnableExtensions EnableDelayedExpansion
Set "Chars=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
Call :RandChar 26 Name
For /L %%A in (1,1,14) Do Call :RandChar 62 Name
Echo %Name%
Goto :Eof
:RandChar Range Var
Set /A Pnt=%Random% %% %1 & Set %2=!%2!!Chars:~%Pnt%,1!
Result when executed 10 times:
AOyVq8olMi7kZaR
ANyU2MoAzZwTpwo
AYNXqJSGKXgyvca
AFGoCImfNOHuVSz
AHNhxnj9Wyqkqo3
AML6hTrSHK4TFut
AHuinBZCWr5D5NZ
AQYNtXaYMXRdGOb
ARWYXn7YNMQ0cmm
APHdWggSQl5KUhA
How can the code be modified to randomise the starting character too?
Set /A Pnt=%Random% %% %1 & Set %2=!%2!!Chars:~%Pnt%,1!
should be
Set /A Pnt=%Random% %% %1
Set %2=!%2!!Chars:~%Pnt%,1!
The entire line is parsed, then executed and during the parsing phase, any %var% will be replaced by the value of varat that time. Hence,pntwill be replaced by the value ofpntat the very start, yieldingSet %2=!%2!!Chars:~,1!` and thereafter it will be replaced by the value established on the previous call.
Breaking the line forces the two statements to be executed sequentially.
I am running a small .bat script to output the system time to a text file to then be imported to OBS. The project it is being used for however needs to have the time displayed in Central time instead of Eastern (my time zone). Is it possible to change the outputs time zone without changing the timezone on my computer's clock?
:loop
time /T > C:\Users\Brennan\Desktop\time\time.txt
time /T
timeout /t 15
goto loop
The command wmic path win32_utctime get outputs UTF-16 Little Endian encoded:
Day DayOfWeek Hour Milliseconds Minute Month Quarter Second WeekInMonth Year
16 0 11 12 7 3 19 4 2017
This output can be parsed with command FOR and concatenated to a UTC date/time string in international date/time format YYYY-MM-DD HH:mm:ss wit command SET.
#echo off
for /F "skip=1 tokens=1,3,4,5,7,9" %%A in ('%SystemRoot%\System32\wbem\wmic.exe path win32_utctime get') do (
set "Day=0%%A"
set "Hour=0%%B"
set "Minute=0%%C"
set "Month=0%%D"
set "Second=0%%E"
set "Year=%%F"
goto BuildDateTime
)
:BuildDateTime
set "DateTimeUTC=%Year%-%Month:~-2%-%Day:~-2% %Hour:~-2%:%Minute:~-2%:%Second:~-2%"
echo UTC date/time is: %DateTimeUTC%
The output of this batch file for the data posted above is:
UTC date/time is: 2017-07-16 11:12:19
The code can be also modified to get just UTC time:
#echo off
for /F "skip=1 tokens=3,4,7" %%A in ('%SystemRoot%\System32\wbem\wmic.exe path win32_utctime get') do (
set "Hour=0%%A"
set "Minute=0%%B"
set "Second=0%%C"
goto BuildTime
)
:BuildTime
set "TimeUTC=%Hour:~-2%:%Minute:~-2%:%Second:~-2%"
echo UTC time is: %TimeUTC%
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
for /?
set /?
wmic /?
wmic path /?
wmic path win32_utctime /?
wmic path win32_utctime get /?
The zone may be set via tzutil but it is a global (systemwide) change -- the setlocal command will not localize it. The following will temporarily change the desired zone, by saving and restoring it:
for /f "delims=" %%z in ('tzutil /g') do (
rem set desired zone
tzutil /s "Central Standard Time"
time /T > C:\Users\Brennan\Desktop\time\time.txt
rem restore original zone
tzutil /s "%%z"
)
Note the change is systemwide, so the period between tzutil calls the system clock will change. And if the script is aborted between tzutil calls the system time zone will remain altered.
I'm getting a syntax error on the timeout command supposedly because of a "missing operand". But I don't see any operand missing.
rem description for the user to read
echo Insert time in minutes:
rem setting default (1 hour)
set /a timeto=3600
rem asking user for input (integer)
set /p timeto=
rem converting minutes to seconds
set /a timeto=%timeto%*60
rem command based on the inputted value
timeout /t %timeto% /nobreak
Invalid syntax. Commenting commands inline is not possible in cmd CLI nor a batch scripts:
==>set /a timeto=3600 ::setting default time (1 hour)
Missing operator.
==>set /a timeto=3600
3600
==>
Note that %timeTo%*60 exceeds timeout /T valid range -1 to 99999 for default 3600*60.
If your code snippet appears enclosed in () parentheses, then use Delayed Expansion.
#ECHO ON >NUL
#SETLOCAL EnableExtensions EnableDelayedExpansion
if 1==1 (
rem description for the user to read
echo Insert time in minutes:
rem setting default time (1 hour = 60 minues)
set /a timeTo=60
rem asking user for input (integer)
set /p timeTo=
rem converting minutes to seconds - erroneous
set /a timeTo=%timeTo%*60
rem converting minutes to seconds - right approach
set /a timeTo=!timeTo!*60
rem command based on the inputted value
echo timeout /t !timeTo! /nobreak
)
Output: note that set /a timeTo=%timeTo%*60 line causes the Missing operand error as results to erroneous set /a timeTo=*60 in the parse time.
==>D:\bat\SO\32410773.bat
==>if 1 == 1 (
rem description for the user to read
echo Insert time in minutes:
rem setting default time (1 hour = 60 minues)
set /a timeTo=60
rem asking user for input (integer)
set /p timeTo=
rem converting minutes to seconds - erroneous
set /a timeTo=*60
rem converting minutes to seconds - right approach
set /a timeTo=!timeTo!*60
rem command based on the inputted value
echo timeout /t !timeTo! /nobreak
)
Insert time in minutes:
Missing operand.
timeout /t 3600 /nobreak
==>
Batch does not support inline comments.All comments need to be in separate line:
::description for the user to read
echo Insert time in minutes:
::setting default time (1 hour)
set /a timeto=3600
::asking user for input (integer)
set /p timeto=
::converting minutes to seconds
set /a timeto=%timeto%*60
::command based on the inputted value
timeout /t %timeto% /nobreak
I would like to get the time stamp from the last two lines in a file that looks something like this using DOS:
2/3/2013 18:30:00 This is line 1
2/3/2013 19:24:05 This is line 2
2/3/2013 20:10:40 This is line 3
2/3/2013 21:06:00 This is line 4
2/3/2013 22:50:31 This is line 5
Currently, my script looks like this:
setlocal EnableDelayedExpansion
set i=0
for /f "tokens=2" %%x in (inputfile.txt) do (
set /a i=!i!+1
set time!i!=%%x
)
set /a lasttime=time!i!
set /a j=!i!-1
set /a prevtime=time!j!
echo %lasttime%
echo %prevtime%
endlocal
The output only have the hours portion, no minutes and seconds:
21
22
Please tell me how to make it work.
The issue is your using the SET /A command for assigning lasttime and prevtime.
SET /A is used for arithmetic operations, and everything you are feeding it must be converted to a number, even though you are not doing anything with the value apart from storing it to another variable. Your time!i! reference evaluates to 22:50:31 but in the context of the SET /A command it is immediately converted to the closest numeric value, which is 22. Same happens with time!j!.
To fix the issue, just use a simple SET command and mixed expansion, like this:
...
set lasttime=!time%i%!
set /a j=!i!-1
set prevtime=!time%j%!
...
Also, if all you need is the last two lines, you could consider an alternative approach. Instead of using a separate variable for every line of the text, you could use just two: one to store the current line, the other to store the previous value of the former. Here's what I mean:
setlocal EnableDelayedExpansion
for /f "tokens=2" %%x in (inputfile.txt) do (
set prevtime=!lasttime!
set lasttime=%%x
)
echo %lasttime%
echo %prevtime%
endlocal