# DOS Batch file to delete files by date range



## AHMEDBAT

I have a folder that i have to clean out weekly but only want to delete a certain range of files that are in a date range. 

I'd like to create a batch file that could do this in dos but am not sure of how to go about this.

Any help would be greatly appreciated.


----------



## TheOutcaste

Welcome to TSG!

Would this be by Date Created or Date Modified?
One folder only, or also delete files from subfolders?
Remove subfolders if empty, or leave them in place?
Remove folders if empty, or leave it in place?
Always the same number of days, or do you need to specify both start and end dates?
Or specify a date and number of days before or after to delete?
What OS will this be running under, 2K, XP, Vista, Win 7, 2k3, 2k8?


----------



## AHMEDBAT

*Would this be by Date Created or Date Modified?*
*It would be Date Modified*
*One folder only, or also delete files from subfolders?*
*it would be one folder only it will be no subfolders*
*Remove folders if empty, or leave it in place?*
*leave them in place if they r empty
Always the same number of days, or do you need to specify both start and end dates?*
*I need to specify both start and end date*
*OS will this be running under, 2K, XP, Vista, Win 7, 2k3, 2k8? *
*win xp*

*thank you for ur help :up:*


----------



## TheOutcaste

Give this a try. This will print *Del Filename* on the screen for each file it will delete for testing. Remove the *Echo* in line 45 to actually delete files.


Code:


:: Deletes files from a folder based on entered dates
:: Year can be 2 or 4 digits, if not specified uses current
:: year. Leading zeros not needed on month or date, can enter
:: Start,End or End,Start. If the difference in dates
:: is more than 30 days a warning will be displayed.
:: Drag and drop the folder, specify on command line,
:: Put this batch file in the parent folder or set the
:: folder path in the program on the Set _Src= line
:: Hidden and system files will not be deleted.
@Echo Off
Setlocal EnableDelayedExpansion
Set _Src=%~dp0
If Not "%~1"=="" Set _Src=%~1
Call :_GetDate
Set _CurYr=%_fdate:~0,4%
If %_iDate%==0 Set _Format=M%_sDate%D%_sDate%[[CC]YY]
If %_iDate%==1 Set _Format=D%_sDate%M%_sDate%[[CC]YY]
If %_iDate%==2 Set _Format=[[CC]YY]%_sDate%M%_sDate%D
:_Ask
Set _Dates=
Echo.
Echo.Enter the range of dates to be deleted from %_Src%
Echo.Enter the two dates in this format: %_Format%,%_Format% in any order
Echo.Year must be 2 or 4 digits, Leading zeros are not required for month or day
If Not "%_sDate%"==" " Echo You may use a space instead of %_sDate%
Echo.
Echo.If the year is not specified, %_CurYr% will be used.
Set /P _Dates=   Press Enter to cancel: 
If "%_Dates%"=="" Goto :EOF
Set _NumTok=1-3
For /F "Tokens=1,2 Delims=," %%I In ("%_Dates%") Do (
  Call :_GetDate%_iDate% "%%~I"
  Set _Tmp=!_fdate!
  If "%%J"=="" (Echo.)&Echo Missing Date, Please Reenter dates&Goto _Ask
  Call :_GetDate%_iDate% "%%~J")
If "%_Tmp%" LEQ "%_fdate%" (Set _Tmp1=%_Tmp%)&(Set _Tmp2=%_fdate%) Else (Set _Tmp1=%_fdate%)&(Set _Tmp2=%_Tmp%)
Call :_JDate %_Tmp1%
Set _JStart=%_JDate%
Call :_JDate %_Tmp2%
Set _JEnd=%_JDate%
Set /A _Diff=_JEnd-_JStart
If %_Diff% GTR 30 (
Echo.
Echo.*****  Date Range is %_Diff% Days.  *****
Set /P _Resp=Press Y to confirn dates, any other key to re-enter: 
If Not "%_Resp%"=="Y" Goto _Ask)
PushD "%_Src%"
:: Remove -H and/or -S to include Hidden and/or System files
For /F "Tokens=*" %%I In ('Dir /A-D-H-S /B /OD /TW') Do (
  If /I NOT "%%I"=="Desktop.ini" If /I NOT "%%~fI"=="%~f0" (
    For /F "Tokens=1" %%D In ('Echo %%~tI') Do Call :_GetDate "%%D"
    Call :_JDate !_fdate!
    If Not !_Jdate! LSS %_JStart% If !_Jdate! LEQ !_JEnd! ([COLOR=Red][B]Echo[/B][/COLOR] Del %%I) Else (Goto _Done)))
