Setting a windows batch file variable to the day of the week - windows

I have a windows batch file that runs daily. Wish to log data into a file and want to rotate it (i.e. having at most the last 7 days worth of data).
Looked into the commands DATE and DELIMS - Cannot figure out a solution.
Is there a simple solution to create a file name that contains the day of the week i.e. 0 for monday etc.
Or do I have to resort to some better shell script.

%DATE% is not your friend. Because the %DATE% environment variable (and the DATE command) returns the current date using the Windows short date format that is fully and endlessly customizable. One user may configure the system to return 07/06/2012 while another might choose Fri060712. Using %DATE% is a complete nightmare for a BAT programmer.
There are two possible approaches to solve this problem:
You may be tempted to temporarily change the short date format, by changing the locale settings in the registry value HKCU\Control Panel\International\sShortDate, to your recognizable format. Then access %DATE% to get the date in the format you want; and finally restore the format back to the original user format. Something like this
reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f >nul
reg add "HKCU\Control Panel\International" /v sShortDate /d "ddd" /f >nul
set DOW=%DATE%
reg copy "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f >nul
but this method has two problems:
it tampers with a global registry value for its local particular purpouses, so it may interfere with other processes or user tasks that at the very same time query the date in short date format, including itself if run simultaneously.
and it returns the three letter day of the week in the local language that may be different in different systems or different users.
use WMIC Win32_LocalTime, that returns the date in a convenient way to directly parse it with a FOR command.
FOR /F "skip=1" %%A IN ('WMIC Path Win32_LocalTime Get DayOfWeek' ) DO (
set DOW=%%A
)
this is the method I recommend.

few more ways:
1.Robocopy not available in XP but can be downloaded form with win 2003 resource tool kit .Also might depend on localization:
#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%
endlocal
2.MAKECAB - works on every windows machine (but creates a small temp file).Function provided by carlos:
#Echo Off
Call :GetDate.Init
Rem :GetDate.Init should be called one time in the code before call to :Getdate
Call :GetDate
Echo weekday:%weekday%
Goto :EOF
:GetDate.Init
Set /A "jan=1,feb=2,mar=3,apr=4,may=5,jun=6,jul=7,aug=8,sep=9,oct=10,nov=11,dec=12"
Set /A "mon=1,tue=2,wed=3,thu=4,fri=5,sat=6,sun=7"
(
Echo .Set InfHeader=""
Echo .Set InfSectionOrder=""
Echo .Set InfFooter="%%2"
Echo .Set InfFooter1=""
Echo .Set InfFooter2=""
Echo .Set InfFooter3=""
Echo .Set InfFooter4=""
Echo .Set Cabinet="OFF"
Echo .Set Compress="OFF"
Echo .Set DoNotCopyFiles="ON"
Echo .Set RptFileName="NUL"
) >"%Temp%\~foo.ddf"
Goto :Eof
:GetDate
Set "tf=%Temp%\~%random%"
Makecab /D InfFileName="%tf%" /F "%Temp%\~foo.ddf" >NUL
For /F "usebackq tokens=1-7 delims=: " %%a In ("%tf%") Do (
Set /A "year=%%g,month=%%b,day=1%%c-100,weekday=%%a"
Set /A "hour=1%%d-100,minute=1%%e-100,second=1%%f-100")
Del "%tf%" >NUL 2>&1
Goto :Eof
3.W32TM - uses command switches introduced in Vista so will not work on windows 2003/XP:
#echo off
setlocal
call :w32dow day_ow
echo %day_ow%
pause
exit /b 0
endlocal
:w32dow [RrnVar]
setlocal
rem :: prints the day of the week
rem :: works on Vista and above
rem :: getting ansi date ( days passed from 1st jan 1601 ) , timer server hour and current hour
FOR /F "tokens=4,5 delims=:( " %%D in ('w32tm /stripchart /computer:localhost /samples:1 /period:1 /dataonly /packetinfo^|find "Transmit Timestamp:" ') do (
set "ANSI_DATE=%%D"
set "TIMESERVER_HOURS=%%E"
)
set "LOCAL_HOURS=%TIME:~0,2%"
if "%TIMESERVER_HOURS:~0,1%0" EQU "00" set TIMESERVER_HOURS=%TIMESERVER_HOURS:~1,1%
if "%LOCAL_HOURS:~0,1%0" EQU "00" set LOCAL_HOURS=%LOCAL_HOURS:~1,1%
set /a OFFSET=TIMESERVER_HOURS-LOCAL_HOURS
rem :: day of the week will be the modulus of 7 of local ansi date +1
rem :: we need need +1 because Monday will be calculated as 0
rem :: 1st jan 1601 was Monday
rem :: if abs(offset)>12 we are in different days with the time server
IF %OFFSET%0 GTR 120 set /a DOW=(ANSI_DATE+1)%%7+1
IF %OFFSET%0 LSS -120 set /a DOW=(ANSI_DATE-1)%%7+1
IF %OFFSET%0 LEQ 120 IF %OFFSET%0 GEQ -120 set /a DOW=ANSI_DATE%%7+1
rem echo Day of the week: %DOW%
endlocal & if "%~1" neq "" (set "%~1=%DOW%") else echo %DOW%
4..bat/jscript hybrid (must be saved as .bat):
#if (#x)==(#y) #end /***** jscript comment ******
#echo off
for /f %%d in ('cscript //E:JScript //nologo "%~f0"') do echo %%d
exit /b 0
***** end comment *********/
WScript.Echo((new Date).getDay());
5..bat/vbscript hybrid (must be saved as .bat)
:sub echo(str) :end sub
echo off
'>nul 2>&1|| copy /Y %windir%\System32\doskey.exe '.exe >nul
'& echo/
'& for /f %%w in ('cscript /nologo /E:vbscript %~dpfn0') do echo day of the week %%w
'& echo/
'& del /q "'.exe" >nul 2>&1
'& exit /b
WScript.Echo Weekday(Date)
WScript.Quit
6.powershell can be downloaded from microsoft.Available by default in everything form win7 and above:
#echo off
setlocal
for /f %%d in ('"powershell (Get-Date).DayOfWeek.Value__"') do set dow=%%d
echo day of the week : %dow%
endlocal
7.WMIC already used as an answer but just want to have a full reference.And with cleared <CR>:
#echo off
setlocal
for /f "delims=" %%a in ('wmic path win32_localtime get dayofweek /format:list ') do for /f "delims=" %%d in ("%%a") do set %%d
echo day of the week : %dayofweek%
endlocal
9.Selfcompiled jscript.net (must be saved as .bat):
#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.DayOfWeek);

#ECHO OFF
REM GET DAY OF WEEK VIA DATE TO JULIAN DAY NUMBER CONVERSION
REM ANTONIO PEREZ AYALA
REM GET MONTH, DAY, YEAR VALUES AND ELIMINATE LEFT ZEROS
FOR /F "TOKENS=1-3 DELIMS=/" %%A IN ("%DATE%") DO SET /A MM=10%%A %% 100, DD=10%%B %% 100, YY=%%C
REM CALCULATE JULIAN DAY NUMBER, THEN DAY OF WEEK
IF %MM% LSS 3 SET /A MM+=12, YY-=1
SET /A A=YY/100, B=A/4, C=2-A+B, E=36525*(YY+4716)/100, F=306*(MM+1)/10, JDN=C+DD+E+F-1524
SET /A DOW=(JDN+1)%%7
DOW is 0 for Sunday, 1 for Monday, etc.

I thought that my first answer gives the correct day of week as a number between 0 and 6. However, because you had not indicated why this answer does not give the result you want, I can only guess the reason.
The Batch file below create a log file each day with a digit in the name, 0=Sunday, 1=Monday, etc... The program assume that echo %date% show the date in MM/DD/YYYY format; if this is not the case, just change the position of mm and dd variables in the for command.
#echo off
for /F "tokens=1-3 delims=/" %%a in ("%date%") do set /A mm=10%%a %% 100, dd=10%%b %% 100, yy=%%c
if %mm% lss 3 set /A mm+=12, yy-=1
set /A a=yy/100, b=a/4, c=2-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10, dow=(c+dd+e+f-1523)%%7
echo Today log data > Day-%dow%.txt
If this is not what you want, please indicate the problem so I can fix it.
EDIT: The version below get date parts independent of locale settings:
#echo off
for /F "skip=1 tokens=2-4 delims=(-/)" %%A in ('date ^< NUL') do (
for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
set %%A=%%a
set %%B=%%b
set %%C=%%c
)
)
set /A mm=10%mm% %% 100, dd=10%dd% %% 100
if %mm% lss 3 set /A mm+=12, yy-=1
set /A a=yy/100, b=a/4, c=2-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10,
dow=(c+dd+e+f-1523)%%7
echo Today log data > Day-%dow%.txt
EDIT: The version below insert day of week as 3-letter short name:
#echo off
for /F "skip=1 tokens=2-4 delims=(-/)" %%A in ('date ^< NUL') do (
for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
set %%A=%%a
set %%B=%%b
set %%C=%%c
)
)
set /A mm=10%mm% %% 100, dd=10%dd% %% 100
if %mm% lss 3 set /A mm+=12, yy-=1
set /A a=yy/100, b=a/4, c=2-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10,
dow=(c+dd+e+f-1523)%%7 + 1
for /F "tokens=%dow%" %%a in ("Sun Mon Tue Wed Thu Fri Sat") do set dow=%%a
echo Today log data > Day-%dow%.txt
Regards,
Antonio

This turned out way more complex then I first suspected, and I guess that's what intrigued me, I searched every where and all the methods given wouldnt work on Windows 7.
So I have an alternate solution which uses a Visual Basic Script.
The batch creates and executes the script(DayOfWeek.vbs), assigns the scripts output (Monday, Tuesday etc) to a variable (dow), the variable is then checked and another variable (dpwnum) assigned with the days number, afterwards the VBS is deleted hope it helps:
#echo off
REM Create VBS that will get day of week in same directory as batch
echo wscript.echo WeekdayName(Weekday(Date))>>DayOfWeek.vbs
REM Cycle through output to get day of week i.e monday,tuesday etc
for /f "delims=" %%a in ('cscript /nologo DayOfWeek.vbs') do #set dow=%%a
REM delete vbs
del DayOfWeek.vbs
REM Used for testing outputs days name
echo %dow%
REM Case of the days name is important must have a capital letter at start
REM Check days name and assign value depending
IF %dow%==Monday set downum=0
IF %dow%==Tuesday set downum=1
IF %dow%==Wednesday set downum=2
IF %dow%==Thursday set downum=3
IF %dow%==Friday set downum=4
IF %dow%==Saturday set downum=5
IF %dow%==Sunday set downum=6
REM print the days number 0-mon,1-tue ... 6-sun
echo %downum%
REM set a file name using day of week number
set myfile=%downum%.bak
echo %myfile%
pause
exit
EDIT:
Though I turned to VBS, It can be done in pure batch, took me a while to get it working and a lot of searching lol, but this seems to work:
#echo off
SETLOCAL enabledelayedexpansion
SET /a count=0
FOR /F "skip=1" %%D IN ('wmic path win32_localtime get dayofweek') DO (
if "!count!" GTR "0" GOTO next
set dow=%%D
SET /a count+=1
)
:next
echo %dow%
pause
The only caveat for you on the above batch is that its day of weeks are from 1-7 and not 0-6

This works for me
FOR /F "tokens=3" %%a in ('robocopy ^|find "Started"') DO SET TODAY=%%a

