Related
So, I have a script to log the date and time in a text file:
for /f "tokens=2 delims==" %%G in ('wmic os get localdatetime /value') do set datetime=%%G
set year=%datetime:~0,4%
rem pause
set month=%datetime:~4,2%
set day=%datetime:~6,2%
set /a day2=day+5
echo %year%/%month%/%day2%> C:\WLT\Init\lastoptim.txt
And a similar one in a script that runs on startup:
for /f "tokens=2 delims==" %%G in ('type C:\WLT\Init\lastoptim.txt') do set datetime2=%%G
set year=2%datetime2:~0,4%
rem pause
set month2=%datetime2:~4,2%
set day2=%datetime2:~6,2%
set /a day3=day2+1
echo %year2%/%month2%/%day3%> lastoptim2.txt
echo %year2%/%month2%/%day3%
But it doesn’t work. What I need is a script to extract a date from %date% into a text file, and then another one to take that date, see if the current date is X number of days later, and if it is, then run a command.
Would like this script to be entirely dependent on cmd, because this is going to be used on systems as far back as XP. Using an external app (e.g. an exe that prints out the date in a specific format) would be fine.
Your question still not clear for me, but if you want to add one day or one month for your dates, here is an example :
#echo off
Title Manipulate DATES WITH BATCH
#for /f "tokens=* delims=" %%a in ('wmic os get LocalDateTime /value') do for /f "tokens=* delims=" %%# in ("%%a") do set "%%#"
:: Store the local date inside a variable
set "CurrentDateTime=%LocalDateTime%"
set "CurrentDate=%CurrentDateTime:~0,4%/%CurrentDateTime:~4,2%/%CurrentDateTime:~6,2%"
:: Here Adding One day
#for /f %%a in ('Powershell -C "(Get-Date).AddDays(1).ToString('yyyy/MM/dd')"') do set "NextDay=%%a"
:: Here adding 1 month
#for /f %%a in ('Powershell -C "(Get-Date).AddMonths(1).ToString('yyyy/MM/dd')"') do set "NextMonth=%%a"
echo( CurrentDate : %CurrentDate%
echo( NextDay : %NextDay%
echo( NextMonth : %NextMonth%
pause
I need to get today date in Window *.bat file. After it I would like to get day, month and year. How can I do this?
I can't use PowerShell
This will give you DD MM YYYY YY HH Min Sec variables and works on any Windows machine from XP Pro and later.
#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%"
set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%"
set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%"
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
echo fullstamp: "%fullstamp%"
pause
You get and format like this
for /f "tokens=1-4 delims=/ " %%i in ("%date%") do (
set dow=%%i
set month=%%j
set day=%%k
set year=%%l
)
set datestr=%month%_%day%_%year%
echo datestr is %datestr%
Note: Above only works on US locale. It assumes the output of echo %date% looks like this: Thu 02/13/21. If you have different Windows locale settings, you will need to modify the script based on your configuration.
%date% will give you the date.
%time% will give you the time.
The date and time /t commands may give you more detail.
Locale-independent one liner to get any date format you like. I use it to generate archive names. Back quote (`) option is needed because PowerShell command line is using single quotes (').
:: Get date in 'yyyyMMdd_HHmm' format to use with file name.
FOR /f "usebackq" %%i IN (`PowerShell ^(Get-Date^).ToString^('yyyyMMdd_HHmm'^)`) DO SET DTime=%%i
:: Get yesterday date in 'yyyy-MM-dd' format.
FOR /f "usebackq" %%i IN (`PowerShell ^(Get-Date^).AddDays^(-1^).ToString^('yyyy-MM-dd'^)`) DO SET DTime=%%i
:: Show file name with the date.
echo Archive.%DTime%.zip
set datestr=%date%
set result=%datestr:/=-%
#echo %result%
pause
This will give you the date in this format mmddyyyy saved into %today%, assuming your regional settings have you in the US locale.
FOR /f "tokens=2-4 delims=/ " %%a IN ("%date%") DO SET today=%%a%%b%%c
In my case I was looking to create a folder with todays date, like this...
mkdir C:\Users\LKrell\Documents\%today%
How do I save the current date in YYYY-MM-DD format into some variable in a Windows .bat file?
Unix shell analogue:
today=`date +%F`
echo $today
You can get the current date in a locale-agnostic way using
for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x
Then you can extract the individual parts using substrings:
set today=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%
Another way, where you get variables that contain the individual parts, would be:
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%
Much nicer than fiddling with substrings, at the expense of polluting your variable namespace.
If you need UTC instead of local time, the command is more or less the same:
for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%
Use date /T to find the format on command prompt.
If the date format is Thu 17/03/2016 use like this:
set datestr=%date:~10,4%-%date:~7,2%-%date:~4,2%
echo %datestr%
If you wish to achieve this using standard MS-DOS commands in a batch file then you could use:
FOR /F "TOKENS=1 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET dd=%%A
FOR /F "TOKENS=1,2 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET mm=%%B
FOR /F "TOKENS=1,2,3 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET yyyy=%%C
I'm sure this can be improved upon further but this gives the date into 3 variables for Day (dd), Month (mm) and Year (yyyy). You can then use these later in your batch script as required.
SET todaysdate=%yyyy%%mm%%dd%
echo %dd%
echo %mm%
echo %yyyy%
echo %todaysdate%
While I understand an answer has been accepted for this question this alternative method may be appreciated by many looking to achieve this without using the WMI console, so I hope it adds some value to this question.
Two more ways that do not depend on the time settings (both taken from How get data/time independent from localization). And both also get the day of the week and none of them requires admin permissions!:
MAKECAB - will work on EVERY Windows system (fast, but creates a small temporary file) (the foxidrive script):
#echo off
pushd "%temp%"
makecab /D RptFileName=~.rpt /D InfFileName=~.inf /f nul >nul
for /f "tokens=3-7" %%a in ('find /i "makecab"^<~.rpt') do (
set "current-date=%%e-%%b-%%c"
set "current-time=%%d"
set "weekday=%%a"
)
del ~.*
popd
echo %weekday% %current-date% %current-time%
pause
ROBOCOPY - it's not a native command for Windows XP and Windows Server 2003, but it can be downloaded from the Microsoft site. But it is built-in in everything from Windows Vista and above:
#echo off
setlocal
for /f "skip=8 tokens=2,3,4,5,6,7,8 delims=: " %%D in ('robocopy /l * \ \ /ns /nc /ndl /nfl /np /njh /XF * /XD *') do (
set "dow=%%D"
set "month=%%E"
set "day=%%F"
set "HH=%%G"
set "MM=%%H"
set "SS=%%I"
set "year=%%J"
)
echo Day of the week: %dow%
echo Day of the month : %day%
echo Month : %month%
echo hour : %HH%
echo minutes : %MM%
echo seconds : %SS%
echo year : %year%
endlocal
And three more ways that uses other Windows script languages. They will give you more flexibility e.g. you can get week of the year, time in milliseconds and so on.
JScript/BATCH hybrid (need to be saved as .bat). JScript is available on every system from Windows NT and above, as a part of Windows Script Host (though can be disabled through the registry it's a rare case):
#if (#X)==(#Y) #end /* ---Harmless hybrid line that begins a JScript comment
#echo off
cscript //E:JScript //nologo "%~f0"
exit /b 0
*------------------------------------------------------------------------------*/
function GetCurrentDate() {
// Today date time which will used to set as default date.
var todayDate = new Date();
todayDate = todayDate.getFullYear() + "-" +
("0" + (todayDate.getMonth() + 1)).slice(-2) + "-" +
("0" + todayDate.getDate()).slice(-2) + " " + ("0" + todayDate.getHours()).slice(-2) + ":" +
("0" + todayDate.getMinutes()).slice(-2);
return todayDate;
}
WScript.Echo(GetCurrentDate());
VBScript/BATCH hybrid (Is it possible to embed and execute VBScript within a batch file without using a temporary file?) same case as jscript , but hybridization is not so perfect:
:sub echo(str) :end sub
echo off
'>nul 2>&1|| copy /Y %windir%\System32\doskey.exe %windir%\System32\'.exe >nul
'& echo current date:
'& cscript /nologo /E:vbscript "%~f0"
'& exit /b
'0 = vbGeneralDate - Default. Returns date: mm/dd/yy and time if specified: hh:mm:ss PM/AM.
'1 = vbLongDate - Returns date: weekday, monthname, year
'2 = vbShortDate - Returns date: mm/dd/yy
'3 = vbLongTime - Returns time: hh:mm:ss PM/AM
'4 = vbShortTime - Return time: hh:mm
WScript.echo Replace(FormatDateTime(Date, 1), ", ", "-")
PowerShell - can be installed on every machine that has .NET - download from Microsoft (v1, v2, and v3 (only for Windows 7 and above)). Installed by default on everything form Windows 7/Win2008 and above:
C:\> powershell get-date -format "{dd-MMM-yyyy HH:mm}"
Self-compiled jscript.net/batch (I have never seen a Windows machine without .NET so I think this is a pretty portable):
#if (#X)==(#Y) #end /****** silent line that start jscript comment ******
#echo off
::::::::::::::::::::::::::::::::::::
::: Compile the script ::::
::::::::::::::::::::::::::::::::::::
setlocal
if exist "%~n0.exe" goto :skip_compilation
set "frm=%SystemRoot%\Microsoft.NET\Framework\"
:: searching the latest installed .net framework
for /f "tokens=* delims=" %%v in ('dir /b /s /a:d /o:-n "%SystemRoot%\Microsoft.NET\Framework\v*"') do (
if exist "%%v\jsc.exe" (
rem :: the javascript.net compiler
set "jsc=%%~dpsnfxv\jsc.exe"
goto :break_loop
)
)
echo jsc.exe not found && exit /b 0
:break_loop
call %jsc% /nologo /out:"%~n0.exe" "%~dpsfnx0"
::::::::::::::::::::::::::::::::::::
::: End of compilation ::::
::::::::::::::::::::::::::::::::::::
:skip_compilation
"%~n0.exe"
exit /b 0
****** End of JScript comment ******/
import System;
import System.IO;
var dt=DateTime.Now;
Console.WriteLine(dt.ToString("yyyy-MM-dd hh:mm:ss"));
Logman This cannot get the year and day of the week. It's comparatively slow, also creates a temp file and is based on the time stamps that logman puts on its log files.Will work everything from Windows XP and above. It probably will be never used by anybody - including me - but it is one more way...
#echo off
setlocal
del /q /f %temp%\timestampfile_*
Logman.exe stop ts-CPU 1>nul 2>&1
Logman.exe delete ts-CPU 1>nul 2>&1
Logman.exe create counter ts-CPU -sc 2 -v mmddhhmm -max 250 -c "\Processor(_Total)\%% Processor Time" -o %temp%\timestampfile_ >nul
Logman.exe start ts-CPU 1>nul 2>&1
Logman.exe stop ts-CPU >nul 2>&1
Logman.exe delete ts-CPU >nul 2>&1
for /f "tokens=2 delims=_." %%t in ('dir /b %temp%\timestampfile_*^&del /q/f %temp%\timestampfile_*') do set timestamp=%%t
echo %timestamp%
echo MM: %timestamp:~0,2%
echo dd: %timestamp:~2,2%
echo hh: %timestamp:~4,2%
echo mm: %timestamp:~6,2%
endlocal
exit /b 0
More information about the Get-Date function.
As per answer by #ProVi just change to suit the formatting you require
echo %DATE:~10,4%-%DATE:~7,2%-%DATE:~4,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%
will return
yyyy-MM-dd hh:mm:ss
2015-09-15 18:36:11
EDIT
As per #Jeb comment, whom is correct the above time format will only work if your DATE /T command returns
ddd dd/mm/yyyy
Thu 17/09/2015
It is easy to edit to suit your locale however, by using the indexing of each character in the string returned by the relevant %DATE% environment variable you can extract the parts of the string you need.
eg. Using %DATE~10,4% would expand the DATE environment variable, and then use only the 4 characters that begin at the 11th (offset 10) character of the expanded result
For example if using US styled dates then the following applies
ddd mm/dd/yyyy
Thu 09/17/2015
echo %DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%
2015-09-17 18:36:11
I really liked Joey's method, but I thought I'd expand upon it a bit.
In this approach, you can run the code multiple times and not worry about the old date value "sticking around" because it's already defined.
Each time you run this batch file, it will output an ISO 8601 compatible combined date and time representation.
FOR /F "skip=1" %%D IN ('WMIC OS GET LocalDateTime') DO (SET LIDATE=%%D & GOTO :GOT_LIDATE)
:GOT_LIDATE
SET DATETIME=%LIDATE:~0,4%-%LIDATE:~4,2%-%LIDATE:~6,2%T%LIDATE:~8,2%:%LIDATE:~10,2%:%LIDATE:~12,2%
ECHO %DATETIME%
In this version, you'll have to be careful not to copy/paste the same code to multiple places in the file because that would cause duplicate labels. You could either have a separate label for each copy, or just put this code into its own batch file and call it from your source file wherever necessary.
Just use the %date% variable:
echo %date%
It is possible to use PowerShell and redirect its output to an environment variable by using a loop.
From the command line (cmd):
for /f "tokens=*" %a in ('powershell get-date -format "{yyyy-MM-dd+HH:mm}"') do set td=%a
echo %td%
2016-25-02+17:25
In a batch file you might escape %a as %%a:
for /f "tokens=*" %%a in ('powershell get-date -format "{yyyy-MM-dd+HH:mm}"') do set td=%%a
This is an extension of Joey's answer to include the time and pad the parts with 0's.
For example, the result will be 2019-06-01_17-25-36. Also note that this is the UTC time.
for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
set Month=0%Month%
set Month=%Month:~-2%
set Day=0%Day%
set Day=%Day:~-2%
set Hour=0%Hour%
set Hour=%Hour:~-2%
set Minute=0%Minute%
set Minute=%Minute:~-2%
set Second=0%Second%
set Second=%Second:~-2%
set TimeStamp=%Year%-%Month%-%Day%_%Hour%-%Minute%-%Second%
Check this one..
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%" & set "MS=%dt:~15,3%"
set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%" & set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%-%MS%"
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
echo fullstamp: "%fullstamp%"
pause
I set an environment variable to the value in the numeric format desired by doing this:
FOR /F "tokens=1,2,3,4 delims=/ " %a IN ('echo %date%') DO set DateRun=%d-%b-%c
Due to date and time format is location specific info, retrieving them from %date% and %time% variables will need extra effort to parse the string with format transform into consideration. A good idea is to use some API to retrieve the data structure and parse as you wish. WMIC is a good choice. Below example use Win32_LocalTime. You can also use Win32_CurrentTime or Win32_UTCTime.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
for /f %%x in ('wmic path Win32_LocalTime get /format:list ^| findstr "="') do set %%x
set yyyy=0000%Year%
set mmmm=0000%Month%
set dd=00%Day%
set hh=00%Hour%
set mm=00%Minute%
set ss=00%Second%
set ts=!yyyy:~-4!-!mmmm:~-2!-!dd:~-2!_!hh:~-2!:!mm:~-2!:!ss:~-2!
echo %ts%
ENDLOCAL
Result:
2018-04-25_10:03:11
I am using the following:
set iso_date=%date:~6,4%-%date:~3,2%-%date:~0,2%
Or in combination with a logfile name 'MyLogFileName':
set log_file=%date:~6,4%-%date:~3,2%-%date:~0,2%-MyLogFileName
echo %DATE:~10,4%%DATE:~7,2%%DATE:~4,2%
If you have Python installed, you can do
python -c "import datetime;print(datetime.date.today().strftime('%Y-%m-%d'))"
You can easily adapt the format string to your needs.
If powershell is available, you can use codes below:
# get date
$BuildDate=(get-date -format "yyMMdd")
echo BuildDate=$BuildDate
# get time
$BuildTime=(get-date -format "hhmmss")
echo BuildTime=$BuildTime
Here is the result:
BuildDate=200518
BuildTime=115919
If you don't mind an one-time investment of 10 to 30 minutes to get a reliable solution (that doesn't depend on Windows' region settings), please read on.
Let's free our minds. Do you want to simplify the scripts to just look like this? (Assume you wants to set the LOG_DATETIME variable)
FOR /F "tokens=* USEBACKQ" %%F IN (`FormatNow "yyyy-MM-dd"`) DO (
Set LOG_DATETIME=%%F
)
echo I am going to write log to Testing_%LOG_DATETIME%.log
You can. Simply build a FormatNow.exe with C# .NET and add it to your PATH.
Notes:
You can use any Visual Studio edition, such as Visual Studio Express, to build the FormatNow.exe.
In Visual Studio, choose the "Console Application" C# project, not "Windows Forms Application" project.
Common sense: the built FormatNow.exe will need .NET Framework to run.
Common sense: after adding FormatNow.exe to PATH variable, you need to restart CMD to take effect. It also applies to any change in environment variables.
Benefits:
It's not slow (finishes within 0.2 seconds).
Many formats are supported https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx
e.g. FormatNow "ddd" to get only the day of week, FormatNow "yyyy" to get only the year
It doesn't depend on Windows' region settings, so its output is much more reliable. On the other hand, %date% doesn't give a consistent format over different computers, and is not reliable.
You don't need to create so many CMD variables and pollute the variable namespace.
It would require 3 lines in the batch script to invoke the program and get the results. It should be reasonably short enough.
Source code of FormatNow.exe which I built with Visual Studio 2010 (I prefer to build it myself to avoid the risk of downloading an unknown, possibly malicious program). Just copy and paste the codes below, build the program once, and then you have a reliable date formatter for all future uses.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace FormatNow
{
class Program
{
static void Main(string[] args)
{
try
{
if (args.Length < 1)
{
throw new ArgumentException("Missing format");
}
string format = args[0];
Console.Write(DateTime.Now.ToString(format, CultureInfo.InvariantCulture.DateTimeFormat));
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
In general, when dealing with complicated logics, we can make it simpler for by building a very small program and calling the program to capture the output back to a batch script variable instead. We are not students and we're not taking exams requiring us to follow the batch-script-only rule to solve problems. In real working environment, any (legal) method is allowed. Why should we still stick to the poor capabilities of Windows batch script that needs workarounds for many simple tasks? Why should we use the wrong tool for the job?
I've been working on some code in a batch file that evaluates two file dates. If one date is greater than the other then it runs another bat file. What I want to do is format the two dates as YYYYMMDD so that I can use the GTR (greater than).
The code is below but and it works if I use == (equal) because it's evaluating the string. I only want to know if one file date is greater than the other file date.
I'm not asking for someone to amend the code below but if you can show me how to format the dates I would be very grateful.
set Fileone=File1.txt
set FileTwo=File2.txt
pushd "D:\Board\Broadcast\FA_Report8_A"
FOR %%f IN (%FileOne%) DO SET filedatetime=%%~tf
FOR %%f IN (%FileTwo%) DO SET filedatetime2=%%~tf
SET filedatetime2=%year%%month%%day%
IF %filedatetime:~0, 10% GTR %filedatetime2:~0, 10% (
echo FileOne Greater - run bat
timeout /t 20 /nobreak
goto Finish
) else (
echo FileOne not Greater - Finish
goto Finish
)
:Finish
echo finished
pause
It's not portable between machines with different date formats but the simplest way is to use a substring: %var:~STARTPOS,LENGTH%
set filedatetime=14/06/2012 12:26
set filedatetime=%filedatetime:~6,4%%filedatetime:~3,2%%filedatetime:~0,2%
echo "%filedatetime%"
"20120614"
You can separate a date in its parts with a FOR /F command:
set filedatetime=14/06/2012 12:26
for /F "tokens=1-3 delims=/ " %%a in ("%filedatetime%") do (
set filedatetime=%%c%%b%%a
)
This form prevents you to make a mistake in the position or size of each substring, and is very easy to change the order of the parts. For example, if your date is MM/DD/YYYY:
set filedatetime=%%c%%a%%b
Type FOR /? for further details.
The layout for date variable strings in the system can be assumed by settings from the user, by regional and/or language, so, date is not 100% predictable layout to work with.
Try using wmic OS Get localdatetime /value because the result is 100% predictable:
LocalDateTime=20190609123708.733000-180
SO, if you use in for loop, adding 2 delimiters like =., (equal and dot), you go getting this string output:
20190609123708.
The layout from this command is predictable and works independent of regional settings, user settings or system language, so, the command will always return:
set _date=20190609123708
rem :: %_date:~0,4%_%_date:~4,2%_%_date:~6,2%
rem :: year:2019 | month:06 | day:09
In bat file:
#echo off & for /f "tokens=2delims==." %%i in ('wmic OS Get localdatetime /value ^|findstr /r [0-9]')do set "_date=%%i" & echo/%_date:~0,4%%_date:~4,2%%_date:~6,2%
In command line:
for /f "tokens=2delims==." %i in ('wmic OS Get localdatetime /value ^|findstr /r [0-9]')do set "_data=%i" & mkdir %_date:~0,4%_%_date:~4,2%_%_date:~6,2%
This commands result ::
20190609
May I can also suggest:
wmic Path Win32_LocalTime Get Day,Month,Year
In looping for:
#echo off & setlocal enabledelayedexpansion & set "_do=wmic Path Win32_LocalTime Get Day^,Month^,Year"
for /f "tokens=1-3delims= " %%a in ('!_do!^|findstr /r [0-9]')do set "y=%%c" & set "d=0%%a" & set "m=0%%b"
echo/!y!!m:~-2!!d:~-2! >nul
Result:
Day Month Year
9 6 2019
%%a %%b %%c
The difference is no zero in number for month/day less equal 9, so, you can use this bat to put leading zero in this case:
#echo off & setlocal enabledelayedexpansion & set "_do=wmic Path Win32_LocalTime Get Day^,Month^,Year"
for /f "tokens=1-3delims= " %%a in ('!_do!^|findstr /r [0-9]')do set "y=%%c" & set "d=0%%a" & set "m=0%%b"
echo/!y!!m:~-2!!d:~-2!
Result in YearMonthDay:
20190609
Obs.: In PowerShell, the layout can be customized simple by:
ToString("yyyyMMdd")
The strings can be set with ToString.
Sample: yyyy-MM-dd, dd-MM-yyyy, MM-dd-yyyy, MM_dd_yyyy, yyyy_MM_dd, etc..
The Powershell command:
$(Get-Date).ToString("yyyyMMdd")
Result:
2010609
See more about date variable layout output in batch here:
Safe way to get current day month and year in batch
Parsing Dates in Batch Files & Regional Settings / Locale
Update - How applying the comments/observations above in your bat, so, if I understood your code in this question:
#echo off & setlocal enabledelayedexpansion
set "Fileone=File1.txt" & set "FileTwo=File2.txt"
set "_both=!FileOne!-!FileTwo!" & rem cd /d "D:\Board\Broadcast\FA_Report8_A"
set "_path_back=%__CD__%" & rem :: you can use this "%__CD__%" or pushd "D:\Board\Broadcast\FA_Report8_A"
for /f "tokens=2delims==." %%i in ('wmic OS Get localdatetime /value ^|findstr /r [0-9]')do set "_date=%%i"
set _now=!_date:~0,4!!_date:~4,2!!_date:~6,2! & for /f "tokens=1*delims=-" %%i in ('echo/!_both!')do (
call :compare "%%~fi" & call :compare "%%~fj" & if !_dt_file_2! gtr !_dt_file_2! (
echo/ FileOne Greater - run bat & timeout /t 20 /nobreak & goto :run_bat
) else (echo/ FileOne not Greater - Finish & goto Finish)
)
:compare
set "_file=" & set "_file=%~1"
for /f "tokens=1delims=. " %%d in ('wmic datafile where name^='!_file:\=\\!' get LastModified ^|findstr /v "LastModified"')do (
if "!_dt_file_1!./" == "./" (set _dt_file_2=%%d) else (set _dt_file_2=%%d)
) & exit /b
:run_bat
call the_bat_to_run.cmd
:Finish
echo/Finished
So sorry by my limited English...
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)?
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.
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
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.
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
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
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!
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%
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.