:_Done
PopD
Goto :EOF
:_JDate
:: Convert date to Julian
:: Arguments : YYYY MM DD
:: Returns   : Julian date in _JDate
:: Usage
:: Call :_JDate %_GYear% %_GMonth% %_GDay%
:: First strip leading zeroes; a logical error in this
:: routine was corrected with help from Alexander Shapiro
:: Code taken from datediff.bat written by Rob van der Woude
:: http://www.robvanderwoude.com
:: Modified to handle months and days without leading zeros
:: By TheOutcaste http://forums.techguy.org
Set _JMM=%2
Set _JDD=%3
If 1%_JMM% LSS 110 Set _JMM=%_JMM:~-1%
If 1%_JDD% LSS 110 Set _JDD=%_JDD:~-1%
::
:: Algorithm based on Fliegel-Van Flandern
:: algorithm from the Astronomical Almanac,
:: provided by Doctor Fenton on the Math Forum
:: (http://mathforum.org/Library/drmath/view/51907.html),
:: and converted to batch code by Ron Bakowski.
Set /A _JMonth1 = ( %_JMM% - 14 ) / 12
Set /A _JYear1  = %1 + 4800
Set /A _JDate  = 1461 * ( %_JYear1% + %_JMonth1% ) / 4 + 367 * ( %_JMM% - 2 -12 * %_JMonth1% ) / 12 - ( 3 * ( ( %_JYear1% + %_JMonth1% + 100 ) / 100 ) ) / 4 + %_JDD% - 32075
For %%A In (_JMonth1 _JYear1) Do Set %%A=
Goto:EOF 
:_GetDate
:: This batch file will always display the same results,
:: independent of "International" settings.
:: This batch file uses REG.EXE from the NT Resource Kit
:: (already installed with WinXP and Vista)
:: to read the "International" settings from the registry.
:: Date is returned as yyyy mm dd in variable _fdate
:: Modified by TheOutcaste http://forums.techguy.org from
:: SortDate Written byRob van der Woude http://www.robvanderwoude.com
:: to check for two digit years
:: If passed a parameter use that for the date
If "%~1"=="" (Set _Date=%Date%) Else Set _Date=%~1
If "%_Date%A" LSS "A" (Set _NumTok=1-3) Else (Set _NumTok=2-4)
:: Default Delimiter of TAB and Space are used
If NOT Defined _iDate (
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)
Set _TDYM=
Set _FYDF=1
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
If "%_fdate:~2,1%"==" " (Set _FYDF=0) & For /F "Tokens=3 skip=3" %%I In ('Reg Query "HKCU\Control Panel\International\Calendars\TwoDigitYearMax" /V 1 2^>Nul') Do Set _TDYM=%%I
If Defined _TDYM (Set _MaxY=%_TDYM:~2%&Set _Cent=%_TDYM:~0,2%) Else (Set _MaxY=29&Set _Cent=20)
Set /A _Cm1=_Cent-1
If %_FYDF%==0 If %_fdate:~0,2% LEQ %_MaxY% (Set _fdate=%_Cent%%_fdate%) Else (Set _fdate=%_Cm1%%_fdate%)
Goto:EOF
:_Getdate0
For /F "Tokens=%_NumTok% DELIMS=%_sDate% " %%B In ("%~1") Do (
If "%%D"=="" (Set _Year=%_CurYr%) Else Set _Year=%%D
Set _Month=%%B
Set _Day=%%C)
Goto _Check
:_Getdate1
For /F "Tokens=%_NumTok% DELIMS=%_sDate% " %%B In ("%~1") Do (
If "%%D"=="" (Set _Year=%_CurYr%) Else Set _Year=%%D
Set _Month=%%C
Set _Day=%%B)
Goto _Check
:_Getdate2
For /F "Tokens=%_NumTok% DELIMS=%_sDate% " %%B In ("%~1") Do (
If "%%D"=="" (Set _Year=%_CurYr%) Else Set _Year=%%B
Set _Month=%%C
Set _Day=%%D)
:_Check
If %_Year% LEQ 100 If %_Year% LEQ %_MaxY% (Set _Year=%_Cent%%_Year%) Else (Set _Year=%_Cm1%%_Year%)
If 1%_Month% LSS 20 Set _Month=0%_Month%
If 1%_Day% LSS 20 Set _Day=0%_Day%
Set _fdate=%_Year% %_Month% %_Day%
Goto :EOF


----------



## h00dstoker

really very good.
Thanks !


----------



## AHMEDBAT

Dear.. this is what i get in result..
please see attached ..
do i make something wrong?


----------



## TheOutcaste

The brackets around the year indicates that entering the parts in brackets is optional, but the brackets should not be included.
Enter the dates like this:
*18/11/2003,27/5/2009*
or
*18/11/03,27/5/09*


----------



## AHMEDBAT

this is what i get now..

something weird .. sometimes when i re-enter the date range it lists the files what will be deleted and sometimes it doesn't.
buut even whn it lists the files it doesn't show all the files in this range..


----------



## TheOutcaste

OK, found my mistake when checking the response for time periods over 30 days. I don't think it would affect the files that are being listed though.

For me, it's showing all files that are not hidden or system that were modified between the dates I enter, so I don't know why it's not listing them all for you, unless there is something in the regional options that is affecting something.

If it's still not showing all the files, go to *Control Panel | Classic View | Regional and Language Options*
On the Regional Options tab, what language is set in the Drop Down box?
Have you customized any of the date or time formats?
I'll do some testing, see if I can see what's going on.

Here's the corrected version:


Code:


:: Deletes files from a folder based on entered dates
:: Year can be 2 or 4 digits, if not specified uses current
:: year. Leading zeros not needed on month or date, can enter
:: Start,End or End,Start. If the difference in dates
:: is more than 30 days a warning will be displayed.
:: Drag and drop the folder, specify on command line,
:: Put this batch file in the parent folder or set the
:: folder path in the program on the Set _Src= line
:: Hidden and system files will not be deleted.
@Echo Off
Setlocal EnableDelayedExpansion
Set _Src=%~dp0
If Not "%~1"=="" Set _Src=%~1
Call :_GetDate
Set _CurYr=%_fdate:~0,4%
If %_iDate%==0 Set _Format=M%_sDate%D%_sDate%[[CC]YY]
If %_iDate%==1 Set _Format=D%_sDate%M%_sDate%[[CC]YY]
If %_iDate%==2 Set _Format=[[CC]YY]%_sDate%M%_sDate%D
:_Ask
Set _Dates=
Echo.
Echo.Enter the range of dates to be deleted from %_Src%
Echo.Enter the two dates in this format: %_Format%,%_Format% in any order
Echo.Year must be 2 or 4 digits, Leading zeros are not required for month or day
If Not "%_sDate%"==" " Echo You may use a space instead of %_sDate%
Echo.
Echo.If the year is not specified, %_CurYr% will be used.
Set /P _Dates=   Press Enter to cancel: 
If "%_Dates%"=="" Goto :EOF
Set _NumTok=1-3
For /F "Tokens=1,2 Delims=," %%I In ("%_Dates%") Do (
  Call :_GetDate%_iDate% "%%~I"
  Set _Tmp=!_fdate!
  If "%%J"=="" (Echo.)&Echo Missing Date, Please Reenter dates&Goto _Ask
  Call :_GetDate%_iDate% "%%~J")
If "%_Tmp%" LEQ "%_fdate%" (Set _Tmp1=%_Tmp%)&(Set _Tmp2=%_fdate%) Else (Set _Tmp1=%_fdate%)&(Set _Tmp2=%_Tmp%)
Call :_JDate %_Tmp1%
Set _JStart=%_JDate%
Call :_JDate %_Tmp2%
Set _JEnd=%_JDate%
Set /A _Diff=_JEnd-_JStart
If %_Diff% LEQ 30 Goto _Process
Echo.
Echo.*****  Date Range is %_Diff% Days.  *****
Set /P _Resp=Press Y to confirm dates, any other key to re-enter: 
If Not "%_Resp%"=="Y" Goto _Ask
:_Process
PushD "%_Src%"
:: Remove -H and/or -S to include Hidden and/or System files
For /F "Tokens=*" %%I In ('Dir /A-D-H-S /B /OD /TW') Do (
  If /I NOT "%%I"=="Desktop.ini" If /I NOT "%%~fI"=="%~f0" (
    For /F "Tokens=1" %%D In ('Echo %%~tI') Do Call :_GetDate "%%D"
    Call :_JDate !_fdate!
    If Not !_Jdate! LSS %_JStart% If !_Jdate! LEQ !_JEnd! ([COLOR=Red][B]Echo[/B][/COLOR] Del %%I) Else (Goto _Done)))
:_Done
PopD
Goto :EOF
:_JDate
:: Convert date to Julian
:: Arguments : YYYY MM DD
:: Returns   : Julian date in _JDate
:: Usage
:: Call :_JDate %_GYear% %_GMonth% %_GDay%
:: First strip leading zeroes; a logical error in this
:: routine was corrected with help from Alexander Shapiro
:: Code taken from datediff.bat written by Rob van der Woude
:: http://www.robvanderwoude.com
:: Modified to handle months and days without leading zeros
:: By TheOutcaste http://forums.techguy.org
Set _JMM=%2
Set _JDD=%3
If 1%_JMM% LSS 110 Set _JMM=%_JMM:~-1%
If 1%_JDD% LSS 110 Set _JDD=%_JDD:~-1%
::
:: Algorithm based on Fliegel-Van Flandern
:: algorithm from the Astronomical Almanac,
:: provided by Doctor Fenton on the Math Forum
:: (http://mathforum.org/Library/drmath/view/51907.html),
:: and converted to batch code by Ron Bakowski.
Set /A _JMonth1 = ( %_JMM% - 14 ) / 12
Set /A _JYear1  = %1 + 4800
Set /A _JDate  = 1461 * ( %_JYear1% + %_JMonth1% ) / 4 + 367 * ( %_JMM% - 2 -12 * %_JMonth1% ) / 12 - ( 3 * ( ( %_JYear1% + %_JMonth1% + 100 ) / 100 ) ) / 4 + %_JDD% - 32075
For %%A In (_JMonth1 _JYear1) Do Set %%A=
Goto:EOF 
:_GetDate
:: This batch file will always display the same results,
:: independent of "International" settings.
:: This batch file uses REG.EXE from the NT Resource Kit
:: (already installed with WinXP and Vista)
:: to read the "International" settings from the registry.
:: Date is returned as yyyy mm dd in variable _fdate
:: Modified by TheOutcaste http://forums.techguy.org from
:: SortDate Written byRob van der Woude http://www.robvanderwoude.com
:: to check for two digit years
:: If passed a parameter use that for the date
If "%~1"=="" (Set _Date=%Date%) Else Set _Date=%~1
If "%_Date%A" LSS "A" (Set _NumTok=1-3) Else (Set _NumTok=2-4)
:: Default Delimiter of TAB and Space are used
If NOT Defined _iDate (
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)
Set _TDYM=
Set _FYDF=1
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
If "%_fdate:~2,1%"==" " (Set _FYDF=0) & For /F "Tokens=3 skip=3" %%I In ('Reg Query "HKCU\Control Panel\International\Calendars\TwoDigitYearMax" /V 1 2^>Nul') Do Set _TDYM=%%I
If Defined _TDYM (Set _MaxY=%_TDYM:~2%&Set _Cent=%_TDYM:~0,2%) Else (Set _MaxY=29&Set _Cent=20)
Set /A _Cm1=_Cent-1
If %_FYDF%==0 If %_fdate:~0,2% LEQ %_MaxY% (Set _fdate=%_Cent%%_fdate%) Else (Set _fdate=%_Cm1%%_fdate%)
Goto:EOF
:_Getdate0
For /F "Tokens=%_NumTok% DELIMS=%_sDate% " %%B In ("%~1") Do (
If "%%D"=="" (Set _Year=%_CurYr%) Else Set _Year=%%D
Set _Month=%%B
Set _Day=%%C)
Goto _Check
:_Getdate1
For /F "Tokens=%_NumTok% DELIMS=%_sDate% " %%B In ("%~1") Do (
If "%%D"=="" (Set _Year=%_CurYr%) Else Set _Year=%%D
Set _Month=%%C
Set _Day=%%B)
Goto _Check
:_Getdate2
For /F "Tokens=%_NumTok% DELIMS=%_sDate% " %%B In ("%~1") Do (
If "%%D"=="" (Set _Year=%_CurYr%) Else Set _Year=%%B
Set _Month=%%C
Set _Day=%%D)
:_Check
If %_Year% LEQ 100 If %_Year% LEQ %_MaxY% (Set _Year=%_Cent%%_Year%) Else (Set _Year=%_Cm1%%_Year%)
If 1%_Month% LSS 20 Set _Month=0%_Month%
If 1%_Day% LSS 20 Set _Day=0%_Day%
Set _fdate=%_Year% %_Month% %_Day%
Goto :EOF


----------



## AHMEDBAT

GREAT!!..
see it works but i have 2 oint..
1- when it lists the files it listed a file that is modified today..
2- when i remove the echo it deleted the files but some fles still exist!!..
is there any note about the namingn of the files or the extention?

attached the current result


----------



## TheOutcaste

Can't believe I'm still forgetting the quotes
Need to add quotes around *%%I* in line 54:


Code:


If Not !_Jdate! LSS %_JStart% If !_Jdate! LEQ !_JEnd! ([COLOR=Red][B]Echo[/B][/COLOR] Del %%I) Else (Goto _Done)))

