23

The %DATE% and %TIME% environment variables provide the current date and time on Windows machines on the command line and inside a batch file.

Sadly, those values are locale-aware! Meaning that, say, on a German machine, you will get

26.1.2011

instead of

2011-26-01

this screws up sorting if you want to use this variable in a file name.

Is there any easy way to get hold of a locale-unaware YYYY-MM-DD date string in a Windows batch file?

For the moment, I am working with this rather kludgy workaround:

for /f "tokens=1,2,3,4 delims=. " %%i in ('date /t') do set date=%%k-%%j-%%i
echo %date%

but this is now German locale specific - obviously, a completely independent solution would be much nicer.

The OS in question is Server 2008. I would much prefer not using a third party tool, if at all possible.

Pekka
  • 2,158
  • 3
  • 19
  • 32

4 Answers4

25

There were a few attempts (Rob van der Woude had something), but nothing really worked across all locales. However, you can get the current time in a easily-parseable format via

wmic os get LocalDateTime

The following gets you at least UTC already:

@echo off
rem Get the time from WMI - at least that's a format we can work with
set X=
for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do if not defined X set X=%%x
echo.%X%

rem dissect into parts
set DATE.YEAR=%X:~0,4%
set DATE.MONTH=%X:~4,2%
set DATE.DAY=%X:~6,2%
set DATE.HOUR=%X:~8,2%
set DATE.MINUTE=%X:~10,2%
set DATE.SECOND=%X:~12,2%
set DATE.FRACTIONS=%X:~15,6%
set DATE.OFFSET=%X:~21,4%

echo %DATE.YEAR%-%DATE.MONTH%-%DATE.DAY% %DATE.HOUR%:%DATE.MINUTE%:%DATE.SECOND%.%DATE.FRACTIONS%

However, you probably need to account for the time zone offset (unless it's for a log file, then I'd always use UTC) but that's nothing a bit of calculation cannot do :-)

Joey
  • 1,823
  • 11
  • 13
  • 1
    Excellent, this looks exactly like what I need! Thank you. – Pekka Jan 26 '11 at 21:56
  • 2
    For the record: `for /f %%x in ('wmic os get localdatetime ^| findstr /b [0-9]') do @set X=%%x` is a tiny bit nicer. There's also a [more compact version available over here](http://stackoverflow.com/a/203116/), namely in [that comment](http://stackoverflow.com/questions/203090/how-to-get-current-datetime-on-windows-command-line-in-a-suitable-format-for-us#comment14652563_203116). – Tomalak Jan 22 '14 at 10:09
  • It's a bit hard finding and updating all old instances where you wrote something :). I'd probably use Win32_UTCTime and Win32_LocalTime by now. – Joey Jan 22 '14 at 11:57
  • really fantastic! – jeromerg Feb 22 '18 at 15:57
  • As @Tomalak says, the `findstr` solution is much better, as for my case, the original `for` (without the `skip`) iterates 3 times. Once for the word `"LocalDateTime"`, a second time for the actual date, and a third time for an empty value (maybe a line break?). – cavpollo Nov 22 '19 at 04:31
  • Note that this only works inside a `.bat` file. To paste it directly into a cmd window you need to replace each `%%` with `%` – xjcl Jan 20 '21 at 12:26
14

Here's a two-liner I've been using, which seems to work regardless of Windows version or local time settings:

FOR /f %%a in ('WMIC OS GET LocalDateTime ^| find "."') DO set DTS=%%a
set CUR_DATE=%DTS:~0,4%-%DTS:~4,2%-%DTS:~6,2%

This will set a variable called %CUR_DATE% in the following ISO standard format:

yyyy-mm-dd

I tried making it a one-liner with &&, but it didn't seem to take, so I resorted to the two-line version. Hope this helps.

Vocatus Gate
  • 141
  • 1
  • 3
0

Here is my solution to this problem:

@echo off

set curtime=
for /f "tokens=*" %%x in ('powershell -NoLogo -NonInteractive -OutputFormat Text -Command "[DateTime]::Now.ToString(\"yyyy-MM-dd HH:mm:ss\")"') do set curtime=%%x
echo %curtime%

Of course, the same as UTC time:

set curtime=
for /f "tokens=*" %%x in ('powershell -NoLogo -NonInteractive -OutputFormat Text -Command "[DateTime]::UtcNow.ToString(\"yyyy-MM-dd HH:mm:ssK\")"') do set curtime=%%x
echo %curtime%

You may play with formatting as much as you like, the output is stable independent from Windows of CurrentLocale (here is minimal knowledge of Powershell and .Net required).

Dave M
  • 4,494
  • 21
  • 30
  • 30
0

I use this trick to get UTC..

for /f "tokens=*" %%i in ('tzutil /g') do set CTZ=%%i
tzutil /s UTC
set UTC=
for /f  "skip=1 delims=" %%i in ('WMIC OS GET LocalDateTime') do if not defined UTC set UTC=%%i
tzutil /s "%CTZ%"
set UTC=%UTC:~0,4%-%UTC:~4,2%-%UTC:~6,3%T%UTC:~8,13%
echo %UTC%

However it does have the side effect of briefly changing the entire system to UTC. This is probably OK on a personal workstation, but not sure what the impact would be a large production server, which should probably be set to UTC anyway.

mark d drake
  • 101
  • 1