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

118,261

Solution 1

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)

Solution 2

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

Solution 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.

Solution 4

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%

Solution 5

I would like to offer a variation to the excellent GetDate.cmd answer of Tex Hex, and use the wmic parameter "/format:list" instead, to assign the values straight away to batch variables, as demonstrated below. To add the leading zeroes, I used another FOR loop, instead of dealing with each variable individually. It's not much shorter (in total bytes) nor faster, simply a different way of doing it:

@ECHO OFF
REM Defines variables _Year (4 digits), _Month (01-12), _Day (01-31), _DayOfWeek (0=Sun, 1=Mon etc), _Hour (00-23), _Minute (00-59), _Second (00-59)

setlocal EnableDelayedExpansion
FOR /F %%I IN ('WMIC path win32_localtime get Year^,Month^,Day^,DayOfWeek^,Hour^,Minute^,Second /format:list^|FINDSTR "="') DO SET _%%I
FOR /F "tokens=1 delims==" %%I IN ('set _^|FINDSTR /R "^_[DHMS][aoie][^k]*$"') DO SET %%I=0!%%I!&SET %%I=!%%I:~-3!

:: Display the date/time and day of week
ECHO %_Year%-%_Month%-%_Day% %_Hour%:%_Minute%:%_Second% (day %_DayOfWeek%)

::if this script is called from another script, 'endlocal' will be assumed and our variables will be gone. So use a trick to retain them:
set _>%TEMP%\%~n0.tmp
endlocal&(FOR /F %%I IN (%TEMP%\%~n0.tmp) DO SET %%I)&del %TEMP%\%~n0.tmp

I included DayOfWeek, in case someone needs it too.

Note: If this script is called from another batch script, endlocal would be assumed at the end of this one, and our variables _Year etc. would be gone. Therefore we cannot ommit endlocal, and need to use a trick to keep the variables that we have defined. I thought it could be done easily, using endlocal& FOR /F %%I IN ('set _') DO SET %%I, but that does not work, says variable _ is not defined... For that reason I resorted to a temporary file instead.

Furthermore, since the calling script might also be using variable names starting with an underscore, I included a check that the variables whose values I am altering start with a certain capital followed by a certain lower case letter. (Batch variable names are not case sensitive, but FINDSTR by default is.) So if your script is using variable names starting with underscores, make sure they are all lower case (or all upper case) and everything will be fine.

Share:
118,261

Related videos on Youtube

gardenofwine
Author by

gardenofwine

Updated on September 18, 2022

Comments

  • gardenofwine
    gardenofwine almost 2 years

    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?

    • Adrien
      Adrien almost 13 years
      Are you absolutely restricted to Batch? Such a thing is much simpler in VBScript/WSH and/or PowerShell ...
    • gardenofwine
      gardenofwine almost 13 years
      @Adrien, Yes limited to batch - it's part of the VS2008 post-build step.
    • MagTun
      MagTun over 8 years
      replacing %date% by %date:~6,4%-%date:~3,2%-%date:~0,2% worked
  • gardenofwine
    gardenofwine almost 13 years
    Nope, it doesn't.
  • Hydaral
    Hydaral almost 13 years
    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?
  • gardenofwine
    gardenofwine almost 13 years
    I switched French(Belgian) and it gave me 2011-07-27. The US give 07/27/2011
  • Nicholi
    Nicholi almost 13 years
    Ah ha, very neat way of finding the locale's date ordering. ss64 does have a nifty community of cmd.exe users.
  • Shekhar
    Shekhar over 11 years
    tl;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
  • nixda
    nixda almost 9 years
    I included both scripts from your source link. Hope its ok for you
  • nixda
    nixda almost 9 years
    Nearly the same as and31415's answer. Both scripts use wmic os get localdatetime
  • core
    core almost 9 years
    @nixda No problem, whatever the user helps.
  • Tim Parenti
    Tim Parenti about 6 years
    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.
  • Zephan Schroeder
    Zephan Schroeder about 5 years
    +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). :-).
  • Ronny D'Hoore
    Ronny D'Hoore about 4 years
    I like this approach of using wmic very much. I found it could be "automated" more, using only FOR loops. I added an answer demonstrating that.
  • Vomit IT - Chunky Mess Style
    Vomit IT - Chunky Mess Style about 4 years
    I think you mean findstr arguments or parameters values are case sensitive and especially if you use the /R which with regular expressions and not the /I switch to indicate it to not be case sensitive otherwise when not using /R.
  • Ronny D'Hoore
    Ronny D'Hoore about 4 years
    @PimpJuice True. Note however that in other places /I and /R could safely be combined (especially as /R is the default and can be omitted, but I added it here to make it clear that I'm indeed using regular expressions).
  • Ronny D'Hoore
    Ronny D'Hoore about 4 years
    By the way, there is a little mystery in my code. See how I'm taking the last three characters of the variable, instead of the last two? Don't ask me why... If I write "2" instead of 3, it only returns the last character. If I write "3", it returns the last 2 characters. I was investigating this for at least 15 minutes but could not find any satisfactory explanation. It has nothing to do with trailing spaces after a SET or anything like that...
  • Richard Williams
    Richard Williams over 3 years
    There's actually a known window's bug with this method where the daylight saving time is sometimes applied and sometimes not - see serverfault.com/a/1013531/296119. This doesn't seem to happen with the WMIC Path Win32_LocalTime... method.