I am in the US. I can run this code in Windows 7, Windows 2008 R2, Windows Server 2003, Windows XP (All OS's are current with Windows Updates and patches). All with short date setting without ddd (or dddd) (day of week).
#echo off
for /f %%a in ('date /t') do set DAY=%%a
echo.
echo The Day Is: %DAY%
echo.
If today is Thursday, it would output "The Day Is: Thu".
This returns the day on all 4 Windows versions I have tested on. And only the day. When I changed my short date setup to be "ddd, M/d/yyyy", my output would show the day with a comma (e.g. Thu,) which tells me this code does use the short date format. But what also may be happening is that if the short date does not contain the day of week, it may look to the long date format which on all 4 machines I tested on, have dddd in the format.

This is not my work (well, I modified it slightly from the example), and it's late to the game, but this works on Server 2003 for me;
#echo off
set daysofweek=Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
for /F "skip=2 tokens=2-4 delims=," %%A in ('WMIC Path Win32_LocalTime Get DayOfWeek /Format:csv') do set daynumber=%%A
for /F "tokens=%daynumber% delims=," %%B in ("%daysofweek%") do set day=%%B
Citation: TechSupportForum

First - Copy CON SETUPDAY.001
SET WORKDAY=^Z (very important - no cr/lf)
DATE /T >SETUPDAY.002
COPY SETUPDAY.001+SETUPDAY.002 NEWDAY.BAT >nul
CALL NEWDAY.BAT
SET WEEKDAY=%WORKDAY:~0,3%
SET MDY=%WORKDAY:~4,10%
USE %WEEKDAY% IN YOUR SCRIPT

Locale-dependent version: In some environments, the following will extract the day name from the date:
set dayname=%date:~0,3%
It assumes that the day name is the first part of %date%. Depending on the machine settings, though, the substring part (~0,3) would need to change.
A statement such as this would dump to a file with a three character day name:
set logfile=%date:~0,3%.log
echo some stuff > %logfile%
Locale-independent version: If you need it less dependent on the current machine's day format, another way of doing it would be to write a tiny application that prints the day of the week. Then use the output of that program from the batch file. For example, the following C application prints dayN where N=0..6.
#include <stdio.h>
#include <time.h>
int main( int argc, char* argv[] )
{
time_t curtime;
struct tm * tmval;
time( &curtime );
tmval = localtime( &curtime );
// print dayN. Or use a switch statement and print
// the actual day name if you want
printf( "day%d", tmval->tm_wday );
}
If the above were compiled and linked as myday.exe, then you could use it from a batch file like this:
for /f %%d in ('myday.exe') do set logfile=%%d.log
echo some stuff > %logfile%

I have this solution working for me:
Create a file named dayOfWeek.vbs in the same dir where the cmd file will go.
dayOfWeek.vbs contains a single line:
wscript.stdout.write weekdayname(weekday(date))
or, if you want day number instead of name:
wscript.stdout.write weekday(date)
The cmd file will have this line:
For /F %%A In ('CScript dayOfWeek.vbs //NoLogo') Do Set dayName=%%A
Now you can use variable dayName like:
robocopy c:\inetpub \\DCStorage1\Share1\WebServer\InetPub_%dayName% /S /XD history logs

Another spin on this topic. The below script displays a few days around the current, with day-of-week prefix.
At the core is the standalone :dpack routine that encodes the date into a value whose modulo 7 reveals the day-of-week per ISO 8601 standards (Mon == 0). Also provided is :dunpk which is the inverse function:
#echo off& setlocal enabledelayedexpansion
rem 10/23/2018 daydate.bat: Most recent version at paulhoule.com/daydate
rem Example of date manipulation within a .BAT file.
rem This is accomplished by first packing the date into a single number.
rem This demo .bat displays dates surrounding the current date, prefixed
rem with the day-of-week.
set days=0Mon1Tue2Wed3Thu4Fri5Sat6Sun
call :dgetl y m d
call :dpack p %y% %m% %d%
for /l %%o in (-3,1,3) do (
set /a od=p+%%o
call :dunpk y m d !od!
set /a dow=od%%7
for %%d in (!dow!) do set day=!days:*%%d=!& set day=!day:~,3!
echo !day! !y! !m! !d!
)
exit /b
rem gets local date returning year month day as separate variables
rem in: %1 %2 %3=var names for returned year month day
:dgetl
setlocal& set "z="
for /f "skip=1" %%a in ('wmic os get localdatetime') do set z=!z!%%a
set /a y=%z:~0,4%, m=1%z:~4,2% %%100, d=1%z:~6,2% %%100
endlocal& set /a %1=%y%, %2=%m%, %3=%d%& exit /b
rem packs date (y,m,d) into count of days since 1/1/1 (0..n)
rem in: %1=return var name, %2= y (1..n), %3=m (1..12), %4=d (1..31)
rem out: set %1= days since 1/1/1 (modulo 7 is weekday, Mon= 0)
:dpack
setlocal enabledelayedexpansion
set mtb=xxx 0 31 59 90120151181212243273304334& set /a r=%3*3
set /a t=%2-(12-%3)/10, r=365*(%2-1)+%4+!mtb:~%r%,3!+t/4-(t/100-t/400)-1
endlocal& set %1=%r%& exit /b
rem inverse of date packer
rem in: %1 %2 %3=var names for returned year month day
rem %4= packed date (large decimal number, eg 736989)
:dunpk
setlocal& set /a y=%4+366, y+=y/146097*3+(y%%146097-60)/36524
set /a y+=y/1461*3+(y%%1461-60)/365, d=y%%366+1, y/=366
set e=31 60 91 121 152 182 213 244 274 305 335
set m=1& for %%x in (%e%) do if %d% gtr %%x set /a m+=1, d=%d%-%%x
endlocal& set /a %1=%y%, %2=%m%, %3=%d%& exit /b

If you can change format of short date in the PC to "ddd yyyy-MM-dd" (only first parameter 'ddd' is compulsory), then following command returns-
c:\>vol | date
The current date is: Mon 2014-12-01
Then you can write you batch file -
#echo off
vol | date | find /i "sun" > nul
if not errorlevel 1 goto SUN
vol | date | find /i "mon" > nul
if not errorlevel 1 goto MON
# write block for other week days
goto END
:SUN
set fname="sun"
goto BACKUP
:MON
set fname="mon"
goto BACKUP
# write block for other week days
:BACKUP
echo %fname%
:END

Rem Remove the end comma and add /A to set for this line worked for me.
set /A a=yy/100, b=a/4, c=2-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10

Was looking to do this myself and saw complaints about blank lines:
rem Make the win32_localtime output all one line, though some versions may contain blank lines as well.
rem So ignore blank lines and just pick up the number after the equal sign.
for /f "delims== tokens=2" %%a in ('wmic path win32_localtime get dayofweek /format:list') do (
rem Increment the DOW as it is documented to be a zero-based index starting with Sunday.
set /a DayOfWeekIndex=%%a+1
)
rem Also get name day of week. The DOW coming in is now a one-based index.
rem This is used to reference the "array" of week day names.
set DayOfWeekNames=Sun Mon Tue Wed Thu Fri Sat
for /f "tokens=%DayOfWeekIndex%" %%b in ("%DayOfWeekNames%") do (
set DayOfWeekName=%%b
)

I Improved Aacini Answer
to make it Echo Full day of week Name
So here's my Code
#echo off
for /F "skip=1 tokens=2-4 delims=(-/)" %%A in ('date ^< NUL') do (
for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
set %%A=%%a
set %%B=%%b
set %%C=%%c
)
)
set /A mm=10%mm% %% 100, dd=10%dd% %% 100
if %mm% lss 3 set /A mm+=12, yy-=1
set /A a=yy/100, b=a/4, c=4-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10,dow=(c+dd+e+f-1523)%%7 + 1
for /F "tokens=%dow%" %%a in ("Sunday Monday Tuesday Wednesday Thursday Friday Saturday ") do set dow=%%a
echo Today is %dow%>"Today is %dow%.txt"
echo Today is %dow%
Pause>Nul
REM Sun Mon Tue Wed Thu Fri Sat
REM Sunday Monday Tuesday Wednesday Thursday Friday Saturday

I use Tiny C to write a weekday.exe and run with batch file.
for /f %% in ('weekday.exe') do set weekday=%%i
weekday.c:
#include <time.h>
#include <stdio.h>
int main(int argc, char** argv) {
time_t curtime;
struct tm * tmval;
time( &curtime );
tmval = localtime( &curtime );
if (tmval->tm_wday == 1) printf("Mon");
if (tmval->tm_wday == 2) printf("Tue");
if (tmval->tm_wday == 3) printf("Wed");
if (tmval->tm_wday == 4) printf("Thu");
if (tmval->tm_wday == 5) printf("Fri");
if (tmval->tm_wday == 6) printf("Sat");
if (tmval->tm_wday == 0) printf("Sun");
return 0;
}

A version using MSHTA and javascript. Change %jsfunc% to whateve jscript function you want to call
#echo off
::Invoke a javascript function using mhta
set jsfunc=new Date().getDay()
set dialog="about:<script>resizeTo(0,0);new ActiveXObject('Scripting.FileSystemObject').
set dialog=%dialog%GetStandardStream(1).WriteLine(%jsfunc%);close();</script>"
for /f "tokens=* delims=" %%p in ('mshta.exe %dialog%') do set ndow=%%p
::get dow string from array of strings
for /f "tokens=%ndow%" %%d in ("Mon Tue Wed Thu Fri Sat Sun") do set dow=%%d
echo dow is : %ndow% %dow%
pause

Related

using a FOR /L loop to loop through the months of the year depedning on the current month in a batch file