So it will look like this:


Code:


If Not !_Jdate! LSS %_JStart% If !_Jdate! LEQ !_JEnd! ([COLOR=Red][B]Echo[/B][/COLOR] Del [COLOR=Red][B]"[/B][/COLOR]%%I[COLOR=Red][B]"[/B][/COLOR]) Else (Goto _Done)))

Without the quotes, it won't delete any files that have spaces in their names.

The screen shot shows you are entering the dates as day month year. Your system's Regional settings are set for month day year, as the format line shows:


> *Enter the two dates in this format: M/D/[[CC]YY],M/D/[[CC]YY] in any order*


The Month, Day, Year order is read from the registry. 31/12/09 will be seen as Jul 14, 2011, not Dec 31, 2009.

From the screen shot it looks like it's including itself as a file to delete. The batch file's name is specifically excluded, so that should never happen, regardless of the file date. Even entering the dates with month and day reversed shouldn't allow that to happen.

For testing, add this for the Del statement in line 54, it will display the time and full path for each file, maybe we can see why it's including itself:
*(Echo Del %%~tI,"%%~fI" -- "%%I")*
And add this as the first line in the file (that's a zero, not the letter O):
*@Echo."%~f0"*
Then post a screenshot of the result.


----------



## AHMEDBAT

Hello.. first of all thank you so much .. it works now and it lists the right files.. and it deletes it right.. but the confirmation message to enter "Y" doesn't appear any more..

it didn't include itself.. there is two files..
i made a file del.bat to just list the files to be deleted.. and del1.bat is the one to really delete the files..
so it included the other file.. got me? and i think it's because the date format..
i tried to edit the regional settings to make it DD/MM/YY but this format does not exist.
so i went with it MM/DD/YY.

i still will test the changes u suggested and will get back to u.


----------

