How to get the Date in a batch file in a predictable format?

17

7

In a batch file I need to extract a month, day, year from the date command. So I used the following, which essentially parses the Date command to extract its sub strings into a variable:

set Day=%Date:~3,2%
set Mth=%Date:~0,2%
set Yr=%Date:~6,4%

This is all great, but if I deploy this batch file to a machine with a different regional/country settings, it fails because month, day and year are in different locations.

How can I extract month, day and year regardless of the date format?

AngryHacker

Posted 2011-07-27T22:38:53.980

Reputation: 14 731

replacing %date% by %date:~6,4%-%date:~3,2%-%date:~0,2% worked – MagTun – 2015-11-27T10:06:28.337

1Are you absolutely restricted to Batch? Such a thing is much simpler in VBScript/WSH and/or PowerShell ... – Adrien – 2011-07-27T23:20:54.350

@Adrien, Yes limited to batch - it's part of the VS2008 post-build step. – AngryHacker – 2011-07-28T00:06:15.527

Answers

14

Source: http://ss64.com/nt/syntax-getdate.html

Method 2 (single cmd)

GetDate.cmd

@Echo off
:: Check WMIC is available
WMIC.EXE Alias /? >NUL 2>&1 || GOTO s_error

:: Use WMIC to retrieve date and time
FOR /F "skip=1 tokens=1-6" %%G IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
   IF "%%~L"=="" goto s_done
      Set _yyyy=%%L
      Set _mm=00%%J
      Set _dd=00%%G
      Set _hour=00%%H
      SET _minute=00%%I
)
:s_done

:: Pad digits with leading zeros
      Set _mm=%_mm:~-2%
      Set _dd=%_dd:~-2%
      Set _hour=%_hour:~-2%
      Set _minute=%_minute:~-2%

:: Display the date/time in ISO 8601 format:
Set _isodate=%_yyyy%-%_mm%-%_dd% %_hour%:%_minute%
Echo %_isodate%
pause

enter image description here


Method 1 (cmd+vb)

GetDate.cmd

@Echo off
For /f %%G in ('cscript /nologo getdate.vbs') do set _dtm=%%G
Set _yyyy=%_dtm:~0,4%
Set _mm=%_dtm:~4,2%
Set _dd=%_dtm:~6,2%
Set _hh=%_dtm:~8,2%
Set _nn=%_dtm:~10,2%
Echo %_yyyy%-%_mm%-%_dd%T%_hh%:%_nn%

getdate.vbs

Dim dt
dt=now
'output format: yyyymmddHHnn
wscript.echo ((year(dt)*100 + month(dt))*100 + day(dt))*10000 + hour(dt)*100 + minute(dt)

Tex Hex

Posted 2011-07-27T22:38:53.980

Reputation: 2 242

I included both scripts from your source link. Hope its ok for you – nixda – 2015-08-06T21:15:44.373

@nixda No problem, whatever the user helps. – Tex Hex – 2015-08-07T06:54:36.443

If you need to retain the seconds in "Method 2" above, add Set _second=00%%K when extracting from wmic and pad with leading zeros like the others. – Tim Parenti – 2018-04-06T20:21:27.100

1Ah ha, very neat way of finding the locale's date ordering. ss64 does have a nifty community of cmd.exe users. – Nicholi – 2011-07-28T22:06:35.330

12

Windows XP and later

getDate.cmd

@echo off
for /f "tokens=2 delims==" %%G in ('wmic os get localdatetime /value') do set datetime=%%G

set year=%datetime:~0,4%
set month=%datetime:~4,2%
set day=%datetime:~6,2%

echo %year%/%month%/%day%

Output

enter image description here

and31415

Posted 2011-07-27T22:38:53.980

Reputation: 13 382

+1 for the most concise answer. I'd also suggest ending with ECHO %year%-%month%-%day% which is ISO and filesystem compatible format (not to mention automatically sorts by year-month-day). :-). – Zephan Schroeder – 2019-04-09T23:59:24.873

3

I know it's not exactly what you asked for, but I use the Windows port of the Linux date application from a command inside the batch file and then assign the result to a variable.

I have yet to find a way to get the date reliably using only batch commands.