I am trying to do a FOR /L loop for a class of mine i have gotten it to loop the 12 times but its not changing the MonthName variable to display each month. what i want it ot so is take the current month number and execute the loop that many times with the months of the year like for the first time through the loop i want it to display 1. January then 2. Febuary and so on till it reaches the current month here is the code i have so far and a sample execution i can only get it to display the current month's name
rem #echo off
setlocal enabledelayedexpansion
set CurrentMonth=%date:~4,2%
IF %currentMonth% EQU 08 (
set /a currentMonth=8
)
IF %currentMonth% EQU 09 (
set /a currentMonth=9
)
set Mmap=1-Januray;2-Febuary;3-March;4-April;5-May;6-June;7-July;8-August;9-September;10-October;11-November;12-December;
FOR /L %%x in (1,1,!CurrentMonth!) DO (
call set MonthName=%%Mmap:*%%x-=%%
set MonthName=%MonthName:;=&rem.%
echo %%x !MonthName! )
C:\Users\cis106stu\BATCHFILES5>FORLOOP
1 December
2 December
3 December
4 December
5 December
6 December
7 December
8 December
9 December
10 December
11 December
12 December
C:\Users\cis106stu\BATCHFILES5>
As you insist on using a for /l loop:
#echo off
setlocal enabledelayedexpansion
set /a CurrentMonth=1%date:~4,2%-100
set "Mmap=;1-Januray;2-Febuary;3-March;4-April;5-May;6-June;7-July;8-August;9-September;10-October;11-November;12-December;"
FOR /L %%x in (1,1,!CurrentMonth!) DO (
set MonthName=!Mmap:*;%%x-=!
for /f "delims=;" %%y in ("!MonthName!") do echo %%x %%y
)
I added a leading ; to Mmap, used another method to split the string and took advantage of delayed expansion (why not use it when you already enabled it)
(Note: the format of %date% is highly user configurable, so %date:~4,2% may extract the wrong string. It works for the format DDD MM/dd/yyyy and has to be adapted for other formats (better use a settings-independent solution))
Just use a for /l loop and loop 12 times to get the variables we've set and wmic to determine the month you're in.
#echo off
set "m1=January" & set "m2=February" & set "m3=March" & set "m4=April" & set "m5=May" & set "m6=June" & set "m7=July" & set "m8=August" & set "m9=September" & set "m10=October" & set "m11=November" & set "m12=December"
for /f %%i in ('wmic path win32_localtime get month ^| findstr /r /c:[1-12]') do for /l %%a in (1,1,12) do if %%a leq %%i call echo %%a %%m%%a%%%
The above does not require the CurrentMonth variable to be set as the metavariable %%i has that value. If you however still want to set the variable, you can:
#echo off
set "m1=January" & set "m2=February" & set "m3=March" & set "m4=April" & set "m5=May" & set "m6=June" & set "m7=July" & set "m8=August" & set "m9=September" & set "m10=October" & set "m11=November" & set "m12=December"
for /f %%i in ('wmic path win32_localtime get month ^| findstr /r /c:[1-12]') do set /a CurrentMonth=%%i
for /l %%a in (1,1,12) do if %%a leq %CurrentMonth% call echo %%a %%m%%a%%%
Let me suggest an alternative approach (both with correcting the date format and with the extraction from the string Mmap:
#echo off
setlocal
set /a CurrentMonth=1%date:~4,2%-100
set "Mmap=1-Januray;2-Febuary;3-March;4-April;5-May;6-June;7-July;8-August;9-September;10-October;11-November;12-December"
for %%a in (%Mmap%) do (
for /f "tokens=1,2 delims=-" %%b in ("%%a") do (
if %%b leq %CurrentMonth% echo %%b %%c
)
)
(Note: the format of %date% is highly user configurable, so %date:~4,2% may extract the wrong string. It works for the format DDD MM/dd/yyyy and has to be adapted for other formats (better use a settings-independent solution))

date and time not saved in correct format while executing batch file [duplicate]

Update: Now that it's 2016 I'd use PowerShell for this unless there's a really compelling backwards-compatible reason for it, particularly because of the regional settings issue with using date. See #npocmaka's https://stackoverflow.com/a/19799236/8479
What's a Windows command line statement(s) I can use to get the current datetime in a format that I can put into a filename?
I want to have a .bat file that zips up a directory into an archive with the current date and time as part of the name, for example, Code_2008-10-14_2257.zip. Is there any easy way I can do this, independent of the regional settings of the machine?
I don't really mind about the date format, ideally it'd be yyyy-mm-dd, but anything simple is fine.
So far I've got this, which on my machine gives me Tue_10_14_2008_230050_91:
rem Get the datetime in a format that can go in a filename.
set _my_datetime=%date%_%time%
set _my_datetime=%_my_datetime: =_%
set _my_datetime=%_my_datetime::=%
set _my_datetime=%_my_datetime:/=_%
set _my_datetime=%_my_datetime:.=_%
rem Now use the timestamp by in a new ZIP file name.
"d:\Program Files\7-Zip\7z.exe" a -r Code_%_my_datetime%.zip Code
I can live with this, but it seems a bit clunky. Ideally it'd be briefer and have the format mentioned earlier.
I'm using Windows Server 2003 and Windows XP Professional. I don't want to install additional utilities to achieve this (although I realise there are some that will do nice date formatting).
See Windows Batch File (.bat) to get current date in MMDDYYYY format:
#echo off
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 /t') do (set mytime=%%a%%b)
echo %mydate%_%mytime%
If you prefer the time in 24 hour/military format, you can replace the second FOR line with this:
For /f "tokens=1-2 delims=/:" %%a in ("%TIME%") do (set mytime=%%a%%b)
C:> .\date.bat
2008-10-14_0642
If you want the date independently of the region day/month order, you can use "WMIC os GET LocalDateTime" as a source, since it's in ISO order:
#echo off
for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j
set ldt=%ldt:~0,4%-%ldt:~4,2%-%ldt:~6,2% %ldt:~8,2%:%ldt:~10,2%:%ldt:~12,6%
echo Local date is [%ldt%]
C:>test.cmd
Local date is [2012-06-19 10:23:47.048]
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 temp 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
More information about get-date function.
ROBOCOPY - it's not native command for Windows XP and Windows Server 2003, but it can be downloaded from microsoft site. But 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 form 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());
VSCRIPT/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, v3 (only for Windows 7 and above)). It is installed by default on everything from Windows 7/Windows Server 2008 and above:
C:\> powershell get-date -format "{dd-MMM-yyyy HH:mm}"
To use it from a batch file:
for /f "delims=" %%# in ('powershell get-date -format "{dd-MMM-yyyy HH:mm}"') do #set _date=%%#
Self-compiled jscript.net/batch (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 and also creates a temporary file and is based on the time stamps that logman puts on its log files. It will work on everything from Windows XP and above. It probably will be never used by anybody - including me - but 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
One more way with WMIC which also gives week of the year and the day of the week, but not the milliseconds (for milliseconds check foxidrive's answer):
for /f %%# in ('wMIC Path Win32_LocalTime Get /Format:value') do #for /f %%# in ("%%#") do #set %%#
echo %day%
echo %DayOfWeek%
echo %hour%
echo %minute%
echo %month%
echo %quarter%
echo %second%
echo %weekinmonth%
echo %year%
Using TYPEPERF with some efforts to be fast and compatible with different language settings and as fast as possible:
#echo off
setlocal
:: Check if Windows is Windows XP and use Windows XP valid counter for UDP performance
::if defined USERDOMAIN_roamingprofile (set "v=v4") else (set "v=")
for /f "tokens=4 delims=. " %%# in ('ver') do if %%# GTR 5 (set "v=v4") else ("v=")
set "mon="
for /f "skip=2 delims=," %%# in ('typeperf "\UDP%v%\*" -si 0 -sc 1') do (
if not defined mon (
for /f "tokens=1-7 delims=.:/ " %%a in (%%#) do (
set mon=%%a
set date=%%b
set year=%%c
set hour=%%d
set minute=%%e
set sec=%%f
set ms=%%g
)
)
)
echo %year%.%mon%.%date%
echo %hour%:%minute%:%sec%.%ms%
endlocal
MSHTA allows calling JavaScript methods similar to the JScript method demonstrated in #3 above. Bear in mind that JavaScript's Date object properties involving month values are numbered from 0 to 11, not 1 to 12. So a value of 9 means October.
<!-- : Batch portion
#echo off
setlocal
for /f "delims=" %%I in ('mshta "%~f0"') do set "now.%%~I"
rem Display all variables beginning with "now."
set now.
goto :EOF
end batch / begin HTA -->
<script>
resizeTo(0,0)
var fso = new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1),
now = new Date(),
props=['getDate','getDay','getFullYear','getHours','getMilliseconds','getMinutes',
'getMonth','getSeconds','getTime','getTimezoneOffset','getUTCDate','getUTCDay',
'getUTCFullYear','getUTCHours','getUTCMilliseconds','getUTCMinutes','getUTCMonth',
'getUTCSeconds','getYear','toDateString','toGMTString','toLocaleDateString',
'toLocaleTimeString','toString','toTimeString','toUTCString','valueOf'],
output = [];
for (var i in props) {output.push(props[i] + '()=' + now[props[i]]())}
close(fso.Write(output.join('\n')));
</script>
Regionally independent date time parsing
The output format of %DATE% and of the dir command is regionally dependent and thus neither robust nor smart. date.exe (part of UnxUtils) delivers any date and time information in any thinkable format. You may also extract the date/time information from any file with date.exe.
Examples: (in a cmd-script use %% instead of %)
date.exe +"%Y-%m-%d"
2009-12-22
date.exe +"%T"
18:55:03
date.exe +"%Y%m%d %H%M%S: Any text"
20091222 185503: Any text
date.exe +"Text: %y/%m/%d-any text-%H.%M"
Text: 09/12/22-any text-18.55
Command: date.exe +"%m-%d """%H %M %S """"
07-22 "18:55:03"`
The date/time information from a reference file:
date.exe -r c:\file.txt +"The timestamp of file.txt is: %Y-%m-%d %H:%M:%S"
Using it in a CMD script to get year, month, day, time information:
for /f "tokens=1,2,3,4,5,6* delims=," %%i in ('C:\Tools\etc\date.exe +"%%y,%%m,%%d,%%H,%%M,%%S"') do set yy=%%i& set mo=%%j& set dd=%%k& set hh=%%l& set mm=%%m& set ss=%%n
Using it in a CMD script to get a timestamp in any required format:
for /f "tokens=*" %%i in ('C:\Tools\etc\date.exe +"%%y-%%m-%%d %%H:%%M:%%S"') do set timestamp=%%i
Extracting the date/time information from any reference file.
for /f "tokens=1,2,3,4,5,6* delims=," %%i in ('C:\Tools\etc\date.exe -r file.txt +"%%y,%%m,%%d,%%H,%%M,%%S"') do set yy=%%i& set mo=%%j& set dd=%%k& set hh=%%l& set mm=%%m& set ss=%%n
Adding to a file its date/time information:
for /f "tokens=*" %%i in ('C:\Tools\etc\date.exe -r file.txt +"%%y-%%m-%%d.%%H%%M%%S"') do ren file.txt file.%%i.txt
date.exe is part of the free GNU tools which need no installation.
NOTE: Copying date.exe into any directory which is in the search path may cause other scripts to fail that use the Windows built-in date command.
Here's a variant from alt.msdos.batch.nt that works local-independently.
Put this in a text file, e.g. getDate.cmd
-----------8<------8<------------ snip -- snip ----------8<-------------
:: Works on any NT/2k machine independent of regional date settings
#ECHO off
SETLOCAL ENABLEEXTENSIONS
if "%date%A" LSS "A" (set toks=1-3) else (set toks=2-4)
for /f "tokens=2-4 delims=(-)" %%a in ('echo:^|date') do (
for /f "tokens=%toks% delims=.-/ " %%i in ('date/t') do (
set '%%a'=%%i
set '%%b'=%%j
set '%%c'=%%k))
if %'yy'% LSS 100 set 'yy'=20%'yy'%
set Today=%'yy'%-%'mm'%-%'dd'%
ENDLOCAL & SET v_year=%'yy'%& SET v_month=%'mm'%& SET v_day=%'dd'%
ECHO Today is Year: [%V_Year%] Month: [%V_Month%] Day: [%V_Day%]
:EOF
-----------8<------8<------------ snip -- snip ----------8<-------------
To get the code to work sans error msg's to stderr, I had to add the single quotes arount the variable assignments for %%a, %%b and %%c. My locale (PT) was causing errors at one stage in the looping/parsing where stuff like "set =20" was getting executed. The quotes yield a token (albeit empty) for the left-hand side of the assignment statement.
The downside is the messy locale variable names: 'yy', 'mm' and 'dd'. But hey, who cares!
I use this (again not region independent (UK))
set bklog=%date:~6,4%-%date:~3,2%-%date:~0,2%_%time:~0,2%%time:~3,2%
The first four lines of this code will give you reliable YY DD MM YYYY HH Min Sec variables in Windows XP Professional and higher.
#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
Unfortunately this is not immune to regional settings, but it does what you want.
set hour=%time:~0,2%
if "%time:~0,1%"==" " set hour=0%time:~1,1%
set _my_datetime=%date:~10,4%-%date:~4,2%-%date:~7,2%_%hour%%time:~3,2%
Amazing the stuff you can find on Wikipedia.
Please use the following script to get the current day in the command line:
echo %Date:~0,3%day
"d:\Program Files\7-Zip\7z.exe" a -r code_%date:~10,4%-%date:~4,2%-%date:~7,2%.zip
Another way (credit):
#For /F "tokens=2,3,4 delims=/ " %%A in ('Date /t') do #(
Set Month=%%A
Set Day=%%B
Set Year=%%C
)
#echo DAY = %Day%
#echo Month = %Month%
#echo Year = %Year%
Note that both my answers here are still reliant on the order of the day and month as determined by regional settings - not sure how to work around that.
This isn't really briefer but might be a more flexible way (credit):
FOR /F "TOKENS=1* DELIMS= " %%A IN ('DATE/T') DO SET CDATE=%%B
FOR /F "TOKENS=1,2 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET mm=%%B
FOR /F "TOKENS=1,2 DELIMS=/ eol=/" %%A IN ('echo %CDATE%') DO SET dd=%%B
FOR /F "TOKENS=2,3 DELIMS=/ " %%A IN ('echo %CDATE%') DO SET yyyy=%%B
SET date=%mm%%dd%%yyyy%
Short answer :
:: Start - Run , type:
cmd /c "powershell get-date -format ^"{yyyy-MM-dd HH:mm:ss}^"|clip"
:: click into target media, Ctrl + V to paste the result
Long answer
#echo off
:: START USAGE ==================================================================
::SET THE NICETIME
:: SET NICETIME=BOO
:: CALL GetNiceTime.cmd
:: ECHO NICETIME IS %NICETIME%
:: echo nice time is %NICETIME%
:: END USAGE ==================================================================
echo set hhmmsss
:: this is Regional settings dependant so tweak this according your current settings
for /f "tokens=1-3 delims=:" %%a in ('echo %time%') do set hhmmsss=%%a%%b%%c
::DEBUG ECHO hhmmsss IS %hhmmsss%
::DEBUG PAUSE
echo %yyyymmdd%
:: this is Regional settings dependant so tweak this according your current settings
for /f "tokens=1-3 delims=." %%D in ('echo %DATE%') do set yyyymmdd=%%F%%E%%D
::DEBUG ECHO yyyymmdd IS %yyyymmdd%
::DEBUG PAUSE
set NICETIME=%yyyymmdd%_%hhmmsss%
::DEBUG echo THE NICETIME IS %NICETIME%
::DEBUG PAUSE
Here's a way to get date time in a single line:
for /f "tokens=2,3,4,5,6 usebackq delims=:/ " %a in ('%date% %time%') do echo %c-%a-%b %d%e
In the US this will output "yyyy-mm-dd hhmm". Different regional settings will result in different %date% outputs, but you can modify the token order.
If you want a different format, modify the echo statement by rearranging the tokens or using different (or no) separators.
Just use this line:
PowerShell -Command "get-date"
Matthew Johnson's one-liner solution to get the one-liner date and time is eloquent and useful.
It does however need a simple modification to work from within a batch file:
for /f "tokens=2,3,4,5,6 usebackq delims=:/ " %%a in ('%date% %time%') do echo %%c-%%a-%%b %%d%%e
And here is a similar batch-file for the time portion.
:: http://stackoverflow.com/questions/203090/how-to-get-current-datetime-on-windows-command-line-in-a-suitable-format-for-usi
:: Works on any NT/2k machine independent of regional time settings
::
:: Gets the time in ISO 8601 24-hour format
::
:: Note that %time% gets you fractions of seconds, and time /t doesn't, but gets you AM/PM if your locale supports that.
:: Since ISO 8601 does not care about AM/PM, we use %time%
::
#ECHO off
SETLOCAL ENABLEEXTENSIONS
for /f "tokens=1-4 delims=:,.-/ " %%i in ('echo %time%') do (
set 'hh'=%%i
set 'mm'=%%j
set 'ss'=%%k
set 'ff'=%%l)
ENDLOCAL & SET v_Hour=%'hh'%& SET v_Minute=%'mm'%& SET v_Second=%'ss'%& SET v_Fraction=%'ff'%
ECHO Now is Hour: [%V_Hour%] Minute: [%V_Minute%] Second: [%v_Second%] Fraction: [%v_Fraction%]
set timestring=%V_Hour%%V_Minute%%v_Second%.%v_Fraction%
echo %timestring%
:EOF
--jeroen
I changed the answer with the batch file from vMax so it works with the Dutch language too.
The Dutch - persistent as we are - have a few changes in the %date%, date/t, and date that break the original batch-file.
It would be nice if some people can check this against other Windows locales as well, and report back the results.
If the batch-file fails at your location, then please include the output of these two statements on the command prompt:
echo:^|date
date/t
This is a sample of the output you should get from the batch-file:
C:\temp>set-date-cmd.bat
Today is Year: [2011] Month: [01] Day: [03]
20110103
Here is the revised code with comments on why:
:: https://stackoverflow.com/questions/203090/how-to-get-current-datetime-on-windows-command-line-in-a-suitable-format-for-usi
:: Works on any NT/2k machine independent of regional date settings
::
:: 20110103 - adapted by jeroen#pluimers.com for Dutch locale
:: Dutch will get jj as year from echo:^|date, so the '%%c' trick does not work as it will fill 'jj', but we want 'yy'
:: luckily, all countries seem to have year at the end: http://en.wikipedia.org/wiki/Calendar_date
:: set '%%c'=%%k
:: set 'yy'=%%k
::
:: In addition, date will display the current date before the input prompt using dashes
:: in Dutch, but using slashes in English, so there will be two occurances of the outer loop in Dutch
:: and one occurence in English.
:: This skips the first iteration:
:: if "%%a" GEQ "A"
::
:: echo:^|date
:: Huidige datum: ma 03-01-2011
:: Voer de nieuwe datum in: (dd-mm-jj)
:: The current date is: Mon 01/03/2011
:: Enter the new date: (mm-dd-yy)
::
:: date/t
:: ma 03-01-2011
:: Mon 01/03/2011
::
:: The assumption in this batch-file is that echo:^|date will return the date format
:: using either mm and dd or dd and mm in the first two valid tokens on the second line, and the year as the last token.
::
:: The outer loop will get the right tokens, the inner loop assigns the variables depending on the tokens.
:: That will resolve the order of the tokens.
::
#ECHO off
set v_day=
set v_month=
set v_year=
SETLOCAL ENABLEEXTENSIONS
if "%date%A" LSS "A" (set toks=1-3) else (set toks=2-4)
::DEBUG echo toks=%toks%
for /f "tokens=2-4 delims=(-)" %%a in ('echo:^|date') do (
::DEBUG echo first token=%%a
if "%%a" GEQ "A" (
for /f "tokens=%toks% delims=.-/ " %%i in ('date/t') do (
set '%%a'=%%i
set '%%b'=%%j
set 'yy'=%%k
)
)
)
if %'yy'% LSS 100 set 'yy'=20%'yy'%
set Today=%'yy'%-%'mm'%-%'dd'%
ENDLOCAL & SET v_year=%'yy'%& SET v_month=%'mm'%& SET v_day=%'dd'%
ECHO Today is Year: [%V_Year%] Month: [%V_Month%] Day: [%V_Day%]
set datestring=%V_Year%%V_Month%%V_Day%
echo %datestring%
:EOF
--jeroen
This is what I've used:
::Date Variables - replace characters that are not legal as part of filesystem file names (to produce name like "backup_04.15.08.7z")
SET DT=%date%
SET DT=%DT:/=.%
SET DT=%DT:-=.%
If you want further ideas for automating backups to 7-Zip archives, I have a free/open project you can use or review for ideas: http://wittman.org/ziparcy/
A function that is based on wmic:
:Now -- Gets the current date and time into separate variables
:: %~1: [out] Year
:: %~2: [out] Month
:: %~3: [out] Day
:: %~4: [out] Hour
:: %~5: [out] Minute
:: %~6: [out] Second
setlocal
for /f %%t in ('wmic os get LocalDateTime ^| findstr /b [0-9]') do set T=%%t
endlocal & (
if "%~1" neq "" set %~1=%T:~0,4%
if "%~2" neq "" set %~2=%T:~4,2%
if "%~3" neq "" set %~3=%T:~6,2%
if "%~4" neq "" set %~4=%T:~8,2%
if "%~5" neq "" set %~5=%T:~10,2%
if "%~6" neq "" set %~6=%T:~12,2%
)
goto:eof
Upside: Region independent. Downside: Only system administrators can run wmic.exe.
Usage:
call:Now Y M D H N S
echo %Y%-%M%-%D% %H%:%N%:%S%
This echos a string like this:
2014-01-22 12:51:53
Note that function parameters are out-Parameters - that is, you must supply variable names instead of values.
All parameters are optional, so call:Now Y M is a valid call if you only want to get year and month.
I had a similar problem. I have an automatic daily download from an FTP server of an encrypted file. I wanted to decrypt the file using gpg, rename the file to the current date (YYYYMMDD format) and drop the decrypted file into a folder for the correct department.
I went through several suggestions for renaming the file according to date and was having no luck until I stumbled upon this simple solution.
for /f "tokens=1-5 delims=/ " %%d in ("%date%") do rename "decrypted.txt" %%g-%%e-%%f.txt
It worked perfectly (i.e., the filename comes out as "2011-06-14.txt").
(Source)
http://sourceforge.net/projects/unxutils/files/
Look inside the ZIP file for something called "Date.exe" and rename it "DateFormat.exe" (to avoid conflicts).
Put it in your Windows system32 folder.
It has a lot of "date output" options.
For help, use DateFormat.exe --h
I'm not sure how you would put its output into an environment variable... using SET.
Combine Powershell into a batch file and use the meta variables to assign each:
#echo off
for /f "tokens=1-6 delims=-" %%a in ('PowerShell -Command "& {Get-Date -format "yyyy-MM-dd-HH-mm-ss"}"') do (
echo year: %%a
echo month: %%b
echo day: %%c
echo hour: %%d
echo minute: %%e
echo second: %%f
)
You can also change the the format if you prefer name of the month MMM or MMMM and 12 hour to 24 hour formats hh or HH
Regional independent solution generating the ISO date format:
rem save the existing format definition
for /f "skip=2 tokens=3" %%a in ('reg query "HKCU\Control Panel\International" /v sShortDate') do set FORMAT=%%a
rem set ISO specific format definition
reg add "HKCU\Control Panel\International" /v sShortDate /t REG_SZ /f /d yyyy-MM-dd 1>nul:
rem query the date in the ISO specific format
set ISODATE=%DATE%
rem restore previous format definition
reg add "HKCU\Control Panel\International" /v sShortDate /t REG_SZ /f /d %FORMAT% 1>nul:
What could still be optimized:
Other processes might get confused if using the date format in the short period while it is modified. So parsing the output according to the existing format string could be 'safer' - but will be more complicated
:: GetDate.cmd -> Uses WMIC.exe to get current date and time in ISO 8601 format
:: - Sets environment variables %_isotime% and %_now% to current time
:: - On failure, clears these environment variables
:: Inspired on -> https://ss64.com/nt/syntax-getdate.html
:: - (cX) 2017 adolfo.dimare#gmail.com
:: - http://stackoverflow.com/questions/203090
#echo off
set _isotime=
set _now=
:: Check that WMIC.exe is available
WMIC.exe Alias /? >NUL 2>&1 || goto _WMIC_MISSING_
if not (%1)==() goto _help
SetLocal EnableDelayedExpansion
:: Use WMIC.exe to retrieve date and time
FOR /F "skip=1 tokens=1-6" %%G IN ('WMIC.exe Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
IF "%%~L"=="" goto _WMIC_done_
set _yyyy=%%L
set _mm=00%%J
set _dd=00%%G
set _hour=00%%H
set _minute=00%%I
set _second=00%%K
)
:_WMIC_done_
:: 1 2 3 4 5 6
:: %%G %%H %%I %%J %%K %%L
:: Day Hour Minute Month Second Year
:: 27 9 35 4 38 2017
:: Remove excess leading zeroes
set _mm=%_mm:~-2%
set _dd=%_dd:~-2%
set _hour=%_hour:~-2%
set _minute=%_minute:~-2%
set _second=%_second:~-2%
:: Syntax -> %variable:~num_chars_to_skip,num_chars_to_keep%
:: Set date/time in ISO 8601 format:
Set _isotime=%_yyyy%-%_mm%-%_dd%T%_hour%:%_minute%:%_second%
:: -> http://google.com/search?num=100&q=ISO+8601+format
if 1%_hour% LSS 112 set _now=%_isotime:~0,10% %_hour%:%_minute%:%_second%am
if 1%_hour% LSS 112 goto _skip_12_
set /a _hour=1%_hour%-12
set _hour=%_hour:~-2%
set _now=%_isotime:~0,10% %_hour%:%_minute%:%_second%pm
:: -> https://ss64.com/nt/if.html
:: -> http://google.com/search?num=100&q=SetLocal+EndLocal+Windows
:: 'if () else ()' will NOT set %_now% correctly !?
:_skip_12_
EndLocal & set _isotime=%_isotime% & set _now=%_now%
goto _out
:_WMIC_MISSING_
echo.
echo WMIC.exe command not available
echo - WMIC.exe needs Administrator privileges to run in Windows
echo - Usually the path to WMIC.exe is "%windir%\System32\wbem\WMIC.exe"
:_help
echo.
echo GetDate.cmd: Uses WMIC.exe to get current date and time in ISO 8601 format
echo.
echo %%_now%% environment variable set to current date and time
echo %%_isotime%% environment variable to current time in ISO format
echo set _today=%%_isotime:~0,10%%
echo.
:_out
:: EOF: GetDate.cmd
I used date.exe, and renamed it to date_unxutils.exe to avoid conflicts.
Put it inside bin folder next to the batch script.
Code
:: Add binaries to temp path
IF EXIST bin SET PATH=%PATH%;bin
:: Create UTC Timestamp string in a custom format
:: Example: 20210128172058
set timestamp_command='date_unxutils.exe -u +"%%Y%%m%%d%%H%%M%%S"'
FOR /F %%i IN (%timestamp_command%) DO set timestamp=%%i
echo %timestamp%
Download UnxUtils
Link.
References
This awesome answer that I build upon.
PowerShell
Try the code below.
It will create the file or folder varible with the date as ddmmyyhhmm in 24hour time
[int] $day = Get-Date -UFormat %d
[int] $month = Get-Date -UFormat %m
[int] $year = Get-Date -UFormat %y
[String] $date = "$($day)$($month)$($year)"
$time = Get-Date -UFormat %R
$time -replace ‘[:]’,”"
$fileFolderName = $date + time
Given a known locality, for reference in functional form. The ECHOTIMESTAMP call shows how to get the timestamp into a variable (DTS in this example.)
#ECHO off
CALL :ECHOTIMESTAMP
GOTO END
:TIMESTAMP
SETLOCAL EnableDelayedExpansion
SET DATESTAMP=!DATE:~10,4!-!DATE:~4,2!-!DATE:~7,2!
SET TIMESTAMP=!TIME:~0,2!-!TIME:~3,2!-!TIME:~6,2!
SET DTS=!DATESTAMP: =0!-!TIMESTAMP: =0!
ENDLOCAL & SET "%~1=%DTS%"
GOTO :EOF
:ECHOTIMESTAMP
SETLOCAL
CALL :TIMESTAMP DTS
ECHO %DTS%
ENDLOCAL
GOTO :EOF
:END
EXIT /b 0
And saved to file, timestamp.bat, here's the output:
With Windows 7, this code works for me:
SET DATE=%date%
SET YEAR=%DATE:~0,4%
SET MONTH=%DATE:~5,2%
SET DAY=%DATE:~8,2%
ECHO %YEAR%
ECHO %MONTH%
ECHO %DAY%
SET DATE_FRM=%YEAR%-%MONTH%-%DAY%
ECHO %DATE_FRM%
I know that there are numerous ways mentioned already. But here is my way to break it down to understand how it is done. Hopefully, it is helpful for someone who like step by step method.
:: Check your local date format
echo %date%
:: Output is Mon 08/15/2016
:: get day (start index, number of characters)
:: (index starts with zero)
set myday=%DATE:~0,4%
echo %myday%
:: output is Mon
:: get month
set mymonth=%DATE:~4,2%
echo %mymonth%
:: output is 08
:: get date
set mydate=%DATE:~7,2%
echo %mydate%
:: output is 15
:: get year
set myyear=%DATE:~10,4%
echo %myyear%
:: output is 2016
I note that the o/p did not ask for a region-independent solution. My solution is for the UK though.
This is the simplest possible solution, a 1-line solution, for use in a Batch file:
FOR /F "tokens=1-3 delims=/" %%A IN ("%date%") DO (SET today=%%C-%%B-%%A)
echo %today%
This solution can be varied, by altering the order of the variables %%A %%B and %%C in the output statement, to provide any date format desired (e.g. YY-MM-DD or DD-MM-YY).
My intention - my ONLY intention - in posting this answer is to demonstrate that this can be done on the command line, by using a single line of code to achieve it.
And that it is redundant to post answers running to 35 lines of code, as others have done, because the o/p specifically asked for a command line solution in the question. Therefore the o/p specifically sought a single-line solution.

Day minus in windows batch file in 2 digit

I have a bat file which simply generates a date
for /f "tokens=2,3,4 delims=/ " %%a in ('date /t') do set CurrYear=%%c
for /f "tokens=2,3,4 delims=/ " %%a in ('date /t') do set CurrMoth=%%a
for /f "tokens=2,3,4 delims=/ " %%a in ('date /t') do set CurrDay=%%b
set bDate =01/%CurrMoth%/%CurrYear%
set eDate=%CurrDay%/%CurrMoth%/%CurrYear%
set /a dayminus = %CurrDay% - 1
echo %dayminus%
pause
The answer I get for echo %dayminus% is 6 instead of 06 & that's my problem.
If your intent is to simply ensure a number is left-zero-padded to two places, you can just use:
if %dayminus% lss 10 set dayminus=0%dayminus%
However, you'll soon run into another problem, specifically what you do when you run this on the first of the month. But that's probably a matter for a separate question (or you could just look at this one).
If you're open to using other tools (which ship with Windows, just like cmd.exe does), then VBScript is possibly the easiest option. You can just create a one-liner yesterdom.vbs:
wscript.echo day(date()-1)
and then call it from your script:
for /f %%a in ('cscript //nologo yesterdom.vbs') do set dayminus=%%a
If you don't want the hassle of maintaining the one-liner, you can create and destroy it from within your script, such as with:
#echo off
echo wscript.echo day(date()-1) >yesterdom.vbs
for /f %%a in ('cscript //nologo yesterdom.vbs') do set dayminus=%%a
del /q yesterdom.vbs >nul: 2>nul:
echo %dayminus%
(Interestingly, most people want to know how to go the other way.) The reason this is happening is because batch considers numbers that begin with a 0 to be octal and then simplifies them to drop the 0 when printing as an integer. You can get around this by treating the variable like a string instead.
set /a dayminus=%CurrDay%-1
if %dayminus% lss 10 (
set dayminus=0%dayminus%
)
echo %dayminus%
Here is a quick workaround that I have prepared for you in a sample program:
#echo off
set /a test = 4
IF %test% lss 10 (
#echo 0%test%
)
#pause
This will always get you a two digit number since anything below 10 will have the added 0 in front of it when it's being written to the screen.
This is a pure Batch file solution that get the date of yesterday; it also works for the current date minus any number of days less than a month:
#echo off
setlocal EnableDelayedExpansion
rem Create array of days per month; both month and day are 100-based
set i=100
for %%a in (31 28 31 30 31 30 31 31 30 31 30 31) do (
set /A i+=1
set "daysPerMonth[!i!]=1%%a"
)
rem Get today's date parts (from "Dow MM/DD/YYYY" format) - 1 day
for /F "tokens=2-4 delims=/ " %%a in ('date /T') do (
set /A MM=1%%a, DD=1%%b-1, YYYY=%%c, YYYYmod4=YYYY %% 4
)
if %YYYYmod4% equ 0 set "daysPerMonth[102]=129"
rem Adjust date if previous month
if %DD% equ 100 (
set /A MM-=1
if !MM! equ 100 (
set /A MM=112, YYYY-=1
)
set /A DD=daysPerMonth[!MM!]
)
set "dateMinus=%DD:~1%/%MM:~1%/%YYYY%
echo %dateMinus%

Split %date% in a batch file regardless of Regional Settings

Is there a way to split the %date% in a batch file (say, in 3 environment variables), but regardless of Regional Settings? Today's date would be 3/13/2013 for US, but with my Regional Settings it is 13.3.2013 - the delimiter is changed and the order as well.
Four years have passed, but this question doesn't get old, and I think now there's a slightly better answer than using wmic (on win7 onwards).
for /F "tokens=1,2,3 delims=_" %%i in ('PowerShell -Command "& {Get-Date -format "MM_dd_yyyy"}"') do (
set MONTH=%%i
set DAY=%%j
set YEAR=%%k
)
echo %MONTH% %DAY% %YEAR%
With powershell Get-Date you can fine-tune the format you want (short,long, numbers,names,etc..). In this example "MM_dd_yyyy" will get you a numeric date with leading zeros in case of single digit months or days
You can do it using wmic (but WMIC isn't included with XP Home):
#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
)
:s_done
:: Pad digits with leading zeros
Set _mm=%_mm:~-2%
Set _dd=%_dd:~-2%
Set _hour=%_hour:~-2%
Set _minute=%_minute:~-2%
:: Display the date/time in ISO 8601 format:
Set _isodate=%_yyyy%-%_mm%-%_dd% %_hour%:%_minute%
Echo %_isodate%
GOTO:EOF
:s_error
Echo GetDate.cmd
Echo Displays date and time independent of OS Locale, Language or date format.
Echo Requires Windows XP Professional, Vista or Windows 7
Echo.
Echo Returns 6 environment variables containing isodate,Year,Month,Day,hour and minute.
And you can do it by parsing the date command to lookup what the current date format is required to be.
The first link indicates you might need to edit the code in the second, on Win7, to handle a few extra wrinkles around short date/long date form.
I've reworked sashoalm's version to take care of the suppressed-leading-zero situation:
#Echo OFF
SETLOCAL
If "%Date%A" LSS "A" (Set _NumTok=1-3) Else (Set _NumTok=2-4)
:: Default Delimiter of TAB and Space are used
For /F "TOKENS=2*" %%A In ('REG QUERY "HKCU\Control Panel\International" /v iDate') Do Set _iDate=%%B
For /F "TOKENS=2*" %%A In ('REG QUERY "HKCU\Control Panel\International" /v sDate') Do Set _sDate=%%B
IF %_iDate%==0 For /F "TOKENS=%_NumTok% DELIMS=%_sdate% " %%F In ("%Date%") Do CALL :procdate %%H %%F %%G
IF %_iDate%==1 For /F "TOKENS=%_NumTok% DELIMS=%_sdate% " %%F In ("%Date%") Do CALL :procdate %%H %%G %%F
IF %_iDate%==2 For /F "TOKENS=%_NumTok% DELIMS=%_sdate% " %%F In ("%Date%") Do CALL :procdate %%F %%G %%H
endlocal&SET YYYYMMDD=%YYYYMMDD%
GOTO :eof
::
:: Date elements are supplied in Y,M,D order but may have a leading zero
::
:procdate
:: if single-digit day then 1%3 will be <100 else 2-digit
IF 1%3 LSS 100 (SET YYYYMMDD=0%3) ELSE (SET YYYYMMDD=%3)
:: if single-digit month then 1%2 will be <100 else 2-digit
IF 1%2 LSS 100 (SET YYYYMMDD=0%2%YYYYMMDD%) ELSE (SET YYYYMMDD=%2%YYYYMMDD%)
:: Similarly for the year - I've never seen a single-digit year
IF 1%1 LSS 100 (SET YYYYMMDD=20%YYYYMMDD%) ELSE (SET YYYYMMDD=%1%YYYYMMDD%)
GOTO :eof
returning YYYYMMDD - substring at your will.
Interestingly, inserting after SETLOCAL
IF NOT "%1"=="" set date=%1
will allow any date in the local sequence (without the dayname) to be decoded to YYYYMMDD (but be careful that 19xx dates provided with the yy form will appear as 20xx - easily compensated-for if you find it necessary)
I have an additional suggestion with robocopy:
#echo off &setlocal enabledelayedexpansion
set "day="
for /f "tokens=3,4,8skip=4delims=: " %%i in ('robocopy') do if not defined day (
set "month=%%i"
set "day=0%%j"
set "year=%%k"
)
set /a cnt=0
for %%i in (Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) do (
set /a cnt+=1
if "%%i"=="%month%" set "month=0!cnt!"
)
set "day=%day:~-2%"
set "month=%month:~-2%"
echo.%day%.%month%.%year%
endlocal
Try this: Set_date.cm
#echo off&goto :start
:Set_Date DateEnv [Date] or [/p="Prompt for Date: "] [/r]
echo.
echo.Usage: Set_Date.cmd DateEnv [Date] or [/p="Prompt for Date: "]
echo.Populates date variables labeled: 'DateEnv_???', see below
echo.Accepted date formats:
echo. m-d-y, m/d/y, yyyymmdd, dd-Mon-yy or 7 digit julian date
echo. If "%%date%%" is passed as the 2nd arg it will be interpreted
echo. according to the current regional date setting ie. day dd/mm/yyyy
echo. If /r is passed then the date contained in the DateEnv variable
echo. and/or the [Date] argument will be interpreted in regional format
echo. The /r option should be placed at the end of the list if used
echo. The /r option should only be used if date input is not included
echo. in one of the default listed formats or unexpected consequences...
echo.
echo.DateEnv, if passed alone may be a valid defined date variable or if
echo.undefined then todays date will be used to populate the variables
echo.Two digit years input 'XX' are interpreted as the year '20XX'
echo.Valid dates must be in the year 1601 or greater for the validity check
echo.Returns 0 in errorlevel if the date is valid, else non-zero
echo.
echo.If DateEnv is valid or if [Date] is passed DateEnv_??? will be set to:
echo.DateEnv_mdy will be set to mm-dd-yyyy
echo.DateEnv_ymd will be set to yyyymmdd
echo.DateEnv_y.m.d will be set to yyyy.mm.dd
echo.DateEnv_dte will be set to the current active regional date format
echo.DateEnv_jul will be set to the 7 digit Julian date
echo.DateEnv_dow will be set to day of week, ie. Monday, Tuesday, etc.
echo.DateEnv_vrb will be set to Verbose Date, ie. Saturday, August 20th, 2011
echo.DateEnv_dd will be set to the 2 digit day
echo.DateEnv_mm will be set to the 2 digit month
echo.DateEnv_yyyy will be set to the 4 digit year
echo.DateEnv_month will be set to the month, ie. February or December
echo.DateEnv_mon will be set to the 3 letter month, ie. Jan or Aug
echo.
echo.DateEnv itself will not be changed regardless if its a valid date or not
echo.Also formats yyyymmdd or 7 digit julian date input to desired output
echo.Example: Set_Date today "%%date%%" or Set_Date newyear99 01-Jan-99
echo.
echo.Finally:
echo.If DateEnv is not defined and there is no second argument then %%date%% in
echo.the current regional format will be used to populate the variables
echo.If /p is passed as 2nd argument then quoted 3rd argument will prompt for date
echo.
echo.Examples:
echo. set "AprilsFools=4/1/1"
echo. set_date AprilFools
echo. echo Aprils fools date for 2001 in Julian format is: %%AprilFools_jul%%
echo. echo Aprils fools date in 2001 was on a %AprilFools_dow% ^(Sunday^)
echo. Set_Date birthday /p="Enter your birth date: "
echo. ECHO You were born on a %%birthday_dow%%
echo. set "today="
echo. Set_Date today
echo. echo today is %%today_dte%% or %%today_jul%% in Julian format
echo.
echo.If the '/p' option is used then the _GetString.cmd routine must be in the PATH
echo. or else set/p routine will ask for date with no validity checking
exit /b 1
:start
set "jul="&set "Format="&set "Sep="&set "reg="
if "%~1"=="" exit /b 255
if /i "%~1" equ "/?" goto :Set_Date Syntax
SetLocal EnableDelayedExpansion
echo %*|find /i "/r">nul
if %errorlevel% equ 0 set/a reg=1&if /i "%~1" equ "/r" shift
if defined %~1 (call set jul=%%%~1%%) else (
if "%~2"=="" set "jul=%date%"
)
if not "%~2"=="" (
if /i "%~2" neq "/r" (
set "jul=%~2"&set "args=%~3"
)
) else (if not defined %~1 set/a reg=1)
call :RegDateFmt Format Separator yy mm dd jul
if %errorlevel% neq 0 goto :BadDate
if /i "%~2" equ "%date%" set/a reg=1
if defined reg (
set "jul=!mm!-!dd!-!yy!"
)
if /i "%jul%" equ "/p" (
call :_GetString.cmd "%args%" jul /d
if !errorlevel! gtr 0 goto :BadDate
) else if /i "%jul:~0,1%" gtr "9" (
if defined args set "jul=%jul% %args%"
set "jul=!jul:* =!"
) else if /i "%jul:~3,1%" gtr "9" (
set "Mon=%jul:~3,3%"
call :month_convert Mon
if !errorlevel! gtr 0 goto :BadDate
set "jul=!Mon!-%jul:~0,2%-%jul:~-2%"
)
set mdy=%jul:/=%
set mdy=%mdy:-=%
if /i %mdy% equ %jul% (
call :strlen %mdy%
if /i !errorlevel! equ 7 (
call :date_cvt mdy /j
) else (call :date_cvt jul /j)
) else (call :date_cvt jul /j)
if /i %errorlevel% equ 0 (
set/a mdy=%jul%
set/a dow=%jul% %% 7&call :set_day dow
) else (goto :BadDate)
call :date_cvt mdy /j
set "vrb=%mdy%"
call :format_verbose vrb dow month
set/a ymd=%errorlevel%
set "mon=%month:~0,3%"
set/a dte=%ymd%
call :setRegDate dte Format Separator dow mon
if /i %errorlevel% gtr 0 goto :BadDate
Endlocal&(
call set "%~1_mdy=%mdy%"&call set "%~1_ymd=%ymd%"&call set "%~1_jul=%jul%"
call set "%~1_vrb=%vrb%"&call set "%~1_dow=%dow%"&call set "%~1_dd=%ymd:~-2%"
call set "%~1_mm=%mdy:~0,2%"&call set "%~1_yyyy=%ymd:~0,4%"
call set "%~1_mon=%mon%"&call set "%~1_yy=%ymd:~2,2%"&call set "%~1_dte=%dte%"
call set "%~1_y.m.d=%ymd:~0,4%.%mdy:~0,2%.%ymd:~-2%"&call set "%~1_month=%month%"
exit /b 0
)
:BadDate
Endlocal&(
call set "%~1_mdy="&call set "%~1_ymd="&call set "%~1_dte="&call set "%~1_jul="
call set "%~1_vrb="&call set "%~1_dow="&call set "%~1_vrb="&call set "%~1_y.m.d="
call set "%~1_month="
)&exit /b %errorlevel%
::**********************************::
::*******|| SUBROUTINES ||*******::
::**********************************::
:set_day
SetLocal&call set/a tkn=%%%~1%%+1
for /f "tokens=%tkn%" %%a in ("Monday Tuesday Wednesday Thursday Friday Saturday Sunday") do (
set "dayofwk=%%a"
)
EndLocal&call set %~1=%dayofwk%&exit /b 1
:Date_Cvt DateEnv [/Julian] Date_env is converted
if "%~1"=="" exit /b 1
SetLocal&call set "mdy=%%%~1%%"
set ech=&set "arg="
if not "%~2"=="" (set arg=%~2&set arg=!arg:~0,2!)
xcopy /d:%mdy% /h /l "%~f0" "%~f0\">nul 2>&1
if /i %errorlevel% equ 0 (
for /f "tokens=1-3 delims=/- " %%a in ("%mdy%") do (
set m=%%a&set d=%%b&set "y=%%c"
if /i 1!m! lss 20 set "m=0!m!"
if /i 1!d! lss 20 set "d=0!d!"
if /i 1!y! lss 20 set "y=0!y!"
if /i !y! lss 80 (set y=20!y!) else (if !y! lss 100 set y=19!y!)
set "mdy=!m!-!d!-!y!"
)
) else (
set /a rc=1
for /f "tokens=1-3 delims=0123456789" %%a in ("%mdy%") do set "rc=%%a"
if /i !rc! neq 1 set /a err=2&goto :end
call :strlen %mdy%
if /i !errorlevel! gtr 8 set /a err=3&goto :end
)
set "mdy=%mdy:/=-%"
set "ymd=%mdy:-=%"
if %ymd%==%mdy% (
call :strlen %ymd%
set /a err=!errorlevel!
if /i !err! equ 7 if /i "%arg%" equ "/j" (
call :gdate %ymd%
set /a ymd=!errorlevel!
set /a err=8&set "arg="
)
if /i !err! neq 8 goto :end
set mdy=!ymd:~4,2!-!ymd:~6,2!-!ymd:~0,4!&set "ech=!mdy!"
) else (
set ymd=%ymd:~4,4%%ymd:~0,4%&set "ech=!ymd!"
)
xcopy /d:%mdy% /h /l "%~f0" "%~f0\">nul 2>&1
set /a err=%errorlevel%
if /i %err% neq 0 (set ech=)
if /i %err% equ 0 if /i "%arg%" equ "/j" (
call :jdate %ymd%
set /a ech=!errorlevel!
)
:end
EndLocal&call set "%~1=%ech%"&exit /b %err%
:Strlen Returns length of string in errorlevel
setlocal&set "#=%*"
if not defined # exit /b 0
set/a len=0
:loop
set/a len+=1
set "#=!#:~1!"&if not defined # endlocal&exit/b %len%
goto :loop
:jdate
SetLocal
set "yyyymmdd=%~1"
set "yyyy=%yyyymmdd:~0,4%"
set "mm=%yyyymmdd:~4,2%"
set "dd=%yyyymmdd:~6,2%"
if %mm:~0,1% equ 0 set "mm=%mm:~1%"
if %dd:~0,1% equ 0 set "dd=%dd:~1%"
set /a Month1=(%mm%-14)/12
set /a Year1=%yyyy%+4800
set /a JDate=1461*(%Year1%+%Month1%)/4+367*(%mm%-2-12*%Month1%)^
/12-(3*((%Year1%+%Month1%+100)/100))/4+%dd%-32075
EndLocal&exit /b %JDate%
:gdate
SetLocal
set /a p = %1 + 68569
set /a q = 4 * %p% / 146097
set /a r = %p% - ( 146097 * %q% +3 ) / 4
set /a s = 4000 * ( %r% + 1 ) / 1461001
set /a t = %r% - 1461 * %s% / 4 + 31
set /a u = 80 * %t% / 2447
set /a v = %u% / 11
set /a GYear = 100 * ( %q% - 49 ) + %s% + %v%
set /a GMonth = %u% + 2 - 12 * %v%
set /a GDay = %t% - 2447 * %u% / 80
if /i 1%GMonth% lss 20 set "GMonth=0%GMonth%"
if /i 1%GDay% lss 20 set "GDay=0%GDay%"
set "GDate=%GYear%%GMonth%%GDay%"
EndLocal&exit /b %GDate%
:Format_Verbose M/D/Y dayofweek to verbose date
SetLocal&call set "dte=%%%~1%%"
set "dow=%%%~2%%"
set "st="
set "day=%dte:~3,2%"
set "mon=%dte:~0,2%"
set "year=%dte:~6,4%"
set "ymd=%year%%mon%%day%"
set "dy=%day:~1%"
if %day:~0,1% equ 0 set "day=%day:~1%"
if %mon:~0,1% equ 0 set "mon=%mon:~1%"
set months=January February March April May June^
July August September October November December
for /f "tokens=%mon%" %%a in ("%months%") do set "month=%%a"
if /i %dy% equ 0 set "st=th"
if /i %dy% gtr 3 set "st=th"
if /i %day% geq 11 if /i %day% leq 13 set "st=th"
if defined st goto :end
set/a rst=%day% %% 10
for /f "tokens=%rst%" %%s in ("st nd rd") do set "st=%%s"
:end
set "dow=%dow%, %month% %day%%st%, %year%"
EndLocal&call set %~1=%dow%&call set %~3=%month%&exit /b %ymd%
:_GetString.cmd
set p0=%0&set "p0=!p0:~1!"
if not exist _GetString.cmd (
call :checkpath %p0%
if !errorlevel! neq 0 (
set/p %~2="%~1"
exit/b 0
)
)
call _GetString.cmd "%~1" %~2 %~3
exit/b %errorlevel%
:checkpath
if exist "%~$PATH:1" exit/b 0
exit/b 1
:RegDateFmt Format Separator y m d dte
if "%~2"=="" exit/b 1
setlocal EnabledelayedExpansion
set "Day="&set "Mon="&set "dte="
if not "%~6"=="" set "dte=!%~6!"
if not defined dte set "dte=%date%"
for /f "tokens=2 delims=:" %%A in ('date^<nul') do set Format=%%A&goto :next
:next
set "Format=%Format: =%"
for %%A in (/ - . ,) do (
echo %Format%|find "%%A">nul&if !errorlevel! equ 0 set "Separator=%%A"
)
if /i %Format:~0,1% gtr 9 set "Day=Day "
for /f "skip=1 tokens=2-4 delims=(-)" %%a in ('date^<nul') do (
set "Format=%Day%%%a%Separator%%%b%Separator%%%c"
for /f "tokens=1-3 delims=.-/ " %%d in ("%dte:* =%") do (
set %%a=%%d&set %%b=%%e&set "%%c=%%f"
echo !yy:~3!|find "ECHO">nul
if /i "!errorlevel!" neq "0" set "Format=!Format:yy=yyyy!"
if /i "!mm:~0,1!" gtr "9" (
set "Format=!Format:mm=Mon!"
call :month_convert mm
if /i "!errorlevel!" neq "0" endlocal&exit/b 1
)
)
)
endlocal&(
call set "%~1=%Format%"
call set "%~2=%Separator%"
if not "%~3"=="" call set "%~3=%yy%"
if not "%~4"=="" call set "%~4=%mm%"
if not "%~5"=="" call set "%~5=%dd%"
)&exit/b 0
:month_convert
set "months=Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
call set "month=%%%~1%%"
set/a mnum=0
for %%m in (%months%) do set/a mnum+=1&if /i %month% equ %%m call set "%~1=!mnum!"&exit /b 0
exit/b 1
:setRegDate dte format sep dow mon
setlocal EnableDelayedExpansion
if /i "%~5"=="" exit/b 1
set mon=!%~5!&set dow=!%~4!&set "dow=!dow:~0,3! "
set sep=!%~3!&set "format=!%~2!"&set "dte=!%~1!"
set yyyy=%dte:~0,4%&set yy=%dte:~2,2%&set mm=%dte:~4,2%&set "dd=%dte:~-2%"
set "toks=2-4"
echo %format%|find " ">nul
if %errorlevel% equ 1 set "dow="& set "toks=1-3"
for /f "tokens=%toks% delims=%sep% " %%a in ("%format%") do (
set "dte=%dow%!%%a!%sep%!%%b!%sep%!%%c!"
)
endlocal&call set "%~1=%dte%"&exit/b 0
I found this in http://forums.techguy.org/dos-other/837046-solved-date-format-bat-file.html
I've reworked it a bit to actually split it in 3 environment variables.
The downside is it needs to query the registry, probably to find out the order day, month and year.
#Echo Off
Set _Date=%date%
If "%_Date%A" LSS "A" (Set _NumTok=1-3) Else (Set _NumTok=2-4)
:: Default Delimiter of TAB and Space are used
For /F "TOKENS=2*" %%A In ('REG QUERY "HKCU\Control Panel\International" /v iDate') Do Set _iDate=%%B
For /F "TOKENS=2*" %%A In ('REG QUERY "HKCU\Control Panel\International" /v sDate') Do Set _sDate=%%B
IF %_iDate%==0 For /F "TOKENS=%_NumTok% DELIMS=%_sDate% " %%B In ("%_Date%") Do Set _fdate=%%D%%B%%C
IF %_iDate%==1 For /F "TOKENS=%_NumTok% DELIMS=%_sDate% " %%B In ("%_Date%") Do Set _fdate=%%D%%C%%B
IF %_iDate%==2 For /F "TOKENS=%_NumTok% DELIMS=%_sDate% " %%B In ("%_Date%") Do Set _fdate=%%B%%C%%D
Set _Month=%_fdate:~4,2%
Set _Day=%_fdate:~6,2%
Set _Year=%_fdate:~0,4%
Echo _Year=%_Year%
Echo _Month=%_Month%
Echo _Day=%_Day%
REG QUERY is not sufficient, if sShortDate was set to something like dd yy. Use REG ADD:
#echo off &setlocal
for /f "tokens=2*" %%a in ('reg query "HKCU\Control Panel\International" /v sShortDate^|find "REG_SZ"') do set "ssShortDate=%%b"
reg add "HKCU\Control Panel\International" /f /v sShortDate /d "dd MM yyyy" >nul
set "cdate=%date%"
reg add "HKCU\Control Panel\International" /f /v sShortDate /d "%ssShortDate%" >nul
for /f "tokens=1-3" %%i in ("%cdate%") do set "day=0%%i"&set "month=0%%j"&set "year=%%k"
set "day=%day:~-2%"
set "month=%month:~-2%"
echo.%day%.%month%.%year%
endlocal
This function should work on all regions.
Remarks:
Returns month in text format for MMM regions
#echo off
call :GetDateIntl year month day
echo/Using GetDateIntl you get: %year%-%month%-%day%
goto:eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:GetDateIntl yy mm dd [/A]
:: Returns the current date on any machine with regional-independent settings
:: Arguments:
:: yy = variable name for the year output
:: mm = variable name for the month output
:: dd = variable name for the day output
:: /A = OPTIONAL, removes leading 0 on days/months smaller than 10 (example: 01 becomes 1)
:: Remarks:
:: Will return month in text format in regions with MMM month
::
SETLOCAL ENABLEEXTENSIONS
if "%date%A" LSS "A" (set toks=1-3) else (set toks=2-4)
for /f "tokens=2-4 delims=(-)" %%a in ('echo:^|date') do (
for /f "tokens=%toks% delims=.-/ " %%i in ('date/t') do (
set '%%a'=%%i
set '%%b'=%%j
set '%%c'=%%k
)
)
if /I "%'yy'%"=="" set "'yy'=%'aa'%"
if /I "%'yy'%"=="" ( set "'yy'=%'jj'%" & set "'dd'=%'tt'%" )
if %'yy'% LSS 100 set 'yy'=20%'yy'%
endlocal&set %1=%'yy'%&set %4 %2=%'mm'%&set %4 %3=%'dd'%&goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Below there is a pure Batch solution that just use DATE command and %DATE% variable, so it works on any Windows version. To make this program really universal, just add the name of the day and month parts shown by second line of DATE command in other languages, enclosed in slashes. For example, let's suppose that in German the day part is shown as TT, so you just need to modify this value: set DayNames=/dd/tt/ in order to also use this program in German language Windows (besides all the languages that use DD for the day part).
#echo off
setlocal EnableDelayedExpansion
rem GetStdDate.bat: Get date in standard format independently of Regional Settings
rem Antonio Perez Ayala
rem Set Day and Month names shown by second line of DATE command, enclosed in slashes (add any missing language):
set DayNames=/dd/
set MonthNames=/mm/
rem Get date NAMES from second line of date COMMAND, enclosed in parentheses
for /F "skip=1 tokens=2 delims=()" %%n in ('date ^< NUL') do (
rem Separate and store date names
for /F "tokens=1-3 delims=/-.:" %%a in ("%%n") do (
set one=%%a& set two=%%b& set three=%%c
rem Get date VALUES from %date% VARIABLE
for /F "tokens=1-3 delims=/-.:" %%x in ("%date%") do (
rem Assign date values to date names
set %%a=%%x& set %%b=%%y& set %%c=%%z
)
)
)
rem Identify locale date format and assemble StdDate=YYYY/MM/DD
if "!DayNames:/%one%/=!" neq "%DayNames%" (
rem Locale format is DD/MM/YYYY
set StdDate=!%three%!/!%two%!/!%one%!
) else if "!MonthNames:/%one%/=!" neq "%MonthNames%" (
rem Locale format is MM/DD/YYYY
set StdDate=!%three%!/!%one%!/!%two%!
) else (
rem Locale format is YYYY/MM/DD
set StdDate=!%one%!/!%two%!/!%three%!
)
echo Standard date: %StdDate%
Read a locale independent YYYY-MM-DDThh:mm:ss value.
WMIC gives 20220812142505.576000+180 value and using a simple ~substring we can construct a datetime format.
#set dt=
#CALL :GETDATETIME
#echo Step1 %dt%
#timeout /T 4
#CALL :GETDATETIME
#echo Step2 %dt%
#GOTO :END
:GETDATETIME
#for /f "tokens=2 delims==" %%X in ('wmic os get localdatetime /value') do #set dt=%%X
#set dt=%dt:~0,4%-%dt:~4,2%-%dt:~6,2%T%dt:~8,2%:%dt:~10,2%:%dt:~12,2%
#GOTO :EOF
:END
#pause

How do I get current date/time on the Windows command line in a suitable format for usage in a file/folder name?

Update: Now that it's 2016 I'd use PowerShell for this unless there's a really compelling backwards-compatible reason for it, particularly because of the regional settings issue with using date. See #npocmaka's https://stackoverflow.com/a/19799236/8479
What's a Windows command line statement(s) I can use to get the current datetime in a format that I can put into a filename?
I want to have a .bat file that zips up a directory into an archive with the current date and time as part of the name, for example, Code_2008-10-14_2257.zip. Is there any easy way I can do this, independent of the regional settings of the machine?
I don't really mind about the date format, ideally it'd be yyyy-mm-dd, but anything simple is fine.
So far I've got this, which on my machine gives me Tue_10_14_2008_230050_91:
rem Get the datetime in a format that can go in a filename.
set _my_datetime=%date%_%time%
set _my_datetime=%_my_datetime: =_%
set _my_datetime=%_my_datetime::=%
set _my_datetime=%_my_datetime:/=_%
set _my_datetime=%_my_datetime:.=_%
rem Now use the timestamp by in a new ZIP file name.
"d:\Program Files\7-Zip\7z.exe" a -r Code_%_my_datetime%.zip Code
I can live with this, but it seems a bit clunky. Ideally it'd be briefer and have the format mentioned earlier.
I'm using Windows Server 2003 and Windows XP Professional. I don't want to install additional utilities to achieve this (although I realise there are some that will do nice date formatting).
See Windows Batch File (.bat) to get current date in MMDDYYYY format:
#echo off
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 /t') do (set mytime=%%a%%b)
echo %mydate%_%mytime%
If you prefer the time in 24 hour/military format, you can replace the second FOR line with this:
For /f "tokens=1-2 delims=/:" %%a in ("%TIME%") do (set mytime=%%a%%b)
C:> .\date.bat
2008-10-14_0642
If you want the date independently of the region day/month order, you can use "WMIC os GET LocalDateTime" as a source, since it's in ISO order:
#echo off
for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j
set ldt=%ldt:~0,4%-%ldt:~4,2%-%ldt:~6,2% %ldt:~8,2%:%ldt:~10,2%:%ldt:~12,6%
echo Local date is [%ldt%]
C:>test.cmd
Local date is [2012-06-19 10:23:47.048]
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 temp 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
More information about get-date function.
ROBOCOPY - it's not native command for Windows XP and Windows Server 2003, but it can be downloaded from microsoft site. But 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 form 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());
VSCRIPT/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, v3 (only for Windows 7 and above)). It is installed by default on everything from Windows 7/Windows Server 2008 and above:
C:\> powershell get-date -format "{dd-MMM-yyyy HH:mm}"
To use it from a batch file:
for /f "delims=" %%# in ('powershell get-date -format "{dd-MMM-yyyy HH:mm}"') do #set _date=%%#
Self-compiled jscript.net/batch (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 and also creates a temporary file and is based on the time stamps that logman puts on its log files. It will work on everything from Windows XP and above. It probably will be never used by anybody - including me - but 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
One more way with WMIC which also gives week of the year and the day of the week, but not the milliseconds (for milliseconds check foxidrive's answer):
for /f %%# in ('wMIC Path Win32_LocalTime Get /Format:value') do #for /f %%# in ("%%#") do #set %%#
echo %day%
echo %DayOfWeek%
echo %hour%
echo %minute%
echo %month%
echo %quarter%
echo %second%
echo %weekinmonth%
echo %year%
Using TYPEPERF with some efforts to be fast and compatible with different language settings and as fast as possible:
#echo off
setlocal
:: Check if Windows is Windows XP and use Windows XP valid counter for UDP performance
::if defined USERDOMAIN_roamingprofile (set "v=v4") else (set "v=")
for /f "tokens=4 delims=. " %%# in ('ver') do if %%# GTR 5 (set "v=v4") else ("v=")
set "mon="
for /f "skip=2 delims=," %%# in ('typeperf "\UDP%v%\*" -si 0 -sc 1') do (
if not defined mon (
for /f "tokens=1-7 delims=.:/ " %%a in (%%#) do (
set mon=%%a
set date=%%b
set year=%%c
set hour=%%d
set minute=%%e
set sec=%%f
set ms=%%g
)
)
)
echo %year%.%mon%.%date%
echo %hour%:%minute%:%sec%.%ms%
endlocal
MSHTA allows calling JavaScript methods similar to the JScript method demonstrated in #3 above. Bear in mind that JavaScript's Date object properties involving month values are numbered from 0 to 11, not 1 to 12. So a value of 9 means October.
<!-- : Batch portion
#echo off
setlocal
for /f "delims=" %%I in ('mshta "%~f0"') do set "now.%%~I"
rem Display all variables beginning with "now."
set now.
goto :EOF
end batch / begin HTA -->
<script>
resizeTo(0,0)
var fso = new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1),
now = new Date(),
props=['getDate','getDay','getFullYear','getHours','getMilliseconds','getMinutes',
'getMonth','getSeconds','getTime','getTimezoneOffset','getUTCDate','getUTCDay',
'getUTCFullYear','getUTCHours','getUTCMilliseconds','getUTCMinutes','getUTCMonth',
'getUTCSeconds','getYear','toDateString','toGMTString','toLocaleDateString',
'toLocaleTimeString','toString','toTimeString','toUTCString','valueOf'],
output = [];
for (var i in props) {output.push(props[i] + '()=' + now[props[i]]())}
close(fso.Write(output.join('\n')));
</script>
Regionally independent date time parsing
The output format of %DATE% and of the dir command is regionally dependent and thus neither robust nor smart. date.exe (part of UnxUtils) delivers any date and time information in any thinkable format. You may also extract the date/time information from any file with date.exe.
Examples: (in a cmd-script use %% instead of %)
date.exe +"%Y-%m-%d"
2009-12-22
date.exe +"%T"
18:55:03
date.exe +"%Y%m%d %H%M%S: Any text"
20091222 185503: Any text
date.exe +"Text: %y/%m/%d-any text-%H.%M"
Text: 09/12/22-any text-18.55
Command: date.exe +"%m-%d """%H %M %S """"
07-22 "18:55:03"`
The date/time information from a reference file:
date.exe -r c:\file.txt +"The timestamp of file.txt is: %Y-%m-%d %H:%M:%S"
Using it in a CMD script to get year, month, day, time information:
for /f "tokens=1,2,3,4,5,6* delims=," %%i in ('C:\Tools\etc\date.exe +"%%y,%%m,%%d,%%H,%%M,%%S"') do set yy=%%i& set mo=%%j& set dd=%%k& set hh=%%l& set mm=%%m& set ss=%%n
Using it in a CMD script to get a timestamp in any required format:
for /f "tokens=*" %%i in ('C:\Tools\etc\date.exe +"%%y-%%m-%%d %%H:%%M:%%S"') do set timestamp=%%i
Extracting the date/time information from any reference file.
for /f "tokens=1,2,3,4,5,6* delims=," %%i in ('C:\Tools\etc\date.exe -r file.txt +"%%y,%%m,%%d,%%H,%%M,%%S"') do set yy=%%i& set mo=%%j& set dd=%%k& set hh=%%l& set mm=%%m& set ss=%%n
Adding to a file its date/time information:
for /f "tokens=*" %%i in ('C:\Tools\etc\date.exe -r file.txt +"%%y-%%m-%%d.%%H%%M%%S"') do ren file.txt file.%%i.txt
date.exe is part of the free GNU tools which need no installation.
NOTE: Copying date.exe into any directory which is in the search path may cause other scripts to fail that use the Windows built-in date command.
Here's a variant from alt.msdos.batch.nt that works local-independently.
Put this in a text file, e.g. getDate.cmd
-----------8<------8<------------ snip -- snip ----------8<-------------
:: Works on any NT/2k machine independent of regional date settings
#ECHO off
SETLOCAL ENABLEEXTENSIONS
if "%date%A" LSS "A" (set toks=1-3) else (set toks=2-4)
for /f "tokens=2-4 delims=(-)" %%a in ('echo:^|date') do (
for /f "tokens=%toks% delims=.-/ " %%i in ('date/t') do (
set '%%a'=%%i
set '%%b'=%%j
set '%%c'=%%k))
if %'yy'% LSS 100 set 'yy'=20%'yy'%
set Today=%'yy'%-%'mm'%-%'dd'%
ENDLOCAL & SET v_year=%'yy'%& SET v_month=%'mm'%& SET v_day=%'dd'%
ECHO Today is Year: [%V_Year%] Month: [%V_Month%] Day: [%V_Day%]
:EOF
-----------8<------8<------------ snip -- snip ----------8<-------------
To get the code to work sans error msg's to stderr, I had to add the single quotes arount the variable assignments for %%a, %%b and %%c. My locale (PT) was causing errors at one stage in the looping/parsing where stuff like "set =20" was getting executed. The quotes yield a token (albeit empty) for the left-hand side of the assignment statement.
The downside is the messy locale variable names: 'yy', 'mm' and 'dd'. But hey, who cares!
I use this (again not region independent (UK))
set bklog=%date:~6,4%-%date:~3,2%-%date:~0,2%_%time:~0,2%%time:~3,2%
The first four lines of this code will give you reliable YY DD MM YYYY HH Min Sec variables in Windows XP Professional and higher.
#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
Unfortunately this is not immune to regional settings, but it does what you want.
set hour=%time:~0,2%
if "%time:~0,1%"==" " set hour=0%time:~1,1%
set _my_datetime=%date:~10,4%-%date:~4,2%-%date:~7,2%_%hour%%time:~3,2%
Amazing the stuff you can find on Wikipedia.
Please use the following script to get the current day in the command line:
echo %Date:~0,3%day
"d:\Program Files\7-Zip\7z.exe" a -r code_%date:~10,4%-%date:~4,2%-%date:~7,2%.zip
Another way (credit):
#For /F "tokens=2,3,4 delims=/ " %%A in ('Date /t') do #(
Set Month=%%A
Set Day=%%B
Set Year=%%C
)
#echo DAY = %Day%
#echo Month = %Month%
#echo Year = %Year%
Note that both my answers here are still reliant on the order of the day and month as determined by regional settings - not sure how to work around that.
This isn't really briefer but might be a more flexible way (credit):
FOR /F "TOKENS=1* DELIMS= " %%A IN ('DATE/T') DO SET CDATE=%%B
FOR /F "TOKENS=1,2 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET mm=%%B
FOR /F "TOKENS=1,2 DELIMS=/ eol=/" %%A IN ('echo %CDATE%') DO SET dd=%%B
FOR /F "TOKENS=2,3 DELIMS=/ " %%A IN ('echo %CDATE%') DO SET yyyy=%%B
SET date=%mm%%dd%%yyyy%
Short answer :
:: Start - Run , type:
cmd /c "powershell get-date -format ^"{yyyy-MM-dd HH:mm:ss}^"|clip"
:: click into target media, Ctrl + V to paste the result
Long answer
#echo off
:: START USAGE ==================================================================
::SET THE NICETIME
:: SET NICETIME=BOO
:: CALL GetNiceTime.cmd
:: ECHO NICETIME IS %NICETIME%
:: echo nice time is %NICETIME%
:: END USAGE ==================================================================
echo set hhmmsss
:: this is Regional settings dependant so tweak this according your current settings
for /f "tokens=1-3 delims=:" %%a in ('echo %time%') do set hhmmsss=%%a%%b%%c
::DEBUG ECHO hhmmsss IS %hhmmsss%
::DEBUG PAUSE
echo %yyyymmdd%
:: this is Regional settings dependant so tweak this according your current settings
for /f "tokens=1-3 delims=." %%D in ('echo %DATE%') do set yyyymmdd=%%F%%E%%D
::DEBUG ECHO yyyymmdd IS %yyyymmdd%
::DEBUG PAUSE
set NICETIME=%yyyymmdd%_%hhmmsss%
::DEBUG echo THE NICETIME IS %NICETIME%
::DEBUG PAUSE
Here's a way to get date time in a single line:
for /f "tokens=2,3,4,5,6 usebackq delims=:/ " %a in ('%date% %time%') do echo %c-%a-%b %d%e
In the US this will output "yyyy-mm-dd hhmm". Different regional settings will result in different %date% outputs, but you can modify the token order.
If you want a different format, modify the echo statement by rearranging the tokens or using different (or no) separators.
Just use this line:
PowerShell -Command "get-date"
Matthew Johnson's one-liner solution to get the one-liner date and time is eloquent and useful.
It does however need a simple modification to work from within a batch file:
for /f "tokens=2,3,4,5,6 usebackq delims=:/ " %%a in ('%date% %time%') do echo %%c-%%a-%%b %%d%%e
And here is a similar batch-file for the time portion.
:: http://stackoverflow.com/questions/203090/how-to-get-current-datetime-on-windows-command-line-in-a-suitable-format-for-usi
:: Works on any NT/2k machine independent of regional time settings
::
:: Gets the time in ISO 8601 24-hour format
::
:: Note that %time% gets you fractions of seconds, and time /t doesn't, but gets you AM/PM if your locale supports that.
:: Since ISO 8601 does not care about AM/PM, we use %time%
::
#ECHO off
SETLOCAL ENABLEEXTENSIONS
for /f "tokens=1-4 delims=:,.-/ " %%i in ('echo %time%') do (
set 'hh'=%%i
set 'mm'=%%j
set 'ss'=%%k
set 'ff'=%%l)
ENDLOCAL & SET v_Hour=%'hh'%& SET v_Minute=%'mm'%& SET v_Second=%'ss'%& SET v_Fraction=%'ff'%
ECHO Now is Hour: [%V_Hour%] Minute: [%V_Minute%] Second: [%v_Second%] Fraction: [%v_Fraction%]
set timestring=%V_Hour%%V_Minute%%v_Second%.%v_Fraction%
echo %timestring%
:EOF
--jeroen
I changed the answer with the batch file from vMax so it works with the Dutch language too.
The Dutch - persistent as we are - have a few changes in the %date%, date/t, and date that break the original batch-file.
It would be nice if some people can check this against other Windows locales as well, and report back the results.
If the batch-file fails at your location, then please include the output of these two statements on the command prompt:
echo:^|date
date/t
This is a sample of the output you should get from the batch-file:
C:\temp>set-date-cmd.bat
Today is Year: [2011] Month: [01] Day: [03]
20110103
Here is the revised code with comments on why:
:: https://stackoverflow.com/questions/203090/how-to-get-current-datetime-on-windows-command-line-in-a-suitable-format-for-usi
:: Works on any NT/2k machine independent of regional date settings
::
:: 20110103 - adapted by jeroen#pluimers.com for Dutch locale
:: Dutch will get jj as year from echo:^|date, so the '%%c' trick does not work as it will fill 'jj', but we want 'yy'
:: luckily, all countries seem to have year at the end: http://en.wikipedia.org/wiki/Calendar_date
:: set '%%c'=%%k
:: set 'yy'=%%k
::
:: In addition, date will display the current date before the input prompt using dashes
:: in Dutch, but using slashes in English, so there will be two occurances of the outer loop in Dutch
:: and one occurence in English.
:: This skips the first iteration:
:: if "%%a" GEQ "A"
::
:: echo:^|date
:: Huidige datum: ma 03-01-2011
:: Voer de nieuwe datum in: (dd-mm-jj)
:: The current date is: Mon 01/03/2011
:: Enter the new date: (mm-dd-yy)
::
:: date/t
:: ma 03-01-2011
:: Mon 01/03/2011
::
:: The assumption in this batch-file is that echo:^|date will return the date format
:: using either mm and dd or dd and mm in the first two valid tokens on the second line, and the year as the last token.
::
:: The outer loop will get the right tokens, the inner loop assigns the variables depending on the tokens.
:: That will resolve the order of the tokens.
::
#ECHO off
set v_day=
set v_month=
set v_year=
SETLOCAL ENABLEEXTENSIONS
if "%date%A" LSS "A" (set toks=1-3) else (set toks=2-4)
::DEBUG echo toks=%toks%
for /f "tokens=2-4 delims=(-)" %%a in ('echo:^|date') do (
::DEBUG echo first token=%%a
if "%%a" GEQ "A" (
for /f "tokens=%toks% delims=.-/ " %%i in ('date/t') do (
set '%%a'=%%i
set '%%b'=%%j
set 'yy'=%%k
)
)
)
if %'yy'% LSS 100 set 'yy'=20%'yy'%
set Today=%'yy'%-%'mm'%-%'dd'%
ENDLOCAL & SET v_year=%'yy'%& SET v_month=%'mm'%& SET v_day=%'dd'%
ECHO Today is Year: [%V_Year%] Month: [%V_Month%] Day: [%V_Day%]
set datestring=%V_Year%%V_Month%%V_Day%
echo %datestring%
:EOF
--jeroen
This is what I've used:
::Date Variables - replace characters that are not legal as part of filesystem file names (to produce name like "backup_04.15.08.7z")
SET DT=%date%
SET DT=%DT:/=.%
SET DT=%DT:-=.%
If you want further ideas for automating backups to 7-Zip archives, I have a free/open project you can use or review for ideas: http://wittman.org/ziparcy/
A function that is based on wmic:
:Now -- Gets the current date and time into separate variables
:: %~1: [out] Year
:: %~2: [out] Month
:: %~3: [out] Day
:: %~4: [out] Hour
:: %~5: [out] Minute
:: %~6: [out] Second
setlocal
for /f %%t in ('wmic os get LocalDateTime ^| findstr /b [0-9]') do set T=%%t
endlocal & (
if "%~1" neq "" set %~1=%T:~0,4%
if "%~2" neq "" set %~2=%T:~4,2%
if "%~3" neq "" set %~3=%T:~6,2%
if "%~4" neq "" set %~4=%T:~8,2%
if "%~5" neq "" set %~5=%T:~10,2%
if "%~6" neq "" set %~6=%T:~12,2%
)
goto:eof
Upside: Region independent. Downside: Only system administrators can run wmic.exe.
Usage:
call:Now Y M D H N S
echo %Y%-%M%-%D% %H%:%N%:%S%
This echos a string like this:
2014-01-22 12:51:53
Note that function parameters are out-Parameters - that is, you must supply variable names instead of values.
All parameters are optional, so call:Now Y M is a valid call if you only want to get year and month.
I had a similar problem. I have an automatic daily download from an FTP server of an encrypted file. I wanted to decrypt the file using gpg, rename the file to the current date (YYYYMMDD format) and drop the decrypted file into a folder for the correct department.
I went through several suggestions for renaming the file according to date and was having no luck until I stumbled upon this simple solution.
for /f "tokens=1-5 delims=/ " %%d in ("%date%") do rename "decrypted.txt" %%g-%%e-%%f.txt
It worked perfectly (i.e., the filename comes out as "2011-06-14.txt").
(Source)
http://sourceforge.net/projects/unxutils/files/
Look inside the ZIP file for something called "Date.exe" and rename it "DateFormat.exe" (to avoid conflicts).
Put it in your Windows system32 folder.
It has a lot of "date output" options.
For help, use DateFormat.exe --h
I'm not sure how you would put its output into an environment variable... using SET.
Combine Powershell into a batch file and use the meta variables to assign each:
#echo off
for /f "tokens=1-6 delims=-" %%a in ('PowerShell -Command "& {Get-Date -format "yyyy-MM-dd-HH-mm-ss"}"') do (
echo year: %%a
echo month: %%b
echo day: %%c
echo hour: %%d
echo minute: %%e
echo second: %%f
)
You can also change the the format if you prefer name of the month MMM or MMMM and 12 hour to 24 hour formats hh or HH
Regional independent solution generating the ISO date format:
rem save the existing format definition
for /f "skip=2 tokens=3" %%a in ('reg query "HKCU\Control Panel\International" /v sShortDate') do set FORMAT=%%a
rem set ISO specific format definition
reg add "HKCU\Control Panel\International" /v sShortDate /t REG_SZ /f /d yyyy-MM-dd 1>nul:
rem query the date in the ISO specific format
set ISODATE=%DATE%
rem restore previous format definition
reg add "HKCU\Control Panel\International" /v sShortDate /t REG_SZ /f /d %FORMAT% 1>nul:
What could still be optimized:
Other processes might get confused if using the date format in the short period while it is modified. So parsing the output according to the existing format string could be 'safer' - but will be more complicated
:: GetDate.cmd -> Uses WMIC.exe to get current date and time in ISO 8601 format
:: - Sets environment variables %_isotime% and %_now% to current time
:: - On failure, clears these environment variables
:: Inspired on -> https://ss64.com/nt/syntax-getdate.html
:: - (cX) 2017 adolfo.dimare#gmail.com
:: - http://stackoverflow.com/questions/203090
#echo off
set _isotime=
set _now=
:: Check that WMIC.exe is available
WMIC.exe Alias /? >NUL 2>&1 || goto _WMIC_MISSING_
if not (%1)==() goto _help
SetLocal EnableDelayedExpansion
:: Use WMIC.exe to retrieve date and time
FOR /F "skip=1 tokens=1-6" %%G IN ('WMIC.exe Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
IF "%%~L"=="" goto _WMIC_done_
set _yyyy=%%L
set _mm=00%%J
set _dd=00%%G
set _hour=00%%H
set _minute=00%%I
set _second=00%%K
)
:_WMIC_done_
:: 1 2 3 4 5 6
:: %%G %%H %%I %%J %%K %%L
:: Day Hour Minute Month Second Year
:: 27 9 35 4 38 2017
:: Remove excess leading zeroes
set _mm=%_mm:~-2%
set _dd=%_dd:~-2%
set _hour=%_hour:~-2%
set _minute=%_minute:~-2%
set _second=%_second:~-2%
:: Syntax -> %variable:~num_chars_to_skip,num_chars_to_keep%
:: Set date/time in ISO 8601 format:
Set _isotime=%_yyyy%-%_mm%-%_dd%T%_hour%:%_minute%:%_second%
:: -> http://google.com/search?num=100&q=ISO+8601+format
if 1%_hour% LSS 112 set _now=%_isotime:~0,10% %_hour%:%_minute%:%_second%am
if 1%_hour% LSS 112 goto _skip_12_
set /a _hour=1%_hour%-12
set _hour=%_hour:~-2%
set _now=%_isotime:~0,10% %_hour%:%_minute%:%_second%pm
:: -> https://ss64.com/nt/if.html
:: -> http://google.com/search?num=100&q=SetLocal+EndLocal+Windows
:: 'if () else ()' will NOT set %_now% correctly !?
:_skip_12_
EndLocal & set _isotime=%_isotime% & set _now=%_now%
goto _out
:_WMIC_MISSING_
echo.
echo WMIC.exe command not available
echo - WMIC.exe needs Administrator privileges to run in Windows
echo - Usually the path to WMIC.exe is "%windir%\System32\wbem\WMIC.exe"
:_help
echo.
echo GetDate.cmd: Uses WMIC.exe to get current date and time in ISO 8601 format
echo.
echo %%_now%% environment variable set to current date and time
echo %%_isotime%% environment variable to current time in ISO format
echo set _today=%%_isotime:~0,10%%
echo.
:_out
:: EOF: GetDate.cmd
I used date.exe, and renamed it to date_unxutils.exe to avoid conflicts.
Put it inside bin folder next to the batch script.
Code
:: Add binaries to temp path
IF EXIST bin SET PATH=%PATH%;bin
:: Create UTC Timestamp string in a custom format
:: Example: 20210128172058
set timestamp_command='date_unxutils.exe -u +"%%Y%%m%%d%%H%%M%%S"'
FOR /F %%i IN (%timestamp_command%) DO set timestamp=%%i
echo %timestamp%
Download UnxUtils
Link.
References
This awesome answer that I build upon.
PowerShell
Try the code below.
It will create the file or folder varible with the date as ddmmyyhhmm in 24hour time
[int] $day = Get-Date -UFormat %d
[int] $month = Get-Date -UFormat %m
[int] $year = Get-Date -UFormat %y
[String] $date = "$($day)$($month)$($year)"
$time = Get-Date -UFormat %R
$time -replace ‘[:]’,”"
$fileFolderName = $date + time
Given a known locality, for reference in functional form. The ECHOTIMESTAMP call shows how to get the timestamp into a variable (DTS in this example.)
#ECHO off
CALL :ECHOTIMESTAMP
GOTO END
:TIMESTAMP
SETLOCAL EnableDelayedExpansion
SET DATESTAMP=!DATE:~10,4!-!DATE:~4,2!-!DATE:~7,2!
SET TIMESTAMP=!TIME:~0,2!-!TIME:~3,2!-!TIME:~6,2!
SET DTS=!DATESTAMP: =0!-!TIMESTAMP: =0!
ENDLOCAL & SET "%~1=%DTS%"
GOTO :EOF
:ECHOTIMESTAMP
SETLOCAL
CALL :TIMESTAMP DTS
ECHO %DTS%
ENDLOCAL
GOTO :EOF
:END
EXIT /b 0
And saved to file, timestamp.bat, here's the output:
With Windows 7, this code works for me:
SET DATE=%date%
SET YEAR=%DATE:~0,4%
SET MONTH=%DATE:~5,2%
SET DAY=%DATE:~8,2%
ECHO %YEAR%
ECHO %MONTH%
ECHO %DAY%
SET DATE_FRM=%YEAR%-%MONTH%-%DAY%
ECHO %DATE_FRM%
I know that there are numerous ways mentioned already. But here is my way to break it down to understand how it is done. Hopefully, it is helpful for someone who like step by step method.
:: Check your local date format
echo %date%
:: Output is Mon 08/15/2016
:: get day (start index, number of characters)
:: (index starts with zero)
set myday=%DATE:~0,4%
echo %myday%
:: output is Mon
:: get month
set mymonth=%DATE:~4,2%
echo %mymonth%
:: output is 08
:: get date
set mydate=%DATE:~7,2%
echo %mydate%
:: output is 15
:: get year
set myyear=%DATE:~10,4%
echo %myyear%
:: output is 2016
I note that the o/p did not ask for a region-independent solution. My solution is for the UK though.
This is the simplest possible solution, a 1-line solution, for use in a Batch file:
FOR /F "tokens=1-3 delims=/" %%A IN ("%date%") DO (SET today=%%C-%%B-%%A)
echo %today%
This solution can be varied, by altering the order of the variables %%A %%B and %%C in the output statement, to provide any date format desired (e.g. YY-MM-DD or DD-MM-YY).
My intention - my ONLY intention - in posting this answer is to demonstrate that this can be done on the command line, by using a single line of code to achieve it.
And that it is redundant to post answers running to 35 lines of code, as others have done, because the o/p specifically asked for a command line solution in the question. Therefore the o/p specifically sought a single-line solution.

Resources