I came across a bug in my DOS script that uses date and time data for file naming. The problem was I ended up with a gap because the time variable didn't automatically provide leading zero for hour < 10. So running> echo %time% gives back: ' 9:29:17.88'.

Does anyone know of a way to conditionally pad leading zeros to fix this?

More info: My filename set command is:

set logfile=C:\Temp\robolog_%date:~-4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log

which ends up being: C:\Temp\robolog_20100602_ 93208.log (for 9:23 in the morning).

This question is related to this one.


  • It is possible to get padded hour value... FOR /F "TOKENS=1 DELIMS=:" %%A IN ('TIME/T') DO SET HH=%%A then replace %time:~0,2% with %HH% I was hoping for a more compact solution, but this will work. – Ira Jun 2 '10 at 17:55
  • A "more compact" solution would be something in another language (powershell? python? perl? WSH?). – user1686 Jun 2 '10 at 19:20
  • Switched to mark Jesse's answer as the solution I use. It works with both pre-noon times to pad w/ leading 0 and also post-noon military time. – Ira May 17 '18 at 20:14

13 Answers 13


A very simple way is to just replace the leading space with zero:
echo %TIME: =0%

  • 1
    it works! this is the simplest solution I think.. – aerobrain Jun 30 '14 at 2:01
  • Can this also be done with multiple characters? i.E. all ',', ' ' and ':'. Currently I create intermediate variables but of course, this works only because of the few numbers of replacements. For more it would be cumbersome. – Devolus Jan 9 '16 at 9:19
  • 1
    I'm using this in a second "step" to modify the Hours: set HH=%time:~-11,2% set MM=%time:~-8,2% set SS=%time:~-5,2% set ISOTIME=%HH: =0%-%MM%-%SS% echo %ISOTIME% Also see ss64.com/nt/syntax-replace.html – handle Mar 2 '17 at 8:40
  • +1 This is shortest/best answer. How I used: set timestring=%TIME: =0% early in sub call - then just work with timestring instead (or whatever variable you use). – bshea Apr 7 '18 at 13:02

My Solution was to use the following idea:

IF "%HOUR:~0,1%" == " " SET HOUR=0%HOUR:~1,1%
  • I like it. Simple and intuitive. – Ken Feb 12 '14 at 20:16
  • Works on modern windows, but gives syntax error on server 2003! – Dr BDO Adams May 24 '16 at 11:17
  • Works flawless on 2008+, most elegant solution. Thank you. – bjoster Dec 23 '16 at 10:09
  • 1
    but gives syntax error on server 2003 - why you care that in 2016? – Marcin Orlowski Jan 24 '17 at 23:45
  • Perfect on Windows 10 Command Prompt – Mike Upjohn Jul 21 '18 at 6:51

Similar idea to Dennis' answer. The problem is that the width of %time% is always the same, so it inserts a space in the beginning instead of returning a shorter string.

You can get rid of that with for:

for /f "delims= " %x in ("%time%") do set T=0%x

The rest is more or less the same, then.

  • 2
    This solution works for > 10 but now creates '010' for 10:... – Devolus Jan 9 '16 at 9:02
  • 3
    The answer from Jesse is the correct one... – Simon Sobisch Jul 14 '16 at 6:39
  • This is a very bad answer, it breaks down as soon as there are two digits in the hour. I can't beleive the OP selected it. – thebunnyrules Dec 14 '17 at 12:15

Using Jesse's Contribution, I just created a variable with the modified output. Then I reference that variable to build the hour portion.

set NantTime=%time: =0%
nant\bin\nant.exe -nologo+ -debug+ -verbose+ -D:project.config=debug /f:build\default.build -l:logs\architect-build-%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2%-%NantTime:~0,2%-%time:~3,2%-%time:~6,2%.log 

With the original source:

set hour=%time: =0%
set logfile=C:\Temp\robolog_%date:~-4%%date:~4,2%%date:~7,2%_%hour:~0,2%%time:~3,2%%time:~6,2%.log

Thanks Jesse. I would have voted if I had the reputation points.


For the most compact solution implementing everything above, I think that

FOR /F "TOKENS=1-4 DELIMS=/ " %%A IN ("%DATE%") DO FOR /F "TOKENS=1-3 DELIMS=:." %%E IN ("%TIME: =0%") DO SET logfile=C:\Temp\robolog_%%D%%C%%B_%%E%%F%%G.log

would work here without adding any new lines to the script. It's perhaps less elegant than multiple command solutions, though..


The following takes a few more lines but is clear and understandable. It saves stdout and stderr to separate files, each with a timestamp. The timestamp includes year, month, day, hour, minute, and second, in that order. Timestamps should always have the most significant date component first (year) and the least component (seconds) last. That enables files listings to be in time order. Without further ado, here is my solution.

:prepare time stamp 
set year=%date:~10,4%
set month=%date:~4,2%
set day=%date:~7,2%
set hour=%time:~0,2%
:replace leading space with 0 for hours < 10
if "%hour:~0,1%" == " "  set hour=0%hour:~1,1%
set minute=%time:~3,2%
set second=%time:~6,2%
set timeStamp=%year%.%month%.%day%_%hour%.%minute%.%second%

