Reputation: 21
I know the command to delete the files which are olders then days. How to delete 12 hours old files using forfiles command
I am using forfile command in .bat file
Upvotes: 2
Views: 12283
Reputation: 130819
It is ridiculous how difficult it is to work with date and time in Windows batch. I suspect PowerShell may be better, but I don't really know.
I have written a handy hybrid JScript/batch utility that does date and time arithmetic and formatting. It can be used to establish the date and time 12 hours ago, and format it in virtually any format needed. The utility works on any Windows platform from XP onward. It is pure script, so it does not require download or installation of any exe file. getTimestamp.bat is available here. The actual utility is at the bottom of the post, and it includes extensive documentation within the script.
The FOR
command can give the last modified date and time, but it uses localized formatting, which makes it difficult to parse with generic code. To make matters worse, it ignores whether daylight savings was in effect or not. So it becomes impossible to accurately determine the elapsed time on days when transitioning either direction between standard time and daylight savings time.
WMIC provides the timestamp, complete with time zone information that accounts for daylight savings, in a universal format that does not vary between locales. The timestamp is in a format that sorts chronologically when doing string comparisons, a very important and useful point.
The getTimestamp.bat
utility can be used to get the current timestamp and the cutoff timestamp for deletion. The cutoff needs to be adjusted + or - one hour if the file timestamp and current timestamp do not agree with regard to daylight savings time. The cutoff is formatted to match the WMIC timestamp to make comparisons simple.
Assuming getTimestamp.bat
is either in your current folder, or better yet, somewhere in your PATH
, then the following should work. I believe it should work anywhere in the world, as long as the local daylight savings adjustment is 1 hour. I don't know if there are any locales where daylight savings is something other than an hour.
I've generally tested the code, but I haven't tested the daylight savings transition days. I might have gotten my logic backwards.
@echo off
setlocal disableDelayedExpansion
:: Define the folder to delete from.
:: The value must be a path without a file name or file wild cards.
set "folderPath=d:\test"
:: Define the hour offset for the deletion cutoff
set /a hourOffset=-12
for /f "delims=" %%F in ("%folderPath%\") do (
set "driveFilter=%%~dF"
set "pathFilter=%%~pF"
)
for /f "tokens=1-3" %%A in ('getTimestamp -f "{ums} {zzzz} {z}"') do (
set "now=%%A"
set "tz=%%B"
set "z=%%C"
)
call getTimestamp -d %now% -oh %hourOffset% -f {yyyy}{mm}{dd}{hh}{nn}{ss} -r cutoff
call getTimestamp -d %now% -oh %hourOffset%-1 -f {yyyy}{mm}{dd}{hh}{nn}{ss} -r cutoff-1
call getTimestamp -d %now% -oh %hourOffset%+1 -f {yyyy}{mm}{dd}{hh}{nn}{ss} -r cutoff+1
for /f "tokens=1* delims=." %%A in (
'wmic datafile where "Drive='%driveFilter%' and Path='%pathFilter:\=\\%'" get LastModified^,Name'
) do for /f "tokens=2* delims=+- " %%C in ("%%B") do (
if "%%C" neq "%tz:~1%" (
set "fz=%%B"
set "file=%%~fD"
setlocal enableDelayedExpansion
set /a "fz=!fz:~6,1!1!fz:~7,3!%%1000"
if !fz! lss !z! if "%%A" leq "%cutoff-1%" del "!file!"
if !fz! gtr !z! if "%%A" leq "%cutoff+1%" del "!file!"
endlocal
) else (
if "%%A" leq "%cutoff%" del "%%~fD"
)
)
exit /b
Upvotes: 2
Reputation: 11151
Ok, I did hard work for you...
SETLOCAL ENABLEDELAYEDEXPANSION
REM 1: Parse date time string
FOR /F "TOKENS=1-5 DELIMS=/-:,. " %%i IN ("%DATE% %TIME%") DO (
SET year=%%k
SET month=%%j
SET day=%%i
SET hour=%%l
SET minute=%%m
)
REM 2: Subtract 12 hours, handling day wrap including leap year.
SET /A hour-=12
IF %hour% LSS 0 SET /A hour+=24 & SET /A day-=1
IF %day% LSS 1 (
SET /A month-=1
IF !month! LSS 1 SET /A month+=12 & SET /A year-=1
FOR %%m IN (1 3 5 7 8 10 12) DO IF %%m == !month! SET /A day+=31
FOR %%m IN (4 6 9 11) DO IF %%m == !month! SET /A day+=30
IF !month! == 2 (
SET /A day+=28
SET /A y4=!year! %% 4
IF !y4! == 0 (
SET /A y400=!year! %% 400
IF !y400! == 0 (
SET /A day+=1
) ELSE (
SET /A y100=!year! %% 100
IF NOT !y100! == 0 SET /A day+=1
)
)
)
)
REM 3: Normalize string for later string comparison
CALL :norm_datetime "%day%-%month%-%year% %hour%:%minute%" limit_datetime
REM 4: List file, parse file sate time and delete on comparison verified.
FOR %%f IN (*.*) DO (
CALL :norm_datetime "%%~tf" file_datetime
IF !file_datetime! LSS %limit_datetime% ECHO DEL %%f
)
ENDLOCAL
GOTO :EOF
REM 4: function to normalize date time string
REM norm_datetime "time string" output_environment_variable
REM time string format must be d-m-y-h-m[-...], where - is any valid separator.
REM output will be YYYYMMDDTHHMM
:norm_datetime
FOR /F "TOKENS=1-5 DELIMS=/-:,. " %%i IN ("%~1") DO (
SET year=0000%%k
SET month=00%%j
SET day=00%%i
SET hour=00%%l
SET minute=00%%m
)
SET %2=%year:~-4%%month:~-2%%day:~-2%T%hour:~-2%%minute:~-2%
GOTO :EOF
Check expected date and time formats in code remarks.
Note that date and time format are system dependent, so this code must be adapted for different systems.
Upvotes: 4