Append date to text file in MS DOS 6.22 - windows

I have been looking around and can't seem to find a solution. I'm a total newbie with Windows command line and scripting in general so I figure this is a great place to ask my question.
I'm basically trying to append a time stamp to my script assignments. We submit the batch scripts as text files and I wanted to put append a time stamp to the text document. I asked my professor and he said it was possible but he wasn't sure how to do it. I can't seem to find the solution that I am looking for online. I know how to do this in the windows command line, but not in on the commandline. Any help would be greatly appreciated!
rem This batch file copies all work to a batch file and then to com1:
#echo off
cls
cd \
cd menu
copy *.bat mywork.bat
echo This file was created on (this is where I run in to trouble)
type mywork.bat > com1:
cd \
cls
All Files have been copied.

These are all MSDOS methods and will mostly not work in default Windows.
Using Qbasic in a batch script:
#echo off
echo open "!_~_!.bat" for output as #1: a$=DATE$>!_~_!.bas
echo ? #1, "SET DAY="+RIGHT$(a$,2)+LEFT$(a$,2)+MID$(a$,4,2)>>!_~_!.bas
echo SYSTEM>>!_~_!.bas
qbasic /run !_~_!.bas
call !_~_!.bat
del !_~_!.bat
del !_~_!.bas
echo %day%
ren filename.xxx %day%.xxx
Native way to get the date
#echo off
echo exit|"%comspec%" /k prompt set d=$D$_|find /v "exit">"%temp%.\datetmp.bat"
for %%a in (call del) do %%a "%temp%.\datetmp.bat"
echo the date is %d%
Using an ASCII binary:
#echo off
:: ascii assembler line processing utility by Herbert Kleebauer
:: for the source code and usage information, use this URL
:: http://groups.google.com.au/groups?q=Usage:+edl
::
echo Bj#jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>edl.com
echo 0DxFP,0Xx.t0P,=XtGsB4o#$?PIyU WwX0GwUY Wv;ovBX2Gv0ExGIuht6>>edl.com
echo ?#}I{uNWEF~NPCkaEFAKLCmaIj#KguHaEFCKYCmavh#{HM?cCiuGGwHmYz>>edl.com
echo CgisCGH`LbuuGNO#hRgco{W?dOGg#N?]gBgoG}G?X_SgONks?GN`LBgDu}>>edl.com
echo G?I_DgGNoG?w#jgLiuuroD#?FHoGpBBDcB?1?pIoCRaICSbICn}ExvHmE?>>edl.com
echo coF?DO~yanxCqap?#?lpZrH~sa`LyNHKqDGwQVTNG`CiECICtdL{D?{esL>>edl.com
echo ysICu_{OuD#sCREGHt~F#lgNHYq`EE{S~{Hq_gC{Lr#CE{HQ}#ExuCNQmB>>edl.com
echo BwjFCs?osqs?}n`LKLj?o{}HwJvClpCSEGt~~1}HGGHCSaCU}GiuJaxLCS>>edl.com
echo c}BWuNC_FE{sCkEGFAPqCmEGNAcQNJwLECuQsa{Oe~CK~CkqCmeGmEFbCN>>edl.com
echo C?kEFbBaCGH1jnjBrz?JAcqo~O~?lJgvxs~CspajF{oFEBHijnjBrz?JAc>>edl.com
echo vx~O~?QJLqos~CspFjN{xFEByijnj#ComJcIpCSAijZNUmJaujC{U]JaJB>>edl.com
echo CcClmCJ\jbCS]GFrj~CkEGjBSookVBA_#NJBHmClnEj1JYjxCoIBrh{BFC>>edl.com
echo HtdCWECaBsCC#ZgB#WgB}fj~BsMV#NgB~chvsb{Os{AR{msDUsycsk{SK{>>edl.com
echo VQ{ZsH\sQdsq{Sj{cAICNWl{~B1CNW_K~BxVkSfCA?Cb#N}W#{=sIfjBH}>>edl.com
echo G}N}NK}NNguM#[umCqBJqD#mzDCCClmCJFuhClmC{#jJSN?`CWEG{Cs#Pt>>edl.com
echo cc?AyAFZp{CkEGjBEpEFDNCCkq=jBktx{S[zDgsjCKtl{S]zDgjjCKtc{S>>edl.com
echo _zDgajCKtG{SazDgXjCKtL{SczDgOjCKtR{SezDgFjCKtX{SYzMgFICG?K>>edl.com
echo gF#FIE?EgF}ZhziEuRN~CK}~DqgLoqo?t_ogIKEh?{JU=fCguGiuz_FrCC>>edl.com
echo sCyOjEEsjwr~EvPK~CSqCt~FS}Ha}HCGxCUqERNG]CRQa_BfsCoaoy?h#x>>edl.com
echo CGJH?w``LRaDBBobc?q?a_q?C_0x>>edl.com
:: creates a variable in YYYYMMDD format
echo.!|edl "" "set date=$tY$ty$tm$td">temp.bat
call temp.bat
del temp.bat
echo %date%
del edl.com
:: $tY : year - leading 2 digits (20 for 2003)
:: $ty : year - trailing 2 digits (13 for 2013)
:: $tm : month - 2 digits
:: $td : day - 2 digits
:: $tH : hour - 2 digits in military time (23:00 is 11pm)
:: $tM : minute - 2 digits
:: $tS : second - 2 digits
Another MSDOS method that gives various date and time info:
:: D8TIME.BAT by Larry Nelson from BATPOWER Fidonet Echo
:: Modified 17/07/1995
#echo off
:: goto %1
:: Setup Magic.bat with %temp% in it withour CR/LF
echo %temp%>%temp%b4.bat
for %%x in (rcx 3 w q) do echo %%x>>%temp%b4.scr
:: ^ (2h=2 chars, 3h=3 chars, 4h=4 chars, etc.)
debug %temp%b4.bat<%temp%b4.scr>nul
:d8ti
echo set d8ti=%%3 %%4 >%temp%!.bat
echo y|copy %temp%b4.bat %temp%magic.bat>nul
dir %temp%!.bat |find "!" >>%temp%magic.bat
call %temp%magic.bat
:: goto L8r
:d8
echo set d8=%%3 >%temp%!.bat
echo y|copy %temp%b4.bat %temp%magic.bat>nul
dir %temp%!.bat |find "!" >>%temp%magic.bat
call %temp%magic.bat
:: goto L8r
:time
echo set time=%%4 >%temp%!.bat
echo y|copy %temp%b4.bat %temp%magic.bat>nul
dir %temp%!.bat |find "!" >>%temp%magic.bat
call %temp%magic.bat
:: goto L8r
:day
echo y|copy %temp%b4.bat %temp%magic.bat>nul
ver |date |find/i "current" >>%temp%magic.bat
echo set day=%%3 >%temp%current.bat
call %temp%magic.bat
:: goto L8r
:L8r
for %%q in (magic current ! b4) do if exist %temp%%%q.bat del %temp%%%q.bat
if exist %temp%b4.scr del %temp%b4.scr
set
pause
:: D8TIME.bat
:: Usage = d8time d8 (date) time (time) d8ti (date/time) day (day of week).
:: Datetime pulls system date and/or time, or day of the
:: week and puts it into an envar with current date/time,
:: date, or time. Find.exe must be in path. A sample usage
:: of Datetime is Bootlog.bat below. With { call bootlog }
:: in your Autoexec.bat a file named Bootlog.dat will
:: receive a record of every time your computer is booted up.
::
::BOOTLOG.BAT
::
:: #echo off
:: cls
:: call d8time d8ti
:: echo %d8ti% >>bootlog.dat
:: set d8ti=
:: :L8r

You can use the %DATE% and/or %TIME% variables:
> echo %DATE% %TIME%
2014-09-23 13:43:03.02
Alternatively, you can use the DATE and/or TIME commands:
> date /t
2014-09-23
> time /t
13:56
The /t switch means "don't prompt to set the date/time, just output the current value". You can pipe the output of the commands to a file like this:
date /t >> mywork.bat
The >> means append the output to the end of the file.

#echo off
setlocal
set "script=%~f0"
set "script=%script:\=\\%"
:: Define simple macros to support JavaScript within batch
set "beginJS=mshta "javascript:close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write("
set "endJS=));""
set "JS=(new ActiveXObject('Scripting.FileSystemObject').GetFile('%script%')).DateCreated"
for /f %%N in (
'%beginJS% %JS% %endJS%'
) do set date_created=%%N
rem checks if time stamp function is created
call :getTimeStamp >nul 2>&1 || (
echo(>>"%~f0"
echo :getTimeStamp >>"%~f0"
echo echo created on %date_created% >>"%~f0"
echo goto :eof >>"%~f0"
)
endlocal
::::::::your code goes here
cls
cd \
cd menu
copy *.bat mywork.bat
::this line is changed
call :getTimeStamp
type mywork.bat > com1:
cd \
cls
All Files have been copied.
::::::::end of your code
goto :eof
EDIT
This is about a REAL dos.Just saw the comments bellow.
This will totally not work on DOS - no call :lablel , no MSHTA , no FOR /F ...
Despite I have no willingness to delete my answer - it was not so easy to get the creation date of the file ,and append a new subroutine (only if there is no already) that prints the date.At least was a good exercise .

Related

How to redirect windows command output to both console and file

In windows I need to give a command similar to
c:>dir > file.txt
But the I need the output both on the file.txt as well as on console. Is there any way to do this.
Syntax is: dir | batchtee file.txt
This is a batch file tool designed by dbenham
::batchTee.bat OutputFile [+]
::
:: Write each line of stdin to both stdout and outputFile.
:: The default behavior is to overwrite any existing outputFile.
:: If the 2nd argument is + then the content is appended to any existing
:: outputFile.
::
:: Limitations:
::
:: 1) Lines are limited to ~1000 bytes. The exact maximum line length varies
:: depending on the line number. The SET /P command is limited to reading
:: 1021 bytes per line, and each line is prefixed with the line number when
:: it is read.
::
:: 2) Trailing control characters are stripped from each line.
::
:: 3) Lines will not appear on the console until a newline is issued, or
:: when the input is exhaused. This can be a problem if the left side of
:: the pipe issues a prompt and then waits for user input on the same line.
:: The prompt will not appear until after the input is provided.
::
#echo off
setlocal enableDelayedExpansion
if "%~1" equ ":tee" goto :tee
:lock
set "teeTemp=%temp%\tee%time::=_%"
2>nul (
9>"%teeTemp%.lock" (
for %%F in ("%teeTemp%.test") do (
set "yes="
pushd "%temp%"
copy /y nul "%%~nxF" >nul
for /f "tokens=2 delims=(/" %%A in (
'^<nul copy /-y nul "%%~nxF"'
) do if not defined yes set "yes=%%A"
popd
)
for /f %%A in ("!yes!") do (
find /n /v ""
echo :END
echo %%A
) >"%teeTemp%.tmp" | <"%teeTemp%.tmp" "%~f0" :tee %* 7>&1 >nul
(call )
) || goto :lock
)
del "%teeTemp%.lock" "%teeTemp%.tmp" "%teeTemp%.test"
exit /b
:tee
set "redirect=>"
if "%~3" equ "+" set "redirect=>>"
8%redirect% %2 (call :tee2)
set "redirect="
(echo ERROR: %~nx0 unable to open %2)>&7
:tee2
for /l %%. in () do (
set "ln="
set /p "ln="
if defined ln (
if "!ln:~0,4!" equ ":END" exit
set "ln=!ln:*]=!"
(echo(!ln!)>&7
if defined redirect (echo(!ln!)>&8
)
)
How about just echoing it?
dir > file.txt & type file.txt

Batch Script: Validate Date Input

I have a batch file that I use to create new project folders for clients that walks a user through the creation process and adds the appropriate files and folders to a central location. I need to add an input section so they can put a date (not always current date) in and it is included in the naming of the files.
The issue I have, and I have hunted high and low and can't find my answer, is that I need to dummy proof the date input. I want the user to input the date in the MM-DD-YYYY format including dashes. It needs to then format it into YYYY-MM-DD. It needs to be smart enough that it forces the user to use the required format of MM-DD-YYYY; has to be numbers and dashes, no slashes, the right amount of characters, and so forth.
I haven't been able to find anything close to even remotely get me where I need to be so I am asking the awesome geniuses out there for help in this regard as it is driving me up a wall. Below is my script code. I need this input to go right after the job type is selected. "Please insert date (MM-DD-YYYY format): "
#echo off
setlocal EnableDelayedExpansion
set version=7.95
set projectpath="P:"
set workbookpath="\\server2\Documents\Blanks (DO NOT EDIT)\dryingworkbook_v3r75.xls"
set questions="\\server2\Documents\Blanks (DO NOT EDIT)\Abatement and Mold Questions.txt"
set notes="\\server2\Documents\Blanks (DO NOT EDIT)\Job Notes.docx"
set info="\\server2\Documents\Blanks (DO NOT EDIT)\Job Information.docx"
set bizname=1
ECHO =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
ECHO = Welcome to SERVPRO Project Creation Wizard v%version% =
ECHO =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
ECHO.
:sof
ECHO.
ECHO Is this new project for a Residential or Commercial job?
:loopJobType
SET /P jobtype=Enter [r] for Residential or [c] for Commercial:
ECHO.
IF "%jobtype%" == "r" GOTO :loopResidential
IF "%jobtype%" == "R" GOTO :loopResidential
IF "%jobtype%" == "c" GOTO :loopCommercial
IF "%jobtype%" == "C" GOTO :loopCommercial
GOTO :loopJobType
:loopResidential
ECHO You have chosen to create a new Residential job project.
ECHO.
set type=1
GOTO :loopFirstName
:loopCommercial
ECHO You have chosen to create a new Commercial job project.
ECHO.
set type=2
SET /p bizname=Please enter the business name:
ECHO.
IF "%bizname%"=="" GOTO :loopCommercial
:loopFirstName
SET /P FirstName=Please enter the insured's first name:
IF "%FirstName%"=="" GOTO :loopFirstName
call :format FirstName
:loopLastName
ECHO.
SET /P LastName= Please enter the insured's last name:
IF "%LastName%"=="" GOTO :loopLastName
call :format LastName
SET FullName=%LastName%, %FirstName%
SET FullBizName=%bizname% (%FullName%)
goto :ConfirmProject
:format
set Name=!%1!
set Head=%Name:~0,1%
set Tail=%Name:~1%
for %%a in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do set Head=!Head:%%a=%%a!
for %%a in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do set Tail=!Tail:%%a=%%a!
set %1=%Head%%Tail%
GOTO :eof
:ConfirmProject
ECHO.
IF "%type%" == "1" SET /P yesno=Are you sure you want to add "%FullName%" to the Project directory? [y/n]
IF "%type%" == "2" SET /P yesno=Are you sure you want to add "%FullBizName%" to the Project directory? [y/n]
IF "%yesno%" == "y" GOTO :CreateProject
IF "%yesno%" == "Y" GOTO :CreateProject
IF "%yesno%" == "n" GOTO :sof
IF "%yesno%" == "N" GOTO :sof
GOTO :ConfirmProject
:CreateProject
IF "%type%" == "1" SET ProjectName=%FullName%
IF "%type%" == "2" SET ProjectName=%FullBizName%
:: Create a folder containing a new project.
mkdir "%projectpath%\%ProjectName%"
ECHO.
ECHO.
ECHO Creating a Project directory for "%ProjectName%" ...
:: Create a folder within said project that will contain job documents.
ECHO Creating a Documents directory for "%ProjectName%" ...
mkdir "%projectpath%\%ProjectName%\Documents"
:: (Taken out of use 7-15-13) ECHO Adding a Job Information file for "%ProjectName%" ...
:: (Taken out of use 7-15-13) copy /-Y %info% "%projectpath%\%ProjectName%\Documents\Job Information - %ProjectName%.docx"
ECHO Documents directory creation for "%ProjectName%" finished ...
:: Create a folder within said project that will contain drying workbook(s).
ECHO Creating a Drying Workbook directory for "%ProjectName%" ...
mkdir "%projectpath%\%ProjectName%\Drying Workbooks"
:: Copy a new blank workbook to the project workbook directory and give it the proper name.
ECHO Adding a Drying Workbook for "%ProjectName%" ...
copy /-Y %workbookpath% "%projectpath%\%ProjectName%\Drying Workbooks\DRY 1_%ProjectName%.xls"
ECHO Adding an Abatement and Mold Questions file for "%ProjectName%" ...
copy /-Y %questions% "%projectpath%\%ProjectName%\Drying Workbooks\Abatement and Mold Questions.txt"
ECHO Drying Workbook directory creation for "%ProjectName%" finished ...
:: Create a folder within said project that will contain original photos.
ECHO Creating a Photos directory for "%ProjectName%" ...
mkdir "%projectpath%\%ProjectName%\"Photos
:: Create a folder within said project photo folder that will contain resized photos.
mkdir "%projectpath%\%ProjectName%\Photos\Resized"
mkdir "%projectpath%\%ProjectName%\Photos\Upload"
ECHO Photos directory creation for "%ProjectName%" finished ...
:: Add in Job Notes file.
ECHO Adding a Job Notes files for "%ProjectName%" ...
copy /-Y %notes% "%projectpath%\%ProjectName%\Job Notes - %ProjectName%.docx"
:: Log the creation of the project.
FOR /F "TOKENS=1* DELIMS= " %%A IN ('DATE/T') DO SET CDATE=%%B
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set date=%%a%%b%%c)
echo off > "%projectpath%\Logs\%ProjectName% - [Project Created %date% by %computername%].txt"
ECHO Logging "%ProjectName%" creation date and time...
ECHO Project directory creation for "%ProjectName%" finished ...
GOTO :OpenProject
:OpenProject
:: Ask if the project should be opened now. If so open and close script, else close script.
set /p reply=Do you want to open the "%ProjectName%" project now? [y/n]
if "%reply%" == "y" %SystemRoot%\explorer.exe "%projectpath%\%ProjectName%"
IF "%yesno%" == "Y" %SystemRoot%\explorer.exe "%projectpath%\%ProjectName%"
GOTO :eof
IF "%yesno%" == "n" GOTO :No
IF "%yesno%" == "N" GOTO :No
exit
:No
ECHO.
ECHO.
ECHO You have successfully created a new project for %ProjectName%.
ECHO.
ECHO Press any key to exit . . .
PAUSE>NUL
:eof
The Batch file below check that the inserted date have the right format and that it represent a valid date, that is, that have the right number of days in each month, even for February on leap years!
#echo off
setlocal EnableDelayedExpansion
set i=0
for %%a in (31 28 31 30 31 30 31 31 30 31 30 31) do (
set /A i+=1
set dpm[!i!]=%%a
)
set /P "inDate=Please insert date (MM-DD-YYYY format): "
if "%inDate:~2,1%%inDate:~5,1%" neq "--" goto invalidDate
for /F "tokens=1-3 delims=-" %%a in ("%inDate%") do set "MM=%%a" & set "DD=%%b" & set "YYYY=%%c"
ver > NUL
set /A month=1%MM%-100, day=1%DD%-100, year=1%YYYY%-10000, leap=year%%4 2>NUL
if errorlevel 1 goto invalidDate
if not defined dpm[%month%] goto invalidDate
if %leap% equ 0 set dpm[2]=29
if %day% gtr !dpm[%month%]! goto invalidDate
if %day% lss 1 goto invalidDate
echo Date correct: %YYYY%-%MM%-%DD%
goto :EOF
:invalidDate
echo Bad date
You can check whether your string is valid easily with the findstr command.
set /p date= Please insert date (MM-DD-YYYY format):
echo %date%| findstr /r "^[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]$">nul
if errorlevel 1 (
echo invalid date
)
pause
(^ means beginning of line, while $ stands for end of line.)
Now for the reformatting MM-DD-YYYY into YYYY-MM-DD, you can split your string and than reassemble it. Since it's a fixed format, this isn't too hard either:
set yyyy=%date:~6,4%
set mm=%date:~0,2%
set dd=%date:~3,2%
set newDate=%yyyy%-%mm%-%dd%
echo %newDate%
The first number in each command resembles the position where the string will be cut.
The second number resembles the length of the substring.
I made a function :getdate who test the date try it;
It will test if the separators are correct, the value range for thr month and the day and
if the values are NUM.
#ECHO OFF
setlocal enabledelayedexpansion
:GetDate
set /p $D=Enter a date (MM-DD-YYYY) :
set $separate=%$d:~2,1% %$d:~5,1%
for %%a in (%$separate%) do (if "%%a" neq "-" (echo Wrong Separator : %%a
pause
goto:Getdate))
set $D=%$D:-= %
set $c=1
for %%a in (%$d%) do (call:test !$c! %%a
set /a $c+=1)
if !$c!==4 set $DateOK=%$month%-%$day%-%$Year%
echo This DATE IS OK %$dateOK%
exit /b
:test
if %1 equ 1 (echo %2 | findstr [0-9][0-9]
if errorlevel 1 (echo Unvalid value for Month [NOT NUM]: %2
pause
goto:getdate)
if %2 GTR 12 (echo Unvalid value for Month [VALUR RANGE +]: %2
pause
goto:getdate)
if %2 LSS 1 (echo Unvalid value for Month [VALUR RANGE -]: %2
pause
goto:getdate)
set $month=%2)
if %1==2 (echo %2 | findstr [0-9][0-9]
if errorlevel 1 (echo Unvalid value for Day [NOT NUM]: %2
pause
goto:getdate)
if %2 GTR 31 (echo Unvalid value for Day [VALUR RANGE +] : %2
pause
goto:getdate)
if %2 LSS 01 (echo Unvalid value for Day [VALUE RANGE -]: %2
pause
goto:getdate)
set $day=%2)
if %1==3 (echo %2 | findstr [0-9][0-9][0-9][0-9]
if errorlevel 1 (echo Unvalid value for Year [NOT NUM] : %2
pause
goto:getdate)
set $Year=%2)
#ECHO OFF
SETLOCAL enabledelayedexpansion
CALL :getverdate
ECHO DATE %indate% is OK.
GOTO :EOF
::
:: Get and verify date in format mm-dd-yyyy; reformat as yyyy-mmm-dd
::
:regetdate
ECHO "%indate%" is not in format "MM-DD-YYYY" or is invalid
:getverdate
SET /p indate="Please insert date (MM-DD-YYYY format): "
IF NOT "%indate:~2,1%%indate:~5,1%"=="--" GOTO regetdate
SET checkdate=9%indate:-=%
IF NOT "%checkdate:~8%"=="%checkdate:~8,1%" GOTO regetdate
FOR %%a IN (0 1 2 3 4 5 6 7 8 9) DO SET checkdate=!checkdate:%%a=!
IF DEFINED checkdate GOTO regetdate
IF %indate:~3,2%==00 GOTO regetdate
FOR %%i IN (01:31 02:29 03:31 04:30 05:31 06:30 07:31 08:31 09:30 10:31 11:30 12:31) DO (
FOR /f "tokens=1,2delims=:" %%j IN ("%%i") DO IF %%j==%indate:~0,2% if "%%k" geq "%indate:~3,2%" GOTO goodday
)
GOTO regetdate
:goodday
IF "%indate:~-4%" geq "1980" IF "%indate:~-4%" leq "2099" GOTO goodyear
GOTO regetdate
:goodyear
SET /a checkdate=%indate:~-4% %% 4
IF "%indate:~0,2%%indate:~3,2%"=="0229" IF %checkdate% neq 0 GOTO regetdate
SET indate=%indate:~-4%-%indate:~0,2%-%indate:~3,2%
GOTO :eof
Here's another 'get and validate date` routine.
Note that in your code you should never set a variable called date. %date% will return the current date - it's a "magic variable" controlled by CMD. Other such variables include %time%, %random% and %errorlevel%. Setting any of these overrides the system-established value.
You could present the user with three prompts - year, month, day.
set /p y="Please enter year (YYYY): "
set /p m="Please enter month (MM): "
set /p d="Please enter day (DD): "
set date=%y%-%m%-%d%
If you would like to verify the length of the input something like:
if [%y:~4%] NEQ [] echo year entered incorrectly & goto :getDate
You can assume if %y% is greater than four characters - i.e. if %y:~4% is not null - that it has been entered incorrectly (see Dos Tips on string manipulation). The same principal applies for day and month, except they should be two characters.
Obviously for that example you would need to add the label :getDate before the user input.
You may use ReadFormattedLine subroutine for all kind of formatted input. For example, the command below read 3 numbers in a date format; the routine just accept digits, insert the hyphens and continue automatically after read the last digit. If the user delete characters, the hyphens are also deleted automatically.
call :ReadFormattedLine myDate="##-##-####" /M "Please insert date (MM-DD-YYYY format): "
This subroutine is written in pure Batch so it does not require any additional program, and it allows several formatted input operations, like read passwords, convert letters to uppercase, etc. You may download ReadFormattedLine subroutine from Read a line with specific format.

Windows batch file timing bug

I've used %time% for timing previously - at least I think I have. I have this weird
IF NOT "%1" == "" (
echo Testing: %1
echo Start: %time%
sqlcmd -S MYSERVER -i test_import_%1.sql -o "test_%1%.log"
sleep 3
echo End: %time%
)
I run this, and it prints:
Testing: pm
Start: 13:29:45.30
End: 13:29:45.30
In this case, my sql code is failing (different reason), but I figure the sleep 3 should make the time increment by 3 at least. Any ideas?
tx,
tff
This has something to do with (not) delayed expansion, but I don't remember how that works exactly. You can work around it by using a "subroutine" like this:
#echo off
if "%1" == "" (
call :doit
)
echo done
goto :eof
:doit
echo %time%
sleep 1
echo %time%
goto :eof
Output:
C:\temp>q
19:46:36.43
19:46:37.45
done
The "proper" way of doing this is probably something like (from this entry in Raymon Chen's blog):
setlocal enabledelayedexpansion
if "%1" == "" (
echo !time!
sleep 2
echo !time!
)
To "see" the problem with immediate expansion, just run this (without echo off):
if "%1" == "" (
echo %time%
sleep 2
echo %time%
)
Output (on Windows 7):
C:\temp>if "" == "" (
echo 19:48:31.95
sleep 2
echo 19:48:31.95
)
19:48:31.95
19:48:31.95
The variables are all expanded at the same time, when the if is parsed.
Pause doesn't accept a parameter at all. It won't fail, but it won't continue either. If all is right, you should see a prompt to press a key.
The time you get, is the time the script is started. Apparently the %time% environment variable is not updated during the execution of the script.
DOS doesn't have a "sleep" function. You need to add this to the end of your batch file (or something like this):
#ECHO off
TITLE Initial title
SET TITLETEXT=Sleep
:: start of script
CALL :sleep 5
:: rest of script
GOTO :END
:: Function
:sleep ARG
ECHO Pausing...
FOR /l %%a in (%~1,-1,1) do (TITLE %TITLETEXT% -- time left %%as&PING.exe -n 2 -w 1 127.0.0.1>nul)
EXIT /B 0
:END
pause
::this is EOF
I tested this code, it should work fine.

Creating a file name as a timestamp in a batch job

We have a batch job that runs every day and copies a file to a pickup folder. I want to also take a copy of that file and drop it into an archive folder with the filename
yyyy-MM-dd.log
What's the easiest way to do this in a Windows batch job?
I'm basically looking for an equivalent of this Unix command:
cp source.log `date +%F`.log
CP source.log %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%.log
But it's locale dependent. I'm not sure if %DATE% is localized, or depends on the format specified for the short date in Windows.
Here is a locale-independent way to extract the current date from this answer, but it depends on WMIC and FOR /F:
FOR /F %%A IN ('WMIC OS GET LocalDateTime ^| FINDSTR \.') DO #SET B=%%A
CP source.log %B:~0,4%-%B:~4,2%-%B:~6,2%.log
This worked for me and was a filename-safe solution (though it generates a MM-dd-YYYY format):
C:\ set SAVESTAMP=%DATE:/=-%#%TIME::=-%
C:\ set SAVESTAMP=%SAVESTAMP: =%
C:\ set SAVESTAMP=%SAVESTAMP:,=.%.jpg
C:\ echo %SAVESTAMP%
11-04-2012#20-52-42.79.jpg
The first command takes a DATE and replaces / with -, takes the TIME and replaces : with -, and combines them into DATE#TIME format. The second set statement removes any spaces, and the third set replaces , with . and appends the .jpg extension.
The above code is used in a little script that pulls images from a security IP Camera for further processing:
:while
set SAVESTAMP=%DATE:/=-%#%TIME::=-%
set SAVESTAMP=%SAVESTAMP: =%
set SAVESTAMP=%SAVESTAMP:,=.%.jpg
wget-1.10.2.exe --tries=0 -O %SAVESTAMP% http://admin:<password>#<ip address>:<port>/snapshot.cgi
timeout 1
GOTO while
For French Locale (France) ONLY, be careful because / appears in the date :
echo %DATE%
08/09/2013
For our problem of log file, here is my proposal for French Locale ONLY:
SETLOCAL
set LOGFILE_DATE=%DATE:~6,4%.%DATE:~3,2%.%DATE:~0,2%
set LOGFILE_TIME=%TIME:~0,2%.%TIME:~3,2%
set LOGFILE=log-%LOGFILE_DATE%-%LOGFILE_TIME%.txt
rem log-2014.05.19-22.18.txt
command > %LOGFILE%
Because the idea of tearing %DATE% and %TIME% apart and mashing them back together seems fragile at best, here's an alternative that uses a powershell oneliner:
for /f %i in ('powershell -c "get-date -format yyyy-MM-dd--HH-mm-ss"') do #set DATETIME=%i
set LOGFILE=my-script-%DATETIME%.txt
Reference for get-date is here, with format options for both .NET-style and UNIX-style.
Here is a locale independent solution (copy to a file named SetDateTimeComponents.cmd):
#echo off
REM This script taken from the following URL:
REM http://www.winnetmag.com/windowsscripting/article/articleid/9177/windowsscripting_9177.html
REM Create the date and time elements.
for /f "tokens=1-7 delims=:/-, " %%i in ('echo exit^|cmd /q /k"prompt $d $t"') do (
for /f "tokens=2-4 delims=/-,() skip=1" %%a in ('echo.^|date') do (
set dow=%%i
set %%a=%%j
set %%b=%%k
set %%c=%%l
set hh=%%m
set min=%%n
set ss=%%o
)
)
REM Let's see the result.
echo %dow% %yy%-%mm%-%dd% # %hh%:%min%:%ss%
I put all my .cmd scripts into the same folder (%SCRIPTROOT%); any script that needs date/time values will call SetDateTimeComponents.cmd as in the following example:
setlocal
#echo Initializing...
set SCRIPTROOT=%~dp0
set ERRLOG=C:\Oopsies.err
:: Log start time
call "%SCRIPTROOT%\SetDateTimeComponents.cmd" >nul
#echo === %dow% %yy%-%mm%-%dd% # %hh%:%min%:%ss% : Start === >> %ERRLOG%
:: Perform some long running action and log errors to ERRLOG.
:: Log end time
call "%SCRIPTROOT%\SetDateTimeComponents.cmd" >nul
#echo === %dow% %yy%-%mm%-%dd% # %hh%:%min%:%ss% : End === >> %ERRLOG%
As the example shows, you can call SetDateTimeComponents.cmd whenever you need to update the date/time values. Hiding the time parsing script in it's own SetDateTimeComponents.cmd file is a nice way to hide the ugly details, and, more importantly, avoid typos.
I frequently use this, and put everything into a single copy command. The following copies example.txt as example_YYYYMMDD_HHMMSS.txt and of course you can modify it to suit your preferred format. The quotes are only necessary if there are any spaces in the filespec. If you want to reuse the exact same date/timestamp, you'd need to store it in a variable.
copy "{path}\example.txt" "{path}\_%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt"
This will ensure that the output is a 2-digit value...you can rearrange the output to your liking and test by un-commenting the diagnostics section. Enjoy!
(I borrowed a lot of this from other forums...)
:: ------------------ Date and Time Modifier ------------------------
#echo off
setlocal
:: THIS CODE WILL DISPLAY A 2-DIGIT TIMESTAMP FOR USE IN APPENDING FILENAMES
:: CREATE VARIABLE %TIMESTAMP%
for /f "tokens=1-8 delims=.:/-, " %%i in ('echo exit^|cmd /q /k"prompt $D $T"') do (
for /f "tokens=2-4 skip=1 delims=/-,()" %%a in ('echo.^|date') do (
set dow=%%i
set %%a=%%j
set %%b=%%k
set %%c=%%l
set hh=%%m
set min=%%n
set sec=%%o
set hsec=%%p
)
)
:: ensure that hour is always 2 digits
if %hh%==0 set hh=00
if %hh%==1 set hh=01
if %hh%==2 set hh=02
if %hh%==3 set hh=03
if %hh%==4 set hh=04
if %hh%==5 set hh=05
if %hh%==6 set hh=06
if %hh%==7 set hh=07
if %hh%==8 set hh=08
if %hh%==9 set hh=09
:: --------- TIME STAMP DIAGNOSTICS -------------------------
:: Un-comment these lines to test output
:: echo dayOfWeek = %dow%
:: echo year = %yy%
:: echo month = %mm%
:: echo day = %dd%
:: echo hour = %hh%
:: echo minute = %min%
:: echo second = %sec%
:: echo hundredthsSecond = %hsec%
:: echo.
:: echo Hello!
:: echo Today is %dow%, %mm%/%dd%.
:: echo.
:: echo.
:: echo.
:: echo.
:: pause
:: --------- END TIME STAMP DIAGNOSTICS ----------------------
:: assign timeStamp:
:: Add the date and time parameters as necessary - " yy-mm-dd-dow-min-sec-hsec "
endlocal & set timeStamp=%yy%%mm%%dd%_%hh%-%min%-%sec%
echo %timeStamp%
Create a file with the current date as filename (ex. 2008-11-08.dat)
echo hello > %date%.dat
With the current date but without the "-" (ex. 20081108.dat)
echo hello > %date:-=%.dat
Maybe this can help:
echo off
#prompt set date=$d$_ set time=$t$h$h$h
echo some log >> %date% %time%.log
exit
or
echo off
set v=%date%.log
echo some log >> %v%
I put together a little C program to print out the current timestamp (locale-safe, no bad characters...). Then, I use the FOR command to save the result in an environment variable:
:: Get the timestamp
for /f %%x in ('#timestamp') do set TIMESTAMP=%%x
:: Use it to generate a filename
for /r %%x in (.\processed\*) do move "%%~x" ".\archived\%%~nx-%TIMESTAMP%%%~xx"
Here's a link:
https://github.com/HarryPehkonen/dos-timestamp
I know this thread is old but I just want to add this here because it helped me alot trying to figure this all out and its clean. The nice thing about this is you could put it in a loop for a batch file that's always running. Server up-time log or something. That's what I use it for anyways. I hope this helps someone someday.
#setlocal enableextensions enabledelayedexpansion
#echo off
call :timestamp freshtime freshdate
echo %freshdate% - %freshtime% - Some data >> "%freshdate - Somelog.log"
:timestamp
set hour=%time:~0,2%
if "%hour:~0,1%" == " " set hour=0%hour:~1,1%
set min=%time:~3,2%
if "%min:~0,1%" == " " set min=0%min:~1,1%
set secs=%time:~6,2%
if "%secs:~0,1%" == " " set secs=0%secs:~1,1%
set FreshTime=%hour%:%min%:%secs%
set year=%date:~-4%
set month=%date:~4,2%
if "%month:~0,1%" == " " set month=0%month:~1,1%
set day=%date:~7,2%
if "%day:~0,1%" == " " set day=0%day:~1,1%
set FreshDate=%month%.%day%.%year%
You can simply detect the current local format and can get the date in your format, for example:
::for 30.10.2016 dd.MM.yyyy
if %date:~2,1%==. set d=%date:~-4%%date:~3,2%%date:~,2%
::for 10/30/2016 MM/dd/yyyy
if %date:~2,1%==/ set d=%date:~-4%%date:~,2%%date:~3,2%
::for 2016-10-30 yyyy-MM-dd
if %date:~4,1%==- set d=%date:~,4%%date:~5,2%%date:~-2%
::variable %d% have now value: 2016103 (yyyyMMdd)
set t=%time::=%
set t=%t:,=%
::variable %t% have now time without delimiters
cp source.log %d%_%t%.log
I know this is an old post, but there is a FAR simpler answer (though maybe it only works in newer versions of windows). Just use the /t parameter for the DATE and TIME dos commands to only show the date or time and not prompt you to set it, like this:
#echo off
echo Starting test batch file > testlog.txt
date /t >> testlog.txt
time /t >> testlog.txt
1) You can download GNU coreutils which comes with GNU date
2) you can use VBScript, which makes date manipulation easier in Windows:
Set objFS = CreateObject("Scripting.FileSystemObject")
strFolder = "c:\test"
Set objFolder = objFS.GetFolder(strFolder)
current = Now
mth = Month(current)
d = Day(current)
yr = Year(current)
If Len(mth) <2 Then
mth="0"&mth
End If
If Len(d) < 2 Then
d = "0"&d
End If
timestamp=yr & "-" & mth &"-"& d
For Each strFile In objFolder.Files
strFileName = strFile.Name
If InStr(strFileName,"file_name_here") > 0 Then
BaseName = objFS.GetBaseName(strFileName)
Extension = objFS.GetExtensionName(strFileName)
NewName = BaseName & "-" & timestamp & "." & Extension
strFile.Name = NewName
End If
Next
Run the script as:
c:\test> cscript /nologo myscript.vbs
This works well with (my) German locale, should be possible to adjust it to your needs...
forfiles /p *PATH* /m *filepattern* /c "cmd /c ren #file
%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%_#file"
For big zip files for deployment, I use quarter hours. No one else on this page had mentioned it before, so I'll put my small script here:
set /a "quarter_hours=%time:~0,2%*4 + %time:~3,2% / 15"
set "zip_file=release_%DATE:~-4%.%DATE:~4,2%.%DATE:~7,2%.%quarter_hours%.zip"
It doesn't zero pad quarter hours from midnight to 5am yet, but it still makes it so you can have a stamped release multiple times a day with few collisions.
Hope that helps.
used Martin's suggestion with a little tweak to add time stamp to the file name:
forfiles /p [foldername] /m rsync2.log /c "cmd /c ren #file %DATE:~6,4%%DATE:~3,2%%DATE:~0,2%_%time:~-11,2%-%time:~-8,2%-%time:~-5,2%-#file
For the 10:17:21 23/10/2019 The result is:
20191023_10-17-21-rsync2.log
echo Date and Time: %date% %time%
rem 29/09/2021 10:01:34,23
set timestamp=%time: =0%
set timestamp=%timestamp::=%
set timestamp=%timestamp:,=%
set timestamp=%date:/=%%timestamp%
echo Timestamp (ddMMYYYYHHmmssms): %timestamp%
rem 2909202109543118
set timestamp=%timestamp:~4,4%%timestamp:~2,2%%timestamp:~0,2%%timestamp:~8,8%
echo Timestamp (YYYYMMddHHmmssms) %timestamp%
rem 2021092910013423
Notice that you could be a little bit more flexible by using negative indexes...
It will fit both English and West Europe date formats (of course with switched positions between days and months)
echo %DATE:~-10,2%%DATE:~-7,2%T%TIME:~0,2%%TIME:~3,2%
This is a 12 year old thread, but still active, and there has not yet been a truly locale-independent batch-only solution so here's my tuppence.
This should work on any windows setup, regardless of your local date settings. To be sure you get the correct DD MM and YYYY parts of the date you need to change the registry short-date format. Try this:
Store current registry short-date format in a local variable
Set the registry format to YYYYMMDD (or whatever you want)
Store current date to a local variable
Reset registry back to the original format
I keep the script below in 'YYYYMMDD.bat' and call it as needed.
#echo off
:: Create environment variable containing current date in YYYYMMDD format.
:: Intended to be called from other batch jobs
::Save current registry date format
for /f "tokens=2*" %%a in ('reg query "HKCU\Control Panel\International" /v sShortDate^|find "REG_SZ"') do set "ssShortDate=%%b"
::Change registry date format to yyyymmdd
reg add "HKCU\Control Panel\International" /f /v sShortDate /d "yyyyMMdd" >nul
::Save current date in yyyymmdd format
set "YYYYMMDD=%date%"
::Restore original format to registry
reg add "HKCU\Control Panel\International" /f /v sShortDate /d "%ssShortDate%" >nul
echo YYYYMMDD=%YYYYMMDD%
timeout /t:1 >nul
exit /b

How to append a date in batch files

I have the following line in a batch file (that runs on an old Windows 2000 box):
7z a QuickBackup.zip *.backup
How do I append the date to the QuickBackup.zip file. So if I ran the batch file today, ideally, the file would be QuickBackup20090514.zip.
Is there a way to do this?
Bernhard's answer needed some tweaking work for me because the %DATE% environment variable is in a different format (as commented elsewhere). Also, there was a tilde (~) missing.
Instead of:
set backupFilename=%DATE:~6,4%%DATE:~3,2%%DATE:0,2%
I had to use:
set backupFilename=%DATE:~10,4%%DATE:~4,2%%DATE:~7,2%
for the date format:
c:\Scripts>echo %DATE%
Thu 05/14/2009
#SETLOCAL ENABLEDELAYEDEXPANSION
#REM Use WMIC to retrieve date and time
#echo off
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
IF NOT "%%~F"=="" (
SET /A SortDate = 10000 * %%F + 100 * %%D + %%A
set YEAR=!SortDate:~0,4!
set MON=!SortDate:~4,2!
set DAY=!SortDate:~6,2!
#REM Add 1000000 so as to force a prepended 0 if hours less than 10
SET /A SortTime = 1000000 + 10000 * %%B + 100 * %%C + %%E
set HOUR=!SortTime:~1,2!
set MIN=!SortTime:~3,2!
set SEC=!SortTime:~5,2!
)
)
#echo on
#echo DATE=%DATE%, TIME=%TIME%
#echo HOUR=!HOUR! MIN=!MIN! SEC=!SEC!
#echo YR=!YEAR! MON=!MON! DAY=!DAY!
#echo DATECODE= '!YEAR!!MON!!DAY!!HOUR!!MIN!'
Output:
DATE=2015-05-20, TIME= 1:30:38.59
HOUR=01 MIN=30 SEC=38
YR=2015 MON=05 DAY=20
DATECODE= '201505200130'
This will work for the non-US date format (dd/MM/yyyy):
set backupFilename=%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%
7z a QuickBackup%backupFilename%.zip *.backup
If you know your regional settings won't change you can do it as follows:
if your short date format is dd/MM/yyyy:
SET MYDATE=%DATE:~3,2%%DATE:~0,2%%DATE:~8,4%
if your short date format is MM/dd/yyyy:
SET MYDATE=%DATE:~0,2%%DATE:~3,2%%DATE:~8,4%
But there's no general way to do it that's independent of your regional settings.
I would not recommend relying on regional settings for anything that's going to be used in a production environment. Instead you should consider using another scripting language - PowerShell, VBScript, ...
For example, if you create a VBS file yyyymmdd.vbs in the same directory as your batch file with the following contents:
' yyyymmdd.vbs - outputs the current date in the format yyyymmdd
Function Pad(Value, PadCharacter, Length)
Pad = Right(String(Length,PadCharacter) & Value, Length)
End Function
Dim Today
Today = Date
WScript.Echo Pad(Year(Today), "0", 4) & Pad(Month(Today), "0", 2) & Pad(Day(Today), "0", 2)
then you will be able to call it from your batch file thus:
FOR /F %%i IN ('cscript "%~dp0yyyymmdd.vbs" //Nologo') do SET MYDATE=%%i
echo %MYDATE%
Of course there will eventually come a point where rewriting your batch file in a more powerful scripting language will make more sense than mixing it with VBScript in this way.
You can also access the date via the variable %DATE%
When testing my system %DATE% produces ddd dd/mm/yyyy
you can use substring operators to produce the format you desire
ie. running the following on MON 11/12/2018 with US regional settings
%DATE:~3,3% %DATE:~0,3% %DATE:~7,2%
Will produce an output:
11 Mon 12
the substring arguments are
%*variable*:~*startpos*,*numberofchars*%
This is all awkward and not local settings independent. Do it like this:
%CYGWIN_DIR%\bin\date +%%Y%%m%%d_%%H%%M% > date.txt
for /f "delims=" %%a in ('type "date.txt" 2^>NUL') do set datetime=%%a
echo %datetime%
del date.txt
Yes, use Cygwin date and all your problems are gone!
Sure.
FOR %%A IN (%Date:/=%) DO SET Today=%%A
7z a QuickBackup%TODAY%.zip *.backup
That is DDMMYYYY format.
Here's YYYYDDMM:
FOR %%A IN (%Date%) DO (
FOR /F "tokens=1-3 delims=/-" %%B in ("%%~A") DO (
SET Today=%%D%%B%%C
)
)
7z a QuickBackup%TODAY%.zip *.backup
There is a tech recipe available here that shows how to format it to MMDDYYYY, you should be able to adapt it for your needs.
echo on
#REM Seamonkey’s quick date batch (MMDDYYYY format)
#REM Setups %date variable
#REM First parses month, day, and year into mm , dd, yyyy formats and then combines to be MMDDYYYY
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%
echo %date%
EDIT: The reason did not work before was because of 'smartquotes' in the original text. I fixed them and the batch file will work if cut & pasted from this page.
I've used the environment variables technique covered here: http://cwashington.netreach.net/depo/view.asp?Index=19
http://cwashington.netreach.net/depo/default.asp?topic=repository&move=last&ScriptType=command&SubType=Misc
Here's the code from that site:
::~~Author~~. Brett Middleton
::~~Email_Address~~. brettm#arches.uga.edu
::~~Script_Type~~. nt command line batch
::~~Sub_Type~~. Misc
::~~Keywords~~. environment variables
::~~Comment~~.
::Sets or clears a group of environment variables containing components of the current date extracted from the string returned by the DATE /T command. These variables can be used to name files, control the flow of execution, etc.
::~~Script~~.
#echo off
::-----------------------------------------------------------------------------
:: SetEnvDate1.CMD 6/30/98
::-----------------------------------------------------------------------------
:: Description : Sets or clears a group of environment variables containing
:: : components of the current date extracted from the string
:: : returned by the DATE /T command. These variables can be
:: : used to name files, control the flow of execution, etc.
:: :
:: Requires : Windows NT with command extensions enabled
:: :
:: Tested : Yes, as demonstration
:: :
:: Contact : Brett Middleton <brettm#arches.uga.edu>
:: : Animal and Dairy Science Department
:: : University of Georgia, Athens
::-----------------------------------------------------------------------------
:: USAGE
::
:: SetEnvDate1 can be used as a model for coding date/time routines in
:: other scripts, or can be used by itself as a utility that is called
:: from other scripts.
::
:: Run or call SetEnvDate1 without arguments to set the date variables.
:: Variables are set for the day abbreviation (DT_DAY), month number (DT_MM),
:: day number (DT_DD) and four-digit year (DT_YYYY).
::
:: When the variables are no longer needed, clean up the environment by
:: calling the script again with the CLEAR argument. E.g.,
::
:: call SetEnvDate1 clear
::-----------------------------------------------------------------------------
:: NOTES
::
:: A time variable could be added by parsing the string returned by the
:: built-in TIME /T command. This is left as an exercise for the reader. B-)
::
:: This script illustrates the following NT command extensions:
::
:: 1. Use of the extended IF command to do case-insensitive comparisons.
::
:: 2. Use of the extended DATE command.
::
:: 3. Use of the extended FOR command to parse a string returned by a
:: command or program.
::
:: 4. Use of the "()" conditional processing symbols to group commands
:: for conditional execution. All commands between the parens will
:: be executed if the preceeding IF or FOR statement is TRUE.
::-----------------------------------------------------------------------------
if not "%1" == "?" goto chkarg
echo.
echo Sets or clears date/time variables in the command environment.
echo.
echo SetEnvDate1 [clear]
echo.
echo When called without arguments, the variables are created or updated.
echo When called with the CLEAR argument, the variables are deleted.
echo.
goto endit
::-----------------------------------------------------------------------------
:: Check arguments and select SET or CLEAR routine. Unrecognized arguments
:: are ignored and SET is assumed.
::-----------------------------------------------------------------------------
:chkarg
if /I "%1" == "CLEAR" goto clrvar
goto setvar
::-----------------------------------------------------------------------------
:: Set variables for the day abbreviation (DAY), month number (MM),
:: day number (DD) and 4-digit year (YYYY).
::-----------------------------------------------------------------------------
:setvar
for /F "tokens=1-4 delims=/ " %%i IN ('date /t') DO (
set DT_DAY=%%i
set DT_MM=%%j
set DT_DD=%%k
set DT_YYYY=%%l)
goto endit
::-----------------------------------------------------------------------------
:: Clear all variables from the environment.
::-----------------------------------------------------------------------------
:clrvar
for %%v in (DT_DAY DT_MM DT_DD DT_YYYY) do set %%v=
goto endit
:endit
As has been noted, parsing the date and time is only useful if you know the format being used by the current user (eg. MM/dd/yy or dd-MM-yyyy just to name 2). This could be determined, but by the time you do all the stressing and parsing, you will still end up with some situation where there is an unexpected format used, and more tweaks will be be necessary.
You can also use some external program that will return a date slug in your preferred format, but that has disadvantages of needing to distribute the utility program with your script/batch.
there are also batch tricks using the CMOS clock in a pretty raw way, but that is tooo close to bare wires for most people, and also not always the preferred place to retrieve the date/time.
Below is a solution that avoids the above problems. Yes, it introduces some other issues, but for my purposes I found this to be the easiest, clearest, most portable solution for creating a datestamp in .bat files for modern Windows systems. This is just an example, but I think you will see how to modify for other date and/or time formats, etc.
reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f
reg add "HKCU\Control Panel\International" /v sShortDate /d "yyMMdd" /f
#REM the following may be needed to be sure cache is clear before using the new setting
reg query "HKCU\Control Panel\International" /v sShortDate
set LogDate=%date%
reg copy "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f
Building on Joe's idea, here is a version which will build its own (.js) helper and supporting time as well:
#echo off
set _TMP=%TEMP%\_datetime.tmp
echo var date = new Date(), string, tmp;> "%_TMP%"
echo tmp = ^"000^" + date.getFullYear(); string = tmp.substr(tmp.length - 4);>> "%_TMP%"
echo tmp = ^"0^" + (date.getMonth() + 1); string += tmp.substr(tmp.length - 2);>> "%_TMP%"
echo tmp = ^"0^" + date.getDate(); string += tmp.substr(tmp.length - 2);>> "%_TMP%"
echo tmp = ^"0^" + date.getHours(); string += tmp.substr(tmp.length - 2);>> "%_TMP%"
echo tmp = ^"0^" + date.getMinutes(); string += tmp.substr(tmp.length - 2);>> "%_TMP%"
echo tmp = ^"0^" + date.getSeconds(); string += tmp.substr(tmp.length - 2);>> "%_TMP%"
echo WScript.Echo(string);>> "%_TMP%"
for /f %%i in ('cscript //nologo /e:jscript "%_TMP%"') do set _DATETIME=%%i
del "%_TMP%"
echo YYYYMMDDhhmmss: %_DATETIME%
echo YYYY: %_DATETIME:~0,4%
echo YYYYMM: %_DATETIME:~0,6%
echo YYYYMMDD: %_DATETIME:~0,8%
echo hhmm: %_DATETIME:~8,4%
echo hhmmss: %_DATETIME:~8,6%
Sairam
With the samples given above, I have tried & came out with the script which I wanted. The position parameters mentioned in other example gave different results. I wanted to create one Batch file to take the Oracle data backup (export data) on daily basis, preserving distinct DMP files with date & time as part of file name. Here is the script which worked well:
cls
set dt=%date:~0,2%%date:~3,2%%date:~6,4%-%time:~0,2%%time:~3,2%
set fn=backup-%dt%.DMP
echo %fn%
pause A
exp user/password file=D:\DATA_DMP\%fn%
If you have WSL enabled (Windows 10 only) you can do it with bash in a locale neutral way.
set dateFile=%TEMP%\currentDate.txt
bash -c "date +%Y%m%d" > %dateFile%
set /p today=<%dateFile%
Feel free to replace the file redirection with a "for" loop abomination suggested in other answers here and over at Windows batch assign output of a program to a variable
I've found two ways that work regardless of the date settings.
On my pc, date/t returns
2009-05-27
You can either access the registry and read the regional settings
(HKEY_CURRENT_USER\Control Panel\International)
Or use a vbscript.
This is the ugly batch file/vbscript hybrid I created some time ago....
#Echo Off
set rnd=%Random%
set randfilename=x%rnd%.vbs
::create temp vbscript file
Echo Dim DayofWeek(7) > %temp%\%randfilename%
Echo DayofWeek(1)="Sun" >> %temp%\%randfilename%
Echo DayofWeek(2)="Mon" >> %temp%\%randfilename%
Echo DayofWeek(3)="Tue" >> %temp%\%randfilename%
Echo DayofWeek(4)="Wed" >> %temp%\%randfilename%
Echo DayofWeek(5)="Thu" >> %temp%\%randfilename%
Echo DayofWeek(6)="Fri" >> %temp%\%randfilename%
Echo DayofWeek(7)="Sat" >> %temp%\%randfilename%
Echo DayofWeek(0)=DayofWeek(Weekday(now)) >> %temp%\%randfilename%
Echo Mon=Left(MonthName(Month(now),1),3) >> %temp%\%randfilename%
Echo MonNumeric=right ( "00" ^& Month(now) , 2) >> %temp%\%randfilename%
Echo wscript.echo ( Year(Now) ^& " " ^& MonNumeric ^& " " ^& Mon ^& " " _ >> %temp%\%randfilename%
Echo ^& right("00" ^& Day(now),2) ^& " "^& dayofweek(0) ^& " "^& _ >> %temp%\%randfilename%
Echo right("00" ^& Hour(now),2)) _ >> %temp%\%randfilename%
Echo ^&":"^& Right("00" ^& Minute(now),2) ^&":"^& Right("00" ^& Second(Now),2) >> %temp%\%randfilename%
::set the output into vars
if "%1" == "" FOR /f "usebackq tokens=1,2,3,4,5,6" %%A in (`start /wait /b cscript //nologo %temp%\%randfilename%`) do Set Y2KYear=%%A& Set MonthNumeric=%%B& Set Month=%%C& Set Day=%%D& Set DayofWeek=%%E& Set Time=%%F
set year=%y2kyear:~2,2%
::cleanup
del %temp%\%randfilename%
It's not pretty, but it works.

Resources