:run the program 
ProgramName.pl 1> RunLogs\out.%timeStamp% ^
               2> RunLogs\err.%timeStamp%

This tacks a zero onto the beginning of the time and takes the last two digits of the hour (the minute and second start positions are shifted by one). So 3 AM becomes "03" then "03" and hour 15 becomes "015" then "15".

set T=0%time%
set T=%T:~1,2%%T:~4,2%%T:~7,2%
set D=%date:~-4%%date:~4,2%%date:~7,2%
set logfile=C:\Temp\robolog_%D%_%T%.log

Less readably:

set T=0%time%
set logfile=C:\Temp\robolog_%date:~-4%%date:~4,2%%date:~7,2%_%T:~1,2%%T:~4,2%%T:~7,2%.log
  • 1
    I'm not sure this works. If I run 'set T=0%time%' and it's 9:38AM, echo %T% gives back: '0 9:38:54.21', then taking %T:~1,2% gets the space, no leading 0. – Ira Jun 3 '10 at 17:41

One line of code will do what you need:

    IF "%Time:~0,1%" == " " SET TimeStamp=0%Time:~1,7%

For example, I use %Date% and then add a leading zero to a variable I use to determine if I need to replace the leading space with a zero for %Time%.

    ::Prepare TimeStamp variable by replacing leading space with 0 for Hours < 10
    SET TimeStamp=%Time:~0,8%
    IF "%Time:~0,1%" == " " SET TimeStamp=0%Time:~1,7%
    Echo Started on %Date$ at %TimeStamp%

    :: Insert what you are doing here...

    SET TimeStamp=%Time:~0,8%
    IF "%Time:~0,1%" == " " SET TimeStamp=0%Time:~1,7%
    ECHO Finished on %Date% at %TimeStamp%

This creates a sortable timestamp and the second line makes sure there are no spaces for single digit hour, etc, to make it usable for scripts:

set datestamp=%date:~-4%.%date:~-10,-8%.%date:~-7,-5%_%time:~0,2%.%time:~3,2%.%time:~6,2%
set datestamp=%datestamp: =_%




Thanks to help from above... This is what I am using:

C:\Windows\System32>SET short=%date:~10,4%-%date:~4,2%-%date:~7,2%
C:\Windows\System32>ECHO -- Short Date: %short%
-- Short Date: 2018-06-27
C:\Windows\System32>SET long=%date:~10,4%-%date:~4,2%-%date:~7,2%_%time:~0,2%_%time:~3,2%_%time:~6,2%
C:\Windows\System32>ECHO -- Long Date: %long%
-- Long Date: 2018-06-27_10_51_43

I then have logs that are called out in Robocopy jobs like this:

There are many like this:

Robocopy C:\Users\ME\Favorites\ %usb%:\Local_PC\Favorites\ /MIR /TEE /FFT /DST /TIMFIX /W:5 /R:5 /NP /LOG+:%usb%:\Robocopy\LOG_%short%.txt

Ends job with this:

REN %usb%:\Robocopy\LOG_%short%.txt COMPLETE_LOG_%long%.log

COMPLETE_LOG_2018-06-27_10_53_54.log is the file produced at the end and it is sortable by file name.


Jesse's answer solved my file rename problem by eliminating the space in the hour field. This is how I set my variables:

for /f "tokens=1,2,3,4 delims=/ " %%a in ("%date%") do set wday=%%a&set month=%%b&set day=%%c&set year=%%d
for /f "tokens=1,2 delims=:" %%a in ("%time: =0%") do set hour=%%a&set minute=%%b

It works like a champ; for some reason date didn't need the same treatment, but I imagine that's down to the regional settings.

    @echo off

    call :PAD aaa,2,0,grw
    echo [[aaa=%aaa%]]

rem #### Function PAD ####
    goto :PADEND
    :PAD <var>,<length>,<padchar>,<string>
        set padtot=%~2
        set padchar=%~3
        set padString=%~4
            call :len lenpadString,%padString%
            if ["%lenpadString%"] GEQ ["%padtot%"] goto :EndPADLOOP
            set padString=%padchar%%padString%
            goto :StartPADLOOP
        set %~1=%padString%

rem #### Function LEN ####
    goto :LENEND
    :LEN <var>,<string>
        set LENtempvar=%~2
        rem echo {{S:%LENtempvar%}}
        set LENCOUNT=0    
            if ["%LENtempvar%"] EQU [""] goto :endLENLOOP
            rem echo {{A:%LENtempvar%}}
            set LENtempvar=%LENtempvar:~0,-1%
            rem echo {{B:%LENtempvar%}}
            set /a LENCOUNT=LENCOUNT+1
        goto :startLENLOOP
        set %~1=%LENCOUNT%
set sFolderName=%time: =0%
xcopy "%UserProfile%\Pictures\*.jpg" Y:\"%DATE%-%sFolderName:~0,2%h%time:~3,2%m%time:~6,2%s-%random%" /I /C /Y


  • 5
    Although the code is appreciated, it should always have an accompanying explanation. This doesn't have to be long but it is expected. – peterh Jun 14 '15 at 6:49

Not the answer you're looking for? Browse other questions tagged or ask your own question.