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.
Related
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
How do I add the time to this batch file when I rename the file?
The results look like this but need time also: Daily Report_Wed 08222018.pdf
#echo off
Pushd c:\Temp
pdftk *.pdf cat output %fn%.pdf
ren %fn%.pdf %fn%.xxx
del *.pdf
ren %fn%.xxx "Daily Report".pdf
for /f "tokens=1-3 delims=/" %%a in ('echo %date%') do set today=%%a%%b%%c
for %%f in (*.pdf) do ren "%%f" "%%~nf_%today%%%~xf"
mkdir "Daily Reports for Review"
move *.pdf "Daily Reports for Review"
Here's something that could get you close to what you want (I modified your 1st for loop):
e:\Work\Dev\StackOverflow>echo Date: [%date%], Time: [%time%]
Date: [2018-08-22], Time: [22:51:36.23]
e:\Work\Dev\StackOverflow>for /f "tokens=1-6 delims=/-:., " %a in ('echo %date: =0%-%time: =0%') do (echo set now=%a%b%c%d%e%f)
e:\Work\Dev\StackOverflow>(echo set now=20180822225136 )
set now=20180822225136
Notes:
Since I am directly in cmd window, and you're in a batch file you have to double the percent sign (%) for parameters (%a -> %%a, %b -> %%b, ... like you already have in your snippet). For more details, check [SS64]: Double %% symbols why are they needed in a batch file?
As you probably noticed (most likely due to "Regional settings"), my date format differs than yours (that's why I added the hyphen (-) in the delims list; also the items ordering is reversed), so you might get slightly different behaviors on different computers (things will get even worse on non English locales, as #Stephan noticed), so it's not a reliable solution (I guess this is batch processing generic)
Here's an untested example for you which uses WMIC to retrieve non locale dependent date and time values:
#Echo Off
If Exist "C:\Temp\*.pdf" (CD /D "C:\Temp") Else Exit /B
Rem The values below can be modified according to your language or preferred day names
Set "WeekDays=Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
For /F %%A In ('WMIC Path Win32_LocalTime Get /Value^|FindStr "[0-9]$"') Do Set "%%A"
For /F "Tokens=1%DayOfWeek%" %%A In (". . . . . . . . . %WeekDays%") Do Set "DayName=%%A"
For %%A In (Day Hour Minute Month Second) Do Call Set "%%A=0%%%%A%%" & Call Set "%%A=%%%%A:~-2%%"
Rem Choose the output %FileName% you want from the following variables:
Rem %Year% e.g. 2018
Rem %Quarter% e.g. 3
Rem %Month% e.g. 08
Rem %WeekInMonth% e.g. 4
Rem %Day% e.g. 22
Rem %DayOfWeek% as an integer where Monday from %WeekDays% is 1 e.g. 3
Rem %DayName% as a string taken from %WeekDays% e.g. Wednesday
Rem %Hour% in 24 hr format e.g. 21
Rem %Minute% e.g. 57
Rem %Second% e.g. 53
Set "FileName=%DayName% %Month%%Day%%Year%%Hour%%Minute%%Second%"
Rem Choose the full or relative output directory name
Set "DirName=Daily Reports for Review"
If Not Exist "%DirName%\" MD "%DirName%"
PDFTK *.pdf cat output "%DirName%\%FileName%.pdf" && Del /Q *.pdf
You will need to include the full or relative path to PDFTK on the last line if it is not located in the current working directory, (C:\Temp), or in %PATH%. Other than that, you should only make modifications to values on lines beginning with Set.
Empty lines and those Remarked can be optionally removed once you've made your modifications.
I have a portion of a script that is intended to remove the ":" out of the time and "/" out of the date as returned by time /t and date /t commands. If I execute the command in a command prompt (cmd.exe), the expected values are returned:
C:\Windows\system32>time /t
02:49 PM
C:\Windows\system32>date /t
Tue 07/03/2018
If I place the same commands at the beginning of my batch script, I get the results I expect. However, if I place the same command within a for statement to parse out the ":" and "/". I receive the following messages:
'date /t' is not recognized as an internal or external command,
operable program or batch file.
'time /t' is not recognized as an internal or external command,
operable program or batch file.
Running the for command outside of the batch file works fine. I have recreated the batchfile from scratch to be sure there were no random odd characters present.
Here is the script itself:
time /t
date /t
for /F "Tokens=2,3,4 delims=/ " %%a in ('date /t') Do Set _cdate=%%c%%a%%b
for /F "Tokens=1,2,3 delims=: " %%a in ('time /t') Do Set _ctime=%%a%%b%%c
pause
This same script works fine on another server as well as my desktop. I am at a loss as to what makes this new server different. (Aside from one is 32bit) The COMSPEC is correct. (C:\Windows\system32\cmd.exe) These commands are part of a larger script to provide file name prefix for logging.
You can try this batch script using WMIC to get Date and Time not depending for locale/user settings :
#echo off
Title Get Date and Time using WMIC
Call :Get_Date_Time
echo Date : %Year%-%Month%-%day%
echo Time : %Hour%:%Min%:%Sec%
Pause>nul & Exit
::********************************************************************************************
:Get_Date_Time
for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set "MyDate=%%x"
set "Year=%MyDate:~0,4%"
set "Month=%MyDate:~4,2%"
set "Day=%MyDate:~6,2%"
set "Hour=%MyDate:~8,2%"
set "Min=%MyDate:~10,2%"
set "Sec=%MyDate:~12,2%
exit /b
::********************************************************************************************
#echo off
:prep
cls
for /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b)
:for /l %A in (1,1,100) do copy "C:\some folder\file.ext" "C:\some folder\file-%%A.ext"
set choice=
:: test to see if directory exists
if EXIST "../delivery_%mydate%.txt" (
goto overwrite
) else (
goto start
)
:overwrite
echo.
echo delivery note already exists - continue?
set /p choice='y / n ?'
if '%choice%'=='' ECHO "%choice%" is not valid please try again
if '%choice%'=='y' goto start
if '%choice%'=='n' goto end
echo.
:start
echo.
for /l %A in (1,1,100) do copy "C:\some folder\delivery_%mydate%.ext" "C:\some folder\delivery_%mydate%.ext"
echo Choose the following:
echo 1. Directories
echo 2. Files
echo 3. quit
echo.
set /p choice=
if '%choice%'=='1' goto directory
if '%choice%'=='2' goto file
if '%choice%'=='3' goto end
cls
ECHO "%choice%" is not valid please try again
goto start
:directory
dir /ad /on /b > ../delivery_%mydate%.txt
echo.
goto checksuccess
:file
dir /a-d /on /b > ../delivery_%mydate%.txt
echo.
goto checksuccess
:checksuccess
I need to add a line of code to this batch file I have created above. I need this code to save an existing file to a higher version without deleting the previous one. This will also need to be embedded into the code I created. For example it will start saving them like: filev001, filev002, etc.
1. Some general advice for writing batch files
A list of commands is output on executing in a command prompt window help. It is advisable to use in batch files for environment variables and labels not a string which is also a command. It is possible, but not advisable.
start is a command to start an application in a separate process. So it is better to use for example Begin instead of start as label.
choice is a command for a choice which is better for single character choices than using set /P. So it is better to use for example UserChoice instead of just choice as environment variable name.
It is better to use echo/ instead echo. to output an empty line. The reason is explained by DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/.
Environment variable names and labels are easier to read on using CamelCase and can be more easily searched case-sensitive and if necessary replaced in a batch file than a name/label which can exist as word also in comments and in strings output with echo.
The answer on question Why is no string output with 'echo %var%' after using 'set var = text' on command line? explains in detail why the usage of the syntax set "Variable=string value" is recommended in batch files on assigning a string to an environment variable.
The directory separator on Windows is the backslash character \. The slash character / is the directory separator on Unix/Linux/Mac. On Windows / is used for options/parameters. The Windows kernel functions support also directory and file paths with / as directory separator by automatically correcting them to \ internally in path. But it is nevertheless recommended to use in a batch file \ in paths.
rem is the command for a comment in a batch file. :: is an invalid label and not really a comment. Lines with a label at begin are ignored for command execution. But a label cannot be used in a command block. For that reason it is recommended to use command rem because :: in a command block results often in unexpected behavior on execution of the batch file.
2. Get current date in a specific format
Let us look on the command line:
for /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b)
date /t is a command which for executes in a background command process with the command line cmd.exe /C date /t for capturing the output of this command process written to standard output handle STDOUT and process the captured output line by line.
Can this be optimized?
Yes, because on running in a command prompt window set /? and reading the output help from first to last page it can be read that there is the environment variable DATE which expands to current date. So there is no need to run the command date to get current date as string.
The command date with option /t outputs the current date in the format defined for the used user account in Windows Region and Language settings. In your case it looks like the region dependent date format is MM/dd/yyyy with the weekday abbreviation at beginning (with no comma) before the date. The date format on my computer is just dd.MM.yyyy without weekday. The environment variable DATE is in same region dependent format as output of command date /t.
So the region dependent date in format ddd, MM/dd/yyyy could be also modified to yyyy-MM-dd using the command line:
for /F "tokens=2-4 delims=/, " %%a in ("%DATE%") do set "MyDate=%%c-%%a-%%b"
It is also possible to use string substitution:
set "MyDate=%DATE:~-4%-%DATE:~-10,2%-%DATE:~-7,2%"
String substitution is also explained by help output on running set /? and read the answer on
What does %date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% mean?
But if yyyy-MM-dd is the wanted date format for current date independent on region settings of the used user account is advisable to use the command lines
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "MyDate=%%I"
set "MyDate=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%"
This region independent solution is really much slower than the above command lines. It is explained in detail by the answer on Why does %date% produce a different result in batch file executed as scheduled task? But it has the big advantage of being region independent.
3. Prompting user for a single character choice
The usage of set /P variable=prompt is not recommended for a single character choice because
the user can just hit RETURN or ENTER without entering anything at all resulting in variable keeping its current value or still not being defined if not defined before set /P command line;
the user can make a typing mistake and presses for example Shift+2 instead of just 2 resulting (on German keyboard) to enter " as string which most batch files using set /P breaks because of a syntax error on next command line evaluating the user input;
the user can enter anything instead of one of the characters asked for including strings which on next command line results in deletion of files and folders.
The solution is using the command choice if that is possible (depends on Windows version). choice waits for the key press of a character specified in the command options and immediately continues after one of these keys is pressed. And choice exits with the index of the pressed character in list as specified in batch file. This exit code is assigned to ERRORLEVEL which can be evaluated next also within a command block without using delayed expansion or used directly in a single goto instruction.
4. Rewritten batch file
Here is the rewritten batch file:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem set "Folder=C:\some folder"
set "Folder=F:\Temp\Test"
:Prepare
cls
rem Get current date region independent in format yyyy-MM-dd.
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "MyDate=%%I"
set "MyDate=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%"
set "FileNumber=0"
for %%I in ("%Folder%\file-*.ext") do call :GetFileNumber "%%~nI"
goto IncrementNumber
rem Subroutine to find out highest file number without using delayed
rem environment variable expansion for number range 0 to 2147483647.
rem Numbers starting with 0 are interpreted as octal number in number
rem comparison which makes it necessary to remove leading 0 from the
rem number string get from file name starting with 5 characters.
:GetFileNumber
set "Number=%~1"
set "Number=%Number:~5%
:RemoveLeadingZero
if "%Number%" == "" goto :EOF
if "%Number:~0,1%" == "0" set "Number=%Number:~1%" & goto RemoveLeadingZero
if %Number% GTR %FileNumber% set "FileNumber=%Number%"
goto :EOF
rem Make sure the file number has at least 3 digits.
:IncrementNumber
set /A FileNumber+=1
if %FileNumber% GEQ 100 goto ExistDelivery
set "FileNumber=00%FileNumber%"
set "FileNumber=%FileNumber:~-3%"
rem Test to see if file exists already.
:ExistDelivery
if not exist "..\delivery_%MyDate%.txt" goto Begin
echo/
%SystemRoot%\System32\choice.exe /C YN /N /M "Delivery note already exists, continue (Y/N)? "
if errorlevel 2 goto :EOF
:Begin
set "FileName=file-%FileNumber%.ext"
copy "%Folder%\file.ext" "%Folder%\%FileName%" >nul
echo/
echo Choose the following:
echo/
echo 1. Directories
echo 2. Files
echo 3. Quit
echo/
%SystemRoot%\System32\choice.exe /C 123 /N /M "Your choice? "
if errorlevel 3 goto :EOF
if errorlevel 2 goto GetFileList
dir * /AD /ON /B >"..\delivery_%MyDate%.txt"
echo/
goto CheckSuccess
:GetFileList
dir * /A-D /ON /B >"..\delivery_%MyDate%.txt"
echo/
:CheckSuccess
rem More commands.
endlocal
It was not really clear for me what the entire batch code is for at all.
It would have been also easier to write the determination of highest number in a file name on knowing the possible number range like 001 to 100. So I wrote a general solution for 001, 002, ..., 099, 100, 101, ..., 1000, ..., 2147483647.
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.
call /?
cls /?
copy /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
rem /?
set /?
setlocal /?
wmic /?
wmic os /?
wmic os get /?
wmic os get localdatetime /?
See also answer on Single line with multiple commands using Windows batch file for an explanation of & operator and read the Microsoft article about Using command redirection operators.
I'm trying to setup 7zip for automated backups but I'm having trouble with output file names.
I tried using the %date% command but it just made 2 directories within my backup.
C:\Users\Desktop\Sun 11\07\2010.7z
How can I make it just log the day and month?
C:\Users\Desktop\Sun 11-07-2010.7z
Try
7z a %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%.7z *.* for (YYYY-MM-DD)
or
7z a %DATE:~7,2%-%DATE:~4,2%-%DATE:~-4%.7z *.* for (DD-MM-YYYY)
(*.* is the mask for the files to back up)
Are you using a bat-file? Look here http://www.tech-recipes.com/rx/956/windows-batch-file-bat-to-get-current-date-in-mmddyyyy-format/
You can use WMI to get your date details in a specific format. The problem with the output from date (and the %date% environment variable) is that it's very locale-specific.
If you execute:
wmic path win32_localtime get day^,month^,year^ /format:csv
you will see the output you need to process.
The following script will get you the yyyy-mm-dd format that you need (using the day of the week as the primary sort key is not a good idea):
#echo off
for /f "skip=2, tokens=2-4" delims=," %%a in ('wmic path win32_localtime get day^,month^,year^ /format:csv') do (
set /a ymd = 10000 * %%c + 100 * %%b + %%a
)
set ymd=%ymd:~0,4%-%ymd:~4,2%%ymd:~6,2%
echo %ymd%