243

In a Windows (Windows XP) batch script I need to format the current date and time for later use in files names, etc.

It is similar to Stack Overflow question How to append a date in batch files, but with time in as well.

I have this so far:

echo %DATE%
echo %TIME%
set datetimef=%date:~-4%_%date:~3,2%_%date:~0,2%__%time:~0,2%_%time:~3,2%_%time:~6,2%
echo %datetimef%

which gives:

28/07/2009
 8:35:31.01
2009_07_28__ 8_36_01

Is there a way I can allow for a single digit hour in %TIME%, so I can get the following?

2009_07_28__08_36_01
Community
  • 1
  • 1
laurie
  • 6,011
  • 4
  • 29
  • 22
  • 1
    Possible duplicate of [How to get current datetime on Windows command line, in a suitable format for using in a filename?](http://stackoverflow.com/questions/203090/how-to-get-current-datetime-on-windows-command-line-in-a-suitable-format-for-us) – IInspectable Jan 19 '16 at 03:23
  • [Split %date% in a batch file regardless of Regional Settings](http://stackoverflow.com/q/15378719/995714) – phuclv Aug 23 '16 at 16:24
  • You can replace empty spaces on your `datetimef` variable, and put 0's instead. On your example: `SET datetimef=%datetimef: =0%` – SebaGra Apr 22 '20 at 13:00

37 Answers37

171

I ended up with this script:

set hour=%time:~0,2%
if "%hour:~0,1%" == " " set hour=0%hour:~1,1%
echo hour=%hour%
set min=%time:~3,2%
if "%min:~0,1%" == " " set min=0%min:~1,1%
echo min=%min%
set secs=%time:~6,2%
if "%secs:~0,1%" == " " set secs=0%secs:~1,1%
echo secs=%secs%

set year=%date:~-4%
echo year=%year%

:: On WIN2008R2 e.g. I needed to make your 'set month=%date:~3,2%' like below ::otherwise 00 appears for MONTH

set month=%date:~4,2%
if "%month:~0,1%" == " " set month=0%month:~1,1%
echo month=%month%
set day=%date:~0,2%
if "%day:~0,1%" == " " set day=0%day:~1,1%
echo day=%day%

set datetimef=%year%%month%%day%_%hour%%min%%secs%

echo datetimef=%datetimef%
laurie
  • 6,011
  • 4
  • 29
  • 22
  • 11
    FYI, on Windows Server 2003 and on Windows 7, this script gave me "201200Mo_085806" (correct year & time). – sfuqua Apr 09 '12 at 14:01
  • 56
    As note for someone who will come here from Google (like me): This is locale dependent, so it may require tweaks to work on non-english Windows! – PiotrK Jan 12 '13 at 22:28
  • i did it this way: Time /T > Time.dat set /P ftime= < Time.dat set fDate=%date:~6%%date:~3,2%%date:~0,2%%ftime:~0,2%%ftime:~3,2% echo %fDate% -> 201310170928 – Ice Oct 17 '13 at 07:43
  • What does %time:~0,2% do where is some documentation on the :~,% structure? – user1605665 Nov 11 '14 at 04:43
  • 7
    All this can be done in just 2 lines using ordinary string replacement: http://stackoverflow.com/a/23558738/1879699 – Andreas Apr 22 '16 at 09:34
  • You could do the following `set ptime= && FOR /F "tokens=1,* delims=:" %a IN ('TIME /T') DO ( set ptime=%a%b ) && echo %ptime%` – Peter Wright Dec 20 '16 at 08:47
  • 1
    FYI, the DAY is wrong when you pull it back. Should %date:~7,2%.. If you use %date:~0,2% it comes back as the day of week, not the day of month. – Chizl Oct 11 '21 at 13:10
95

I usually do it this way whenever I need a date/time string:

set dt=%DATE:~6,4%_%DATE:~3,2%_%DATE:~0,2%__%TIME:~0,2%_%TIME:~3,2%_%TIME:~6,2%
set dt=%dt: =0%

This is for the German date/time format (dd.mm.yyyy hh:mm:ss). Basically I concatenate the substrings and finally replace all spaces with zeros.

The resulting string has the format: yyyy_mm_dd__hh_mm_ss


Short explanation of how substrings work:

%VARIABLE:~num_chars_to_skip,num_chars_to_keep%

So to get just the year from a date like "29.03.2018" use:

%DATE:~6,4%
       ^-----skip 6 characters
         ^---keep 4 characters 
Andreas
  • 5,393
  • 9
  • 44
  • 53
  • 10
    by far the most elegant solution when you just need a clean timestamp (no spaces or other chars) – jvdneste Feb 13 '15 at 08:52
  • 1
    Best answer since it explains how to print the variables instead of forcing some substring that can be different for a lot of people. I would always run echo %date%_%time% first to see what the variables alone print for me and then decide what substrings of those i wanna keep. – Tomislav3008 Jul 27 '21 at 08:15
  • How do you get the UTC-timezone as well, e.g. adding `+01` in the end of the resulting string? – Andreas L. Nov 26 '21 at 15:31
  • @AndreasL. Getting the timezone information on the commandline involves other tools. You can utilise `systeminfo` for example, like this: `for /F "tokens=2 delims=^(: " %i in ('systeminfo^|find "Zeit"') do set "tz=%i"` (assuming you are using a german Windows). Note that if you want to use his in a batch file you need to double the `%s`. – Andreas Nov 26 '21 at 21:06
81

Here is how I generate a log filename (based on http://ss64.com/nt/syntax-getdate.html):

@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
      SET _second=00%%K
)
:s_done

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

Set logtimestamp=%_yyyy%-%_mm%-%_dd%_%_hour%_%_minute%_%_second%
goto make_dump

:s_error
echo WMIC is not available, using default log filename
Set logtimestamp=_

:make_dump
set FILENAME=database_dump_%logtimestamp%.sql
...
nightcoder
  • 13,149
  • 16
  • 64
  • 72
75
@ECHO OFF
: Sets the proper date and time stamp with 24Hr Time for log file naming
: convention ('YYYYMMDD_HHMMSS')

: Scrapes the characters out of their expected permissions in the date/time
: environment variables.

: Expects a date format of '____MM_DD_YYYY'
: Expects a time format of 'HH:MM:SS' or ' H:MM:SS'

SET HOUR=%time:~0,2%
SET dtStamp9=%date:~-4%%date:~4,2%%date:~7,2%_0%time:~1,1%%time:~3,2%%time:~6,2% 
SET dtStamp24=%date:~-4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%

if "%HOUR:~0,1%" == " " (SET dtStamp=%dtStamp9%) else (SET dtStamp=%dtStamp24%)

ECHO %dtStamp%

PAUSE
mwfearnley
  • 3,303
  • 2
  • 34
  • 35
  • 2
    On Windows Server 2003 and on Windows 7, this gave me the correct string. Much more elegant than what I've constructed in the past, so thank you! – sfuqua Apr 09 '12 at 14:02
  • 3
    Here is what it gives me in Windows 7 with russian locale. Current time is 2013-05-03T02:22:51, but the script prints: "2013-5.-01_02_22_51" – nightcoder May 02 '13 at 22:24
  • 8
    The %date% will give different string with different locale. – AechoLiu Nov 12 '13 at 09:04
  • 2
    returns 20146.0._173502 to me (czech locale) – Muflix Oct 16 '14 at 15:36
  • 2
    win7 64bit ultimate, incorrect time: 20140.01_131612 , must be(2014.10.26_131612) – jmp Oct 26 '14 at 11:16
52

If PowerShell is installed, then you can easily and reliably get the Date/Time in any format you'd like, for example:

for /f %%a in ('powershell -Command "Get-Date -format yyyy_MM_dd__HH_mm_ss"') do set datetime=%%a
move "%oldfile%" "backup-%datetime%"

Of course nowadays PowerShell is always installed, but on Windows XP you'll probably only want to use this technique if your batch script is being used in a known environment where you know PS is available (or check in your batch file if PowerShell is available...)

You may reasonably ask: why use a batch file at all if you can use PowerShell to get the date/time, but I think some obvious reasons are: (a) you're not all that familiar with PowerShell and still prefer to do most things the old-fashioned way with batch files or (b) you're updating an old script and don't want to port the whole thing to PS.

G. Lombard
  • 3,569
  • 1
  • 29
  • 30
36

I came across this problem today and solved it with:

SET LOGTIME=%TIME: =0%

It replaces spaces with 0s and basically zero-pads the hour.

After some quick searching I didn't find out if it required command extensions (still worked with SETLOCAL DISABLEEXTENSIONS).

opello
  • 3,254
  • 2
  • 23
  • 23
  • OK, substitusion in variables. Now - how to substitute a colon (`:`)? – Tomasz Gandor Sep 19 '17 at 05:42
  • @TomaszGandor This works for me: `echo %TIME: =:%` but if it isn't maybe try escaping the `:` with a `^` like `echo %TIME: =^:%` (which also works for me). – opello Sep 19 '17 at 15:45
  • 1
    +1 for simplicity. Colons aren't valid in filenames. set theTime=%Time::=% deletes them. Can you substitute 0 for space, delete the colons, and truncate to 6 characters (thus deleting the decimal part) in a single statement? It's not that big of deal if it takes two or three lines. I'm just curious. – riderBill Mar 26 '18 at 01:36
  • Not that I know. Please follow-up if you find one! – opello Mar 27 '18 at 19:42
20

As has been noted, parsing the date and time is only useful if you know the format being used by the current user (for example, MM/dd/yy or dd-MM-yyyy just to name two). This could be determined, but by the time you do all the stressing and parsing, you will still end up with some situation where there is an unexpected format used, and more tweaks will be be necessary.

You can also use some external program that will return a date slug in your preferred format, but that has disadvantages of needing to distribute the utility program with your script/batch.

There are also batch tricks using the CMOS clock in a pretty raw way, but that is tooo close to bare wires for most people, and also not always the preferred place to retrieve the date/time.

Below is a solution that avoids the above problems. Yes, it introduces some other issues, but for my purposes I found this to be the easiest, clearest, most portable solution for creating a datestamp in .bat files for modern Windows systems. This is just an example, but I think you will see how to modify for other date and/or time formats, etc.

reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f
reg add "HKCU\Control Panel\International" /v sShortDate /d "yyMMdd" /f
@REM reg query "HKCU\Control Panel\International" /v sShortDate
set LogDate=%date%
reg copy "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jph
  • 275
  • 2
  • 3
  • 12
    This is a terrible solution. If it fails then a global setting is permanently changed. It also introduces race conditions with other applications. – MikeKulls Aug 13 '15 at 06:25
  • You could use the `reg query "HKCU\Control Panel\International" /v sShortDate`part without changing the registry setting (exercise left to the reader!). – tricasse Nov 19 '15 at 13:27
14

If you don't exactly need this format:

2009_07_28__08_36_01

Then you could use the following 3 lines of code which uses %date% and %time%:

set mydate=%date:/=%
set mytime=%time::=%
set mytimestamp=%mydate: =_%_%mytime:.=_%

Note: The characters / and : are removed and the character . and space is replaced with an underscore.

Example output (taken Wednesday 8/5/15 at 12:49 PM with 50 seconds and 93 milliseconds):

echo %mytimestamp%
Wed_08052015_124950_93
Jesse
  • 1,603
  • 19
  • 20
  • 1
    when hour is less than 12, set mydate=%date:/=% set mytime=%time::=% set mytime=%mytime: =0% set mytimestamp=%mydate: =_%_%mytime:.=_% – ragche Jul 20 '17 at 09:37
9

The following may not be a direct answer but a close one?

set hour=%time:~0,2%
if "%hour:~0,1%" == " " set datetimef=%date:~-4%_%date:~3,2%_%date:~0,2%__0%time:~1,2%_%time:~3,2%_%time:~6,2%
else set datetimef=%date:~-4%_%date:~3,2%_%date:~0,2%__%time:~0,2%_%time:~3,2%_%time:~6,2%

At least it may be inspiring.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ufukgun
  • 6,889
  • 8
  • 33
  • 55
  • Answers using `%date%`/`%time%` are heavily dependent on locale settings. What format does this one expect? – mwfearnley Jul 09 '21 at 13:09
9
REM Assumes UK style date format for date environment variable (DD/MM/YYYY).
REM Assumes times before 10:00:00 (10am) displayed padded with a space instead of a zero.
REM If first character of time is a space (less than 1) then set DATETIME to:
REM YYYY-MM-DD-0h-mm-ss
REM Otherwise, set DATETIME to:
REM YYYY-MM-DD-HH-mm-ss
REM Year, month, day format provides better filename sorting (otherwise, days grouped
REM together when sorted alphabetically).

IF "%time:~0,1%" LSS "1" (
   SET DATETIME=%date:~6,4%-%date:~3,2%-%date:~0,2%-0%time:~1,1%-%time:~3,2%-%time:~6,2%
) ELSE (
   SET DATETIME=%date:~6,4%-%date:~3,2%-%date:~0,2%-%time:~0,2%-%time:~3,2%-%time:~6,2%
)

ECHO %DATETIME%
Mike Raynham
  • 91
  • 1
  • 1
  • Just to say I'm from the UK, but at some point I changed my date format to yyyy-mm-dd, so this doesn't work for me. – mwfearnley Jul 09 '21 at 13:08
7

The offset:length formatting supported with the SET command in Windows will not allow you to pad the 0 as you seem to be interested in.

However, you can code a BATCH script to check for the hour being less than 10 and
pad accordingly with a different echo string.

You will find some information on the SET command on this link.


You can also change to other programming methods to get here.

It is quite simple in unix bash (available with Cygwin on Windows) to just say,

date +%Y_%m_%d__%H_%M_%S

And, it always pads correctly.

nik
  • 13,254
  • 3
  • 41
  • 57
7

I did it this way:

REM Generate FileName from date and time in format YYYYMMTTHHMM

Time /T > Time.dat
set /P ftime= < Time.dat

set FileName=LogFile%date:~6%%date:~3,2%%date:~0,2%%ftime:~0,2%%ftime:~3,2%.log

echo %FileName%

LogFile201310170928.log

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ice
  • 1,162
  • 3
  • 14
  • 27
  • It runs on english server (OS Name: Microsoft(R) Windows(R) Server 2003 Standard x64 Edition, OS Version:5.2.3790 Service Pack 2 Build 3790) – Ice Oct 17 '13 at 13:35
  • 1
    and also tested on german server (Betriebssystemname: Microsoft® Windows Server® 2008 Enterprise, Betriebssystemversion:6.0.6002 Service Pack 2 Build 6002) – Ice Oct 17 '13 at 13:38
  • 1
    Even this one ist ok: (Betriebssystemname: Microsoft Windows Server 2012 Standard, Betriebssystemversion: 6.2.9200 Nicht zutreffend Build 9200) – Ice Oct 17 '13 at 13:43
7

I'm really new to batch files and this is my code!! (I am not sure why, but I couldn't combine date /t and time /t together and I couldn't use %date% and %time% directly without a variable...)

@ECHO OFF
set ldt=%date% %time%
echo %ldt%>> logs.txt
EXIT

It is kind of reused from others (the question was to get a formatted timedate to use as filename).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kelly
  • 143
  • 1
  • 2
  • 8
6

This batch script will do exactly what the O.P. wants (tested on Windows XP SP3).

I also used that clever registry trick described by "jph" previously which IMHO is the simplest way of getting 100% consistent formatting of the date to "yyyy_MM_dd" on any Windows system new or old. The change to one Registry value for doing this is instantaneous temporary and trivial; it only lasts a few milliseconds before it is immediately reverted back.

Double-click this batch file for an instant demo, Command Prompt window will pop up and display your timestamp . . . . .

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: generates a custom formatted timestamp string using date and time.
:: run this batch file for an instant demo.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

@ECHO OFF
SETLOCAL & MODE CON:COLS=80 LINES=15 & COLOR 0A

:: --- CHANGE THE COMPUTER DATE FORMAT TEMPORARILY TO MY PREFERENCE "yyyy_MM_dd",
REG COPY "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f 2>nul >nul
REG ADD "HKCU\Control Panel\International" /v sShortDate /d "yyyy_MM_dd" /f 2>nul >nul

SET MYDATE=%date%

:: --- REVERT COMPUTER DATE BACK TO SYSTEM PREFERENCE
REG COPY "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f 2>nul >nul
REG DELETE "HKCU\Control Panel\International-Temp" /f 2>nul >nul

:: --- SPLIT THE TIME [HH:MM:SS.SS] TO THREE SEPARATE VARIABLES [HH] [MM] [SS.SS]
FOR /F "tokens=1-3 delims=:" %%A IN ('echo %time%') DO (
SET HOUR=%%A
SET MINUTES=%%B
SET SECONDS=%%C
)

:: --- CHOOSE ONE OF THESE TWO OPTIONS :
:: --- FOR 4 DIGIT SECONDS        //REMOVES THE DOT FROM THE SECONDS VARIABLE [SS.SS]
:: SET SECONDS=%SECONDS:.=%
:: --- FOR 2 DIGIT SECONDS        //GETS THE FIRST TWO DIGITS FROM THE SECONDS VARIABLE [SS.SS]
SET SECONDS=%SECONDS:~0,2% 

:: --- FROM 12 AM TO 9 AM, THE HOUR VARIABLE WE EXTRACTED FROM %TIME% RETURNS A SINGLE DIGIT, 
:: --- WE PREFIX A ZERO CHARACTER TO THOSE CASES, SO THAT OUR WANTED TIMESTAMP
:: --- ALWAYS GENERATES DOUBLE-DIGIT HOURS (24-HOUR CLOCK TIME SYSTEM).
IF %HOUR%==0 (SET HOUR=00)
IF %HOUR%==1 (SET HOUR=01)
IF %HOUR%==2 (SET HOUR=02)
IF %HOUR%==3 (SET HOUR=03)
IF %HOUR%==4 (SET HOUR=04)
IF %HOUR%==5 (SET HOUR=05)
IF %HOUR%==6 (SET HOUR=06)
IF %HOUR%==7 (SET HOUR=07)
IF %HOUR%==8 (SET HOUR=08)
IF %HOUR%==9 (SET HOUR=09)

:: --- GENERATE OUR WANTED TIMESTAMP
SET TIMESTAMP=%MYDATE%__%HOUR%_%MINUTES%_%SECONDS%

:: --- VIEW THE RESULT IN THE CONSOLE SCREEN
ECHO.
ECHO    Generate a custom formatted timestamp string using date and time.
ECHO.
ECHO    Your timestamp is:    %TIMESTAMP%
ECHO.
ECHO.
ECHO    Job is done. Press any key to exit . . .
PAUSE > NUL

EXIT
derty2
  • 106
  • 2
  • 4
  • Works on Windows 2019 too. I'll keep your solution around, I like it :) – user225479 Sep 15 '19 at 17:02
  • Question, I just discovered that after midnight, the trailing "0" gets dropped in the output. Any idea as of why? My output with your script gives: Your timestamp is: 2019_09_16__0_58_07 Instead of ..00_58_07. But after 1 o'clock it works as expected (and it will give output: ..01_01_56). – user225479 Sep 15 '19 at 23:07
  • I added IF %HOUR%==0 (SET HOUR=00) to the ELSE statement. That should fix it, I hope :) – user225479 Sep 16 '19 at 16:51
  • 1
    Thanks for the feedback @user225479 . I have fixed the code . All possible permutations of the HOUR variable converted to 24 HOUR format will now work correctly . I have also modified the layout so that it is easier to read. – derty2 May 09 '20 at 14:55
  • `set hour=0%hour%` then `set hour=%hour:~-2%` is far simpler than all those `if` statements! (substring - starting 2 back from end.) – JGFMK Nov 25 '22 at 07:36
6
::========================================================================  
::== CREATE UNIQUE DATETIME STRING IN FORMAT YYYYMMDD-HHMMSS   
::======= ================================================================  
FOR /f %%a IN ('WMIC OS GET LocalDateTime ^| FIND "."') DO SET DTS=%%a  
SET DATETIME=%DTS:~0,8%-%DTS:~8,6%  

The first line always outputs in this format regardles of timezone:
20150515150941.077000+120
This leaves you with just formatting the output to fit your wishes.

Kees
  • 611
  • 7
  • 3
5

There is another easy way of doing it:

set HH=%time:~0,2%
if %HH% LEQ 9 (
set HH=%time:~1,1%
)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
vijay
  • 51
  • 1
  • 1
4

This bat file (save as datetimestr.bat) produces the datetime string 3 times: (1) long datetime string with day of week and seconds, (2) short datetime string without them and (3) short version of the code.

@echo off
REM "%date: =0%" replaces spaces with zeros
set d=%date: =0%
REM "set yyyy=%d:~-4%" pulls the last 4 characters
set yyyy=%d:~-4%
set mm=%d:~4,2%
set dd=%d:~7,2%
set dow=%d:~0,3%
set d=%yyyy%-%mm%-%dd%_%dow%

set t=%TIME: =0%
REM "%t::=%" removes semi-colons
REM Instead of above, you could use "%t::=-%" to 
REM replace semi-colons with hyphens (or any 
REM non-special character)
set t=%t::=%
set t=%t:.=%

set datetimestr=%d%_%t%
@echo  Long date time str = %datetimestr%

set d=%d:~0,10%
set t=%t:~0,4%
set datetimestr=%d%_%t%
@echo Short date time str = %datetimestr%


@REM Short version of the code above
set d=%date: =0%
set t=%TIME: =0%
set datetimestr=%d:~-4%-%d:~4,2%-%d:~7,2%_%d:~0,3%_%t:~0,2%%t:~3,2%%t:~6,2%%t:~9,2%
@echo Datetimestr = %datetimestr%

pause

To give proper credit, I merged the concepts from Peter Mortensen (Jun 18 '14 at 21:02) and opello (Aug 25 '11 at 14:27).

You can write this much shorter, but this long version makes reading and understanding the code easy.

cadvena
  • 1,063
  • 9
  • 17
3

I like the short version on top of @The lorax, but for other language settings it might be slightly different.

For example, in german language settings (with natural date format: dd.mm.yyyy) the month query has to be altered from 4,2 to 3,2:

@ECHO OFF
: Sets the proper date and time stamp with 24h time for log file naming convention i.e.

SET HOUR=%time:~0,2%
SET dtStamp9=%date:~-4%%date:~3,2%%date:~7,2%_0%time:~1,1%%time:~3,2%%time:~6,2% 
SET dtStamp24=%date:~-4%%date:~3,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%

if "%HOUR:~0,1%" == " " (SET dtStamp=%dtStamp9%) else (SET dtStamp=%dtStamp24%)

ECHO %dtStamp%
: Outputs= 20160727_081040
: (format: YYYYMMDD_HHmmss; e.g.: the date-output of this post timestamp)

PAUSE
webMac
  • 185
  • 1
  • 2
  • 11
3

To generate a YYYY-MM-DD hh:mm:ss (24-hour) timestamp I use:

SET CURRENTTIME=%TIME%
IF "%CURRENTTIME:~0,1%"==" " (SET CURRENTTIME=0%CURRENTTIME:~1%)
FOR /F "tokens=2-4 delims=/ " %%A IN ('DATE /T') DO (SET TIMESTAMP=%%C-%%A-%%B %CURRENTTIME%)
sourcenouveau
  • 29,356
  • 35
  • 146
  • 243
  • Does it assume a particular regional setting? – Peter Mortensen Jun 18 '14 at 21:06
  • 2
    According to http://ss64.com/nt/syntax-variables.html the `%TIME%` and `%DATE%` variables use the same format as the `TIME` and `DATE` commands, respectively. On my system the variables don't match my regional settings. – sourcenouveau Jun 19 '14 at 12:02
2

This is my 2 cents for adatetime string. On MM DD YYYY systems switch the first and second %DATE:~ entries.

    REM ====================================================================================
    REM CREATE UNIQUE DATETIME STRING FOR ADDING TO FILENAME
    REM ====================================================================================
    REM Can handle dd DDxMMxYYYY and DDxMMxYYYY > CREATES YYYYMMDDHHMMSS (x= any character)
    REM ====================================================================================
    REM CHECK for SHORTDATE dd DDxMMxYYYY 
    IF "%DATE:~0,1%" GTR "3" (
        SET DATETIME=%DATE:~9,4%%DATE:~6,2%%DATE:~3,2%%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%
    ) ELSE (
    REM ASSUMES SHORTDATE DDxMMxYYYY
        SET DATETIME=%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%
        )
    REM CORRECT FOR HOURS BELOW 10
    IF %DATETIME:~8,2% LSS 10 SET DATETIME=%DATETIME:~0,8%0%DATETIME:~9,5%
    ECHO %DATETIME%
Case
  • 21
  • 2
2
set hourstr = %time:~0,2%
if "%time:~0,1%"==" " (set hourstr=0%time:~1,1%)
set datetimestr=%date:~0,4%%date:~5,2%%date:~8,2%-%hourstr%%time:~3,2%%time:~6,2%
Will Wu
  • 553
  • 4
  • 15
2

Create a file called "search_files.bat" and place the contents below into the file. Then double click it. The temporary %THH% variable was put in place to handle the AM appropriately. If there is a 0 in the first 2 digits of the time, Windows ignores the rest of the file name of the LOG file.

CD .
SET THH=%time:~0,2%
SET THH=%THH: =0%
dir /s /b *.* > %date:~10,4%-%date:~4,2%-%date:~7,2%@%THH%.%time:~3,2%.%time:~6,2%.LOG
JustBeingHelpful
  • 18,332
  • 38
  • 160
  • 245
2

You may use these...

Parameters:
%date:~4,2% -- month
%date:~7,2% -- days
%date:~10,4% -- years

%time:~1,1% -- hours
%time:~3,2% -- minutes
%time:~6,2% -- seconds
%time:~9,2% -- mili-seconds

%date:~4,2%%date:~7,2%%date:~10,4% : MMDDYYYY
%date:~7,2%%date:~4,2%%date:~10,4% : DDMMYYYY
%date:~10,4%%date:~4,2%%date:~7,2% : YYYYMMDD
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
  • 2
    This answer only works if a specific date format is set in Windows. Therefore it won't work on most Windows systems world-wide. – Robert Jun 29 '21 at 09:02
1

I tried the accepted answer and it works pretty well. Unfortunately the US Time Format appears to be H:MM:SS.CS, and the missing 0 on the front was causing parsing problems before 10 am. To get over this hurdle and also allow parsing of most any of the world time formats, I came up with this simple routine that appears to work quite well.

:ParseTime
rem The format of %%TIME%% is H:MM:SS.CS or (HH:MM:SS,CS) for example 0:01:23.45 or 23:59:59,99
FOR /F "tokens=1,2,3,4 delims=:.," %%a IN ("%1") DO SET /A "%2=(%%a * 360000) + (%%b * 6000) + (%%c * 100) + %%d"
GOTO :EOF

The nice thing with this routine is that you pass in the time string as the first parameter and the name of the environment variable you want to contain the time (in centiseconds) as the second parameter. For example:

CALL :ParseTime %START_TIME% START_CS
CALL :ParseTime %TIME% END_CS
SET /A DURATION=%END_CS% - %START_CS%

(*Chris*)

TheChrisPratt
  • 457
  • 3
  • 13
1

Maybe something like this:

@call:DateTime

@for %%? in (
    "Year   :Y"
    "Month  :M"
    "Day    :D"
    "Hour   :H"
    "Minutes:I"
    "Seconds:S"
) do @for /f "tokens=1-2 delims=:" %%# in (%%?) do @for /f "delims=" %%_ in ('echo %%_DT_%%$_%%') do @echo %%# : _DT_%%$_ : %%_

:: OUTPUT
:: Year    : _DT_Y_ : 2014
:: Month   : _DT_M_ : 12
:: Day     : _DT_D_ : 17
:: Hour    : _DT_H_ : 09
:: Minutes : _DT_I_ : 04
:: Seconds : _DT_S_ : 35

@pause>nul

@goto:eof

:DateTime
    @verify errorlevel 2>nul & @wmics Alias /? >nul 2>&1
    @if not errorlevel 1 (
        @for /f "skip=1 tokens=1-6" %%a in ('wmic path win32_localtime get day^,hour^,minute^,month^,second^,year /format:table') do @if not "%%f"=="" ( set "_DT_D_=%%a" & set "_DT_H_=%%b" & set "_DT_I_=%%c" & set "_DT_M_=%%d" & set "_DT_S_=%%e" & set "_DT_Y_=%%f" )
    ) else (
        @set "_DT_T_=1234567890 "
    )
    @if errorlevel 1 (
        @for %%? in ("iDate" "sDate" "iTime" "sTime" "F" "Y" "M" "D" "H" "I" "S") do @set "_DT_%%~?_=%%~?"
        @for %%? in ("Date" "Time") do @for /f "skip=2 tokens=1,3" %%a in ('reg query "HKCU\Control Panel\International" /v ?%%~? 2^>nul') do @for /f %%x in ('echo:%%_DT_%%a_%%') do @if "%%x"=="%%a" set "_DT_%%a_=%%b"
        @for /f "tokens=1-3 delims=%_DT_T_%" %%a in ("%time%") do @set "_DT_T_=%%a%%b%%c"
    )
    @if errorlevel 1 (
        @if "%_DT_iDate_%"=="0" (set "_DT_F_=_DT_D_ _DT_Y_ _DT_M_") else if "%_DT_iDate_%"=="1" (set "_DT_F_=_DT_D_ _DT_M_ _DT_Y_") else if "%_DT_iDate_%"=="2" (set "_DT_F_=_DT_Y_ _DT_M_ _DT_D_")
        @for /f "tokens=1-4* delims=%_DT_sDate_%" %%a in ('date/t') do @for /f "tokens=1-3" %%x in ('echo:%%_DT_F_%%') do @set "%%x=%%a" & set "%%y=%%b" & set "%%z=%%c"
        @for /f "tokens=1-3 delims=%_DT_T_%" %%a in ("%time%") do @set "_DT_H_=%%a" & set "_DT_I_=%%b" & set "_DT_S_=%%c"
        @for %%? in ("iDate" "sDate" "iTime" "sTime" "F" "T") do @set "_DT_%%~?_="
    )
    @for %%i in ("Y"                ) do @for /f %%j in ('echo:"%%_DT_%%~i_%%"') do @set /a _DT_%%~i_+=  0 & @for /f %%k in ('echo:"%%_DT_%%~i_:~-4%%"') do @set "_DT_%%~i_=%%~k"
    @for %%i in ("M" "D" "H" "I" "S") do @for /f %%j in ('echo:"%%_DT_%%~i_%%"') do @set /a _DT_%%~i_+=100 & @for /f %%k in ('echo:"%%_DT_%%~i_:~-2%%"') do @set "_DT_%%~i_=%%~k"
@exit/b
1

Use REG to save/modify/restore what ever values are most useful for your bat file. This is windows 7, for other versions you may need a different key name.

reg save    "HKEY_CURRENT_USER\Control Panel\International" _tmp.reg /y
reg add     "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate  /d "yyyy-MM-dd" /f
set file=%DATE%-%TIME: =0%
reg restore "HKEY_CURRENT_USER\Control Panel\International" _tmp.reg
set file=%file::=-%
set file=%file:.=-%
set file
Malcolm
  • 56
  • 3
1

In situations like this use a simple, standard programming approach: Instead of expending a huge effort parsing an unknown entity, simply save the current configuration, reset it to a known state, extract the info and then restore the original state. Use only standard Windows resources.

Specifically, the date and time formats are stored under the registry key HKCU\Control Panel\International\ in [MS definition] "values": "sTimeFormat" and "sShortDate". Reg is the console registry editor included with all Windows versions. Elevated privileges are not required to modify the HKCU key

Prompt $N:$D $T$G

::Save current config to a temporary (unique name) subkey, Exit if copy fails
Set DateTime=
Set ran=%Random%
Reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp%ran%" /f
If ErrorLevel 1 GoTO :EOF

::Reset the date format to your desired output format (take effect immediately)
::Resetting the time format is useless as it only affect subsequent console windows
::Reg add "HKCU\Control Panel\International" /v sTimeFormat /d "HH_mm_ss"   /f
Reg add "HKCU\Control Panel\International" /v sShortDate  /d "yyyy_MM_dd" /f

::Concatenate the time and (reformatted) date strings, replace any embedded blanks with zeros
Set DateTime=%date%__%time:~0,2%_%time:~3,2%_%time:~6,2%
Set DateTime=%DateTime: =0%

::Restore the original config and delete the temp subkey, Exit if restore fails
Reg copy   "HKCU\Control Panel\International-Temp%ran%" "HKCU\Control Panel\International" /f
If ErrorLevel 1 GoTO :EOF
Reg delete "HKCU\Control Panel\International-Temp%ran%" /f

Simple, straightforward and should work for all regions.

For reasons I don't understand, resetting the "sShortDate" value takes effect immediately in a console window but resetting the very similar "sTimeFormat" value does NOT take effect until a new console window is opened. However, the only thing changeable is the delimiter - the digit positions are fixed.Likewise the "HH" time token is supposed to prepend leading zeros but it doesn't. Fortunately, the workarounds are easy.

ArtK
  • 19
  • 2
  • -1 "Instead of adding a leading zero, why don't you disrupt the machine configuration, change it to your random need and then do your thing?" This approach is out of this world, requires a considerable amount of effort and can lead to an infinite numbrer of unwanted consequences. And I don't even want to start the discussion on readability and standard expected code behaviour. kudos. – vaitrafra Dec 28 '16 at 08:07
  • _Resetting the `sTimeFormat` time format is useless_. Nope. As it affects subsequent console prompt, apply it using `for /f "delims=" %%G in ('cmd /C echo SET "DateTime=%%date%%__%%time%%"') do %%G` – JosefZ Jan 18 '19 at 12:47
1

Using % you will run into a hex operation error when the time value is 7-9. To avoid this, use DelayedExpansion and grab time values with !min:~1!

An alternate method, if you have PowerShell is to call that:

for /F "usebackq delims=Z" %%i IN (`powershell Get-Date -format u`) do (set server-time=%%i)
Sagar V
  • 12,158
  • 7
  • 41
  • 68
Leland
  • 147
  • 1
  • 7
1

This script use a WMI interface accessed primary via WMIC tool, which is an integral part of Windows since Windows XP Professional (Home edition is supported too, but the tool is not installed by default). The script also implements a workaround of missing WMIC tool by creating and calling a WSH vbscript for access a WMI interface and write to console output the time with same format as WMIC tool provide.

@ECHO OFF
REM Returns: RETURN
REM Modify:  RETURN, StdOut
REM Required - mandatory: none
REM Required - optionaly: format strings delimited by a space to format an output delimited by predefined delimiter
REM    YYYY = 4-digit year
REM      MM = 2-digit month
REM      DD = 2-digit day
REM      hh = 2-digit hour
REM      mm = 2-digit minute
REM      ss = 2-digit second
REM      ms = 3-digit millisecond

CALL :getTime %*
ECHO %RETURN%
GOTO :EOF


REM SUBROUTINE
REM Returns: RETURN
REM Modify:  RETURN
REM Required - mandatory: none
REM Required - optionaly: format strings delimited by a space to format an output delimited by predefined delimiter
REM    YYYY = 4-digit year
REM      MM = 2-digit month
REM      DD = 2-digit day
REM      hh = 2-digit hour
REM      mm = 2-digit minute
REM      ss = 2-digit second
REM      ms = 3-digit millisecond
:getTime
  SETLOCAL EnableDelayedExpansion
    SET DELIM=-
    WHERE /Q wmic.exe
    IF NOT ERRORLEVEL 1 FOR /F "usebackq skip=1 tokens=*" %%x IN (`wmic.exe os get LocalDateTime`) DO (SET DT=%%x & GOTO getTime_Parse)
    SET _TMP=%TEMP:"=%
    ECHO Wscript.StdOut.WriteLine (GetObject("winmgmts:root\cimv2:Win32_OperatingSystem=@").LocalDateTime)>"%_TMP%\get_time_local-helper.vbs"
    FOR /F "usebackq tokens=*" %%x IN (`cscript //B //NoLogo "%_TMP%\get_time_local-helper.vbs"`) DO (SET DT=%%x & GOTO getTime_Parse)
    :getTime_Parse
      SET _RET=
      IF "%1" EQU "" (
        SET _RET=%DT:~0,4%%DELIM%%DT:~4,2%%DELIM%%DT:~6,2%%DELIM%%DT:~8,2%%DELIM%%DT:~10,2%%DELIM%%DT:~12,2%%DELIM%%DT:~15,3%
      ) ELSE (
        REM Not recognized format strings are ignored during parsing - no error is reported.
       :getTime_ParseLoop
         SET _VAL=
         IF "%1" EQU "YYYY" SET _VAL=%DT:~0,4%
         IF "%1" EQU "MM"   SET _VAL=%DT:~4,2%
         IF "%1" EQU "DD"   SET _VAL=%DT:~6,2%
         IF "%1" EQU "hh"   SET _VAL=%DT:~8,2%
         IF "%1" EQU "mm"   SET _VAL=%DT:~10,2%
         IF "%1" EQU "ss"   SET _VAL=%DT:~12,2%
         IF "%1" EQU "ms"   SET _VAL=%DT:~15,3%
         IF DEFINED _VAL (
           IF DEFINED _RET (
             SET _RET=!_RET!%DELIM%!_VAL!
           ) ELSE (
             SET _RET=!_VAL!
           )
         )
         SHIFT
         IF "%1" NEQ "" GOTO getTime_ParseLoop
      )
  ENDLOCAL & SET RETURN=%_RET%
GOTO :EOF
1

A nice single-line trick to avoid early variable expansion is to use cmd /c echo ^%time^%

cmd /c echo ^%time^% & dir /s somelongcommand & cmd /c echo ^%time^%
tresf
  • 7,103
  • 6
  • 40
  • 101
1

So the problem with %DATE% is that it depends on locale. So most of the previous answers did not work for me. If you are not picky about the exact format and just want a timestamp to differentiate the files you can do this:

set _date=%DATE%-%TIME%
set _date=%_date:/=-%
set _date=%_date: =-%
set _date=%_date::=-%
set _date=%_date:.=-%
echo %_date%

This should work for most locales. If it doesn't add another line set _date=%_date:<offending_char>=-% to remove the offending character. ie: a character which is not compatible with filenames or something you don't want in the file name.

enter image description here

enter image description here

Please note this doesn't meet the exact criteria laid down by the question.

rahulroy9202
  • 2,730
  • 3
  • 32
  • 45
0
:: =============================================================
:: Batch file to display Date and Time seprated by undescore.
:: =============================================================
:: Read the system date.
:: =============================================================
@SET MyDate=%DATE%
@SET MyDate=%MyDate:/=:%
@SET MyDate=%MyDate:-=:%
@SET MyDate=%MyDate: =:%
@SET MyDate=%MyDate:\=:%
@SET MyDate=%MyDate::=_%
:: =============================================================
:: Read the system time.
:: =============================================================
@SET MyTime=%TIME%
@SET MyTime=%MyTime: =0%
@SET MyTime=%MyTime:.=:%
@SET MyTime=%MyTime::=_%
:: =============================================================
:: Build the DateTime string.
:: =============================================================
@SET DateTime=%MyDate%_%MyTime%
:: =============================================================
:: Display the Date and Time as it is now.
:: =============================================================
@ECHO MyDate="%MyDate%" MyTime="%MyTime%" DateTime="%DateTime%"
:: =============================================================
:: Wait before close.
:: =============================================================
@PAUSE
:: =============================================================
0

Split the results of the date command by slash, then you can move each of the tokens into the appropriate variables.

FOR /F "tokens=1-3 delims=/" %%a IN ("%date:~4%") DO (
SET _Month=%%a
SET _Day=%%b
SET _Year=%%c
)
ECHO Month %_Month%
ECHO Day %_Day%
ECHO Year %_Year%
Barett
  • 5,826
  • 6
  • 51
  • 55
Casey
  • 9
  • 1
0

For a very simple solution for numeric date for use in filenames use the following code:

set month=%date:~4,2%
set day=%date:~7,2%
set curTimestamp=%month%%day%%year%

rem then the you can add a prefix and a file extension easily like this
echo updates%curTimestamp%.txt
0
  1. set xtime=%time%
  2. if "%xtime:~0,1%" == " " set xtime=0%xtime:~1,7%
  3. set isodate=%date:~-4%%date:~3,2%%date:~0,2%_%xtime:~0,2%%xtime:~3,2%%time:~6,2%
  • 4
    If you add an answer to the other 40, it should show a different solution or at least, a better explanation. But an equivalent answer without any explanation isn't very useful. – jeb May 17 '21 at 05:35
-1

Hope this helps:

set MM=%date:~4,2%
set DD=%date:~7,2%
set YYYY=%date:~10,4%

echo %DD%_%MM%_%YYYY%

This will print 05_06_2021

Ankush Jain
  • 5,654
  • 4
  • 32
  • 57
  • What does this show, what dozen existing answers don't already? Moreover, as already discussed, this is unreliable locale-specific solution. On my (Czech) system, this prints `02_6._`. – Martin Prikryl Jun 05 '21 at 20:19
-1
for /f "tokens=1-4 delims=/ " %%I in ("%DATE%") do set curdate=%%K_%%J_%%I
for /f "tokens=1-4 delims=:," %%I in ("%TIME: =0%") do set curtime=%%I_%%J_%%K
echo %curdate%__%curtime%

replace delims symbols if your system uses another (used for slicing to %%I,%%J...)
also edit curdate if your system uses another D/M/Y order

Seriy_A
  • 31
  • 1
  • 8
  • As discussed at dozens of other answers based on `%DATE%`/`%TIME%` – This is unreliable, as it's locale dependent. Not only delimiter can differ. Even the order of date components differ between locales. There are better solutions. – Martin Prikryl Jan 21 '22 at 08:22
  • thx, description modified, +DMY order – Seriy_A Jan 22 '22 at 13:53