Hydaral

Posted 2011-07-27T22:38:53.980

Reputation: 1 674

2

Use this batch file for YYYY-MM-DD format. It uses the window instrumentation tool that should be present in all recent Windows versions to get a datetime string which is independent of regional settings.

Save to a batch file into the path (eg) c:\windows\rdate.bat then access with a CALL RDATE.BAT to set the variable(s). Alternately, copy the code into your batch file.

This date format is suitable for filenames and logging. It sorts correctly. The logtime variable adds a date+time variable as YYYY-MM-DD-HHMMSS suitable for use in logging batch file activity at second accuracy.

Adjust the date (and time) formats as you wish. REM the screen echos in production. The two numbers in each text selection are the zero-based start character index and the number of characters to copy, eg, %datetime:~0,4% takes a 4 character substring starting at position 0.

echo off
rem First, get the locality-invariant datetime
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I
rem echo %datetime%

rem Build the reverse date string YYYY-MM-DD
set rdate=%datetime:~0,4%-%datetime:~4,2%-%datetime:~6,2%
echo rdate=%rdate%

rem Built a datetime string YYYY-MM-DD-hhmmss
set logtime=%rdate%-%datetime:~8,6% 
echo logtime=%logtime%

jim birch

Posted 2011-07-27T22:38:53.980

Reputation: 21

1

Nearly the same as and31415's answer. Both scripts use wmic os get localdatetime

– nixda – 2015-08-06T21:27:02.537

1

While you are right that VS 2008 outputs a batchfile, you can run pretty much any program you want, including Powershell scripts and other programs.

Edit:

Here are some similar questions:

https://stackoverflow.com/questions/1051845/visual-studio-2008-professional-build-process https://stackoverflow.com/questions/3049369/embed-application-compilation-time-stamp

Originally, I was gonna have this moved to SO. . .

surfasb

Posted 2011-07-27T22:38:53.980

Reputation: 21 453

0

Thanks to Shekhar's post this works as needed and zero padding of the time.

@Echo Off

for /f "tokens=1-5 delims=:" %%d in ("%time%") do set var=%date:~10,4%%date:~4,2%%date:~7,2%-%%d%%e

set datetimestr=%var: =0%

set logfile=LogFile-%datetimestr%.txt

echo %logfile%

Output: LogFile-20151113-0901.txt

Trifused

Posted 2011-07-27T22:38:53.980

Reputation: 1

0

Have you tried using NET TIME \\%ComputerName% instead of DATE? I think that NET TIME is supposed to provide the data in a consistent format regardless of locale.

Kirk

Posted 2011-07-27T22:38:53.980

Reputation: 2 182

Nope, it doesn't. – AngryHacker – 2011-07-28T00:06:48.133

Interesting, I just tried it, switching between AU and US formats, and net time always output in m/d/yyyy format. @AngryHacker, with what settings did it not work for you? – Hydaral – 2011-07-28T01:15:30.883

1I switched French(Belgian) and it gave me 2011-07-27. The US give 07/27/2011 – AngryHacker – 2011-07-28T01:30:21.913

-1

This might be somewhat off topic but here is a .bat file that I wrote for my own scheduled backups and also call from postbuild actions in visual studio. I hope that some will find it useful.

Save the following into a .bat file

--------------------------------------------------
**:: The following is Copyright © 2012 ShopNetNuke Corp.  All rights reserved.
::  and released under the GNU General Public License (GPLv3)**

:: The following section retrieves the current date and time and formats it into the '%var%' variable
:: This format always ensures that the Date and Time are fixed length to avoid the situation of
:: having a value of '12/ 1/2012 rather than '12/01/2012'
echo off
for /f "tokens=1-5 delims=:" %%d in ("%time%") do set var=%date:~10,4%-%date:~4,2%-%date:~7,2%-%%d-%%e
set var=%var: =0%
echo Beginning my valuable Backup Set:  Backup--%var%

