38

In my .bat file I want to generate a unique name for files/directories based on date-time.

e.g.

Build-2009-10-29-10-59-00 

The problem is that %TIME% won't do because it contains characters that are illegal in filename (e.g. :).

Is there something like tr in batch files?

Any other ideas how to solve this (that don't require extra command line utilities aside from the batch interpreter)?

    8 Answers 8

    45

    EDIT: A better way of doing this is to take a date/time string that has a defined and unchanging format instead of using the locale-defined ones from %date% and %time%. You can use the following to get it:

    for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined mydate set mydate=%%x 

    It yields something like 20120730203126.530000+120 and you can use that to construct your file names.


    (Old answer below)

    You can simply replace the offending character with an empty string:

    echo %time::=% 

    The syntax %var:str1=str2% takes the environment variable (or pseudo-variable in case of %TIME% and replaces str1 by str2. If nothing follows after the equals sign then str1 is simply deleted.

    In your specific case I think you'd want the following:

    rem cut off fractional seconds set t=%time:~0,8% rem replace colons with dashes set t=%t::=-% set FileName=Build-%date%-%t% 

    A more brute-force way in case you don't know whether colons are used (but the order of the time would be the same):

    set FileName=Build-%date%-%time:~0,2%-%time:~3,2%-%time:~6,2% 

    All preceding things, however, assume that you use standard ISO 8601 date format, i. e. 2009-10-29. I'd assume this as simply normal, but some people use other formats so be careful. But since you didn't ask about the date I was assuming you didn't have a problem there.

    3
    • %time:~0,2%-%time:~3,2%-%time:~6,2% creates a string with whitespace before 10:00AM!CommentedJul 30, 2012 at 18:26
    • 2
      As I said, this assumes that you use a sane date/time format for your system. You can use for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined mydate set mydate=%%x. The date/time format in mydate isn't going to change, it's always YYYYMMDDHHMMSS... and you can cut it up to your liking.
      – Joey
      CommentedJul 30, 2012 at 18:32
    • 4
      For anybody else that tried to copy/paste the code into the command prompt and got an error, the solution is to change "%%" to "%" in both places. The original code works in a batch file, but not in command line.
      – DG.
      CommentedJan 12, 2013 at 4:53
    20

    Following up on @Joey's and @Kees' answers to make them instantly usable.

    On the command line:

    FOR /f %a IN ('WMIC OS GET LocalDateTime ^| FIND "."') DO SET DTS=%a SET DateTime=%DTS:~0,4%-%DTS:~4,2%-%DTS:~6,2%_%DTS:~8,2%-%DTS:~10,2%-%DTS:~12,2% echo %DateTime% 

    In a BAT file:

    @echo off REM See http://stackoverflow.com/q/1642677/1143274 FOR /f %%a IN ('WMIC OS GET LocalDateTime ^| FIND "."') DO SET DTS=%%a SET DateTime=%DTS:~0,4%-%DTS:~4,2%-%DTS:~6,2%_%DTS:~8,2%-%DTS:~10,2%-%DTS:~12,2% echo %DateTime% 

    Example output:

    2014-10-21_16-28-52 
      3

      I use this to create a unique file name for the execution of the batch file.

      REM ****Set up Logging **** For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b) For /f "tokens=1-2 delims=/:" %%a in ("%TIME%") do (set mytime=%%a%%b) set mytime=%mytime: =0% set Logname="PCCU_%mydate%_%mytime%.log" Echo. >>%Logname% 2>>&1 Echo.=================== >>%Logname% 2>>&1 

      I had to add the line

      set mytime=%mytime: =0% 

      because I had the same problem where a blank was being entered before 10 AM, now I get 09 instead of 9. I also reuse the %mydate% and %mytime% variable for other files that I create with this script so that they all have the same date time stamp.

        2

        This routine, actually only one line, works on every system set to any date or time format.
        Output of line 1 is in format 20140725095527.710000+120

        The actual date/time format you need is determined in line 2. You can format it however you want.
        Just add the resulting DateTime variable to your filename ie. Filename_%DateTime%.log

        ::======================================================================= ::== 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% | REM OUTPUT = 20140725-095527 
          2

          I made this universal, Will work on any environment where date format may be different.

          echo off if not exist "C:\SWLOG\" mkdir C:\SWLOG cd C:\SWLOG\ cmd /c "powershell get-date -format ^"{yyyyMMdd-HHmmss}^""> result.txt REM echo %time% > result.txt type result.txt > result1.txt set /p filename=<result1.txt echo %filename% del C:\SWLOG\result.txt del C:\SWLOG\result1.txt 
            1

            To make the code in the previous example work, I needed to adjust slightly. I presume this is because my PC is using a UK date format. To get back "2014-04-19" in mydate I needed:

            For /f "tokens=1-3 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%b-%%a) 

            Below I've pasted my total script, and included an example of how to use the filename

            For /f "tokens=1-3 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%b-%%a) For /f "tokens=1-2 delims=/:" %%a in ("%TIME%") do (set mytime=%%a%%b) set mytime=%mytime: =0% set Logname="c:\temp\LogFiles\MyLogFile_%mydate%_%mytime%.log" Robocopy \\sourceserver\Music H:\MyBackups\Music /MIR /FFT /Z /XA:H /W:5 /np /fp /dcopy:T /unilog:%Logname% /tee 

            Hope this helps!

              1

              Datetime stamp:

              @echo off for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a" set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%" set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%" rem set "datestamp=%YY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%" set "datestamp=%YYYY%%MM%%DD%" set "timestamp=%HH%%Min%%Sec%" set unique_number=%datestamp%%timestamp% echo %unique_number% 
                0

                If you can guarantee that the machine has a specific version of Python installed on it and accessible in the system's PATH, you can use this solution:

                FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "import datetime; print datetime.datetime.now().replace(microsecond=0).isoformat().replace(':', '-')"`) DO ( SET TIMESTAMP=%%F ) ECHO %TIMESTAMP% 

                This will put the current local ISO-8601(ish) date representation into a %TIMESTAMP% variable and echo it out, like so:

                2017-05-25T14:54:37 

                I've put replace(':', '-') after the isoformat() so that the resultant string can be used in a filename or directory, since : is a forbidden character in the Windows filesystem.

                  Start asking to get answers

                  Find the answer to your question by asking.

                  Ask question

                  Explore related questions

                  See similar questions with these tags.