:: If you wanted to request the user input a filename prefix, 
:: then we would use something similar to this
:: set /p nameprefix= Enter the file name prefix?
:: Get the Current Date and Time
::for /f "tokens=1-5 delims=:" %%d in ("%time%") do set var=%date:~10,4%-%date:~4,2%-%date:~7,2%-%%d-%%e
:: set var=%var: =0%
:: echo Beginning my valuable Backup Set:  Backup--%var%_%nameprefix%

Pause

echo Starting SQL Server Database Backup Job...
:: The following line initiates the Backup job within SqlServer Agent.
:: Change 'MyBackupNameInSqlAgent' to the name of the job you want executed
:: Change the directory paths to those relevant to your current system installation directories
:: SqlAgent will not return a value if the backup action succeed, 
:: however, in the event an error is encountered, it will be echoed onto the screen
"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\sqlcmd.exe" -S SQLSERVERNAME\INSTANCENAME -Q "execute msdb.dbo.sp_start_job @job_name = 'MyBackupNameInSqlAgent'"
:: An error will be returned if the Backup job is not found or has already been triggered by another process

echo Starting My Valuable Source Code Directory Backup...

echo ...backing up files and folders in "C:\Source\MyPreciousProjectDirectory\"...
:: The following line will execute the 7zip command to create a .7z file of the directory named in 'MyPreciousProjectDirectory'
:: and tells it to put the archive in the 'MyPreciousBackupDirectory'.  The compression level will be defined by the 7zip default settings
:: The -p flag tells 7zip to password protect the archive, in this case, I've used the Date/Time portion of the filename as the password
:: remove the '-p%var%' section to remove password protection from the archive
"C:\Program Files\7-Zip\7z.exe" a -t7z C:\MyPreciousBackupDirectory\%var%\MyPreciousProject--%var%.7z -p%var% -mhe C:\Source\MyPreciousProjectDirectory\* 

echo Source Code Directory Backups complete.

echo Archiving Database Backups now...
:: The following line will execute the 7zip command to archive the Database backup.
:: The '*' could be replaced by the actual backup name.
:: The '*' indicates all files of type '.bak'
:: The -p flag tells 7zip to password protect the archive, in this case, again, I've used the Date/Time portion of the filename as the password
:: remove the '-p%var%' section to remove password protection from the archive
"C:\Program Files\7-Zip\7z.exe" a -t7z  C:\MyPreciousBackupDirectory\%var%\MyPreciousProject-Database-%var%.7z -p%var% -mhe "C:\Program Files\Microsoft SQL Server\MSSQL10.SQLDEV08\MSSQL\Backup\*.bak"

echo Database Backup Archival process complete.

:: If you wanted to place both the previous backups into one single combination archive,
:: you could do something like the following
"C:\Program Files\7-Zip\7z.exe" a -t7z C:\MyPreciousBackupDirectoryForSourceAndDatabase\%var%\MyPreciousProjectBackupSourceAndDatabase--%var%.7z -p%var% -mhe C:\Source\MyPreciousProjectDirectory\* 


echo Now attempting to copy archives to Network Server...
:: The following line will use xcopy to copy the arechives to the server backup directory and place them in a directory named by the DateTime variable %var%
xcopy /S /I /J /Y C:\MyPreciousBackupDirectory\%var% \\MyPreciousBackupServerName\SourceCode\MyPreciousServerBackupDirectory\%var%
:: Or if the combination above was used then copy that...
xcopy /S /I /J /Y C:\MyPreciousBackupDirectoryForSourceAndDatabase\%var% \\MyPreciousBackupServerName\SourceCode\MyPreciousServerBackupDirectory\%var%


echo 7z Archive files transferred to MyPreciousBackupServerName successfully
echo  ||
echo \||/
echo  \/
echo ---------------------------------------------------
echo ----- BACKUP SET "%var%" COMPLETE ------
echo ---------------------------------------------------
pause

J.C

Posted 2011-07-27T22:38:53.980

Reputation: 1

1tl;dr , you might add an explanation of what the script does. because it does not come off as a solution right away. It might also be more useful, if you can remove the non pertinent bits of code – Shekhar – 2012-12-20T22:09:02.910

1The whole batch script relies on the %date% and %time% variables, which are locale-aware, and can't really be parsed in a predictable way as the OP asked. – and31415 – 2014-02-22T19:02:27.390