The easy part is getting the date and time but doing it reliably takes a bit more. Simon Sheppard nails it:
@echo off&SETLOCAL :: This will return date into environment vars :: Works on any NT/2K/XP machine independent of regional date settings :: 20 March 2002 FOR /f "tokens=1-4 delims=/-. " %%G IN ('date /t') DO (call :s_fixdate %%G %%H %%I %%J) goto :s_print_the_date :s_fixdate if "%1:~0,1%" GTR "9" shift FOR /f "skip=1 tokens=2-4 delims=(-)" %%G IN ('echo.^|date') DO ( set %%G=%1&set %%H=%2&set %%I=%3) goto :eof :s_print_the_date echo Month:[%mm%] Day:[%dd%] Year:[%yy%] ENDLOCAL&SET mm=%mm%&SET dd=%dd%&SET yy=%yy% :: see also http://www.robvanderwoude.com/amb_datetime.html :: http://www.robvanderwoude.com/datetiment.html :: http://www.commandline.co.uk/cmdfuncs/dandt/index.html
@echo off SETLOCAL :: This will return time into environment vars :: Works on any NT/2K/XP machine independent of time format :: 10 Nov 2002 FOR /f "tokens=*" %%G IN ('time/t') DO set v_time=%%G SET v_time=%v_time:~0,2%-%v_time:~3,2% ENDLOCAL&SET v_time=%v_time% SET v :: see also http://www.robvanderwoude.com/amb_datetime.html :: http://www.commandline.co.uk/cmdfuncs/dandt/index.html
This incredible batch file, by Simon Sheppard completes the list of things you didn't think you could do in a batch file.
@ECHO off SETLOCAL :: DateMath, a general purpose date math routine :: If DateMath detects an error, variable v_dd_int is set to 999999. SET v_dd_int=0 SET v_mm_int=0 SET v_yy_int=0 SET v_ymd_str= SET v_mm_str= SET v_dd_str= IF "%3"=="" goto s_syntax IF "%4"=="+" goto s_validate_year IF "%4"=="-" goto s_validate_year IF "%4"=="" goto s_validate_year :s_syntax echo. echo DATEMATH SYNTAX: echo _______________ echo. echo DateMath will set the variables as listed below echo 'str' variables include leading zeros e.g. "01" echo 'int' variables leading zeros are stripped e.g. "1" echo. echo CALL DateMath YY MM DD - YY2 MM2 DD2 echo. echo Will set variable v_dd_int to the signed difference echo between the 2 dates (measured in days) echo. echo. echo CALL DateMath YY MM DD +/- Days echo. echo Will set the following variables to the result of echo adding or substracting days from the initial date: echo v_ymd_str, v_yy_int echo v_mm_str, v_mm_int, echo v_dd_str, v_dd_int echo. echo. echo ___________________________________ pause echo. echo. echo CALL DateMath YY MM DD echo. echo Will set the following variables: echo v_ymd_str, v_yy_int echo v_mm_str, v_mm_int, echo v_dd_str, v_dd_int echo. echo ___________________________________ echo. echo v_ymd_str is in YYYYMMDD format. echo. echo v_yy_int is in YYYY format, even if YY format was originally supplied. echo This conversion is useful for FAT/NTFS file dates which are in YY format. echo. SET /a v_dd_int=999999 goto :eof :s_validate_year ::strip leading zeros SET v_yy=%1 if %v_yy:~0,1% EQU 0 set v_yy=%v_yy:~1% :: Check for Y2K IF %v_yy% LSS 100 IF %v_yy% GEQ 80 SET /A v_yy += 1900 IF %v_yy% LSS 80 SET /A v_yy += 2000 :: at this point v_yy contains a 4 digit year ::validate month and day if %2 GTR 12 goto s_syntax if %3 GTR 31 goto s_syntax SET v_mm=%2 SET v_dd=%3 ::strip leading zeros if %v_mm:~0,1% EQU 0 set v_mm=%v_mm:~1% if %v_dd:~0,1% EQU 0 set v_dd=%v_dd:~1% :: Set the int variables SET /a v_dd_int=%v_dd% SET /a v_yy_int=%v_yy% SET /a v_mm_int=%v_mm% :: Determine which function to perform - ADD, SUBTRACT or CONVERT If not "%6"=="" goto s_validate_2nd_date if "%4"=="" goto s_convert_only :: Add or subtract days to a date SET /a v_number_of_days=%5 goto s_add_or_subtract_days :s_convert_only SET /a v_dd_int=%v_dd% IF %v_dd% LEQ 9 (SET v_dd_str=0%v_dd%) ELSE (SET v_dd_str=%v_dd%) IF %v_mm% LEQ 9 (SET v_mm_str=0%v_mm%) ELSE (SET v_mm_str=%v_mm%) SET v_ymd_str=%v_yy%%v_mm_str%%v_dd_str% ECHO DATEMATH - Convert date only (no maths) goto s_end :::::::::::::::::::::::::::::::::::::::::::::::::: :s_validate_2nd_date If "%4"=="+" goto s_syntax :: Subtracting one date from another :::::: :: strip leading zero SET v_yy2=%5 if %v_yy2:~0,1% EQU 0 set v_yy2=%v_yy2:~1% if %v_yy2% GTR 99 goto s_validate2nd_month if %v_yy2% GTR 49 goto s_prefix_2_1950_1999 if %v_yy2% LSS 10 goto s_prefix_2_2000_2009 SET v_yy2=20%v_yy2% goto s_validate2nd_month :s_prefix_2_2000_2009 SET v_yy2=200%v_yy2% goto s_validate2nd_month :s_prefix_2_1950_1999 SET v_yy2=19%v_yy2% :s_validate2nd_month ::strip leading zeros ::SET /a v_yy2=%v_yy2% if %v_yy2:~0,1% EQU 0 set v_yy2=%v_yy2:~1% ::v_yy2 now contains a 4 digit year if %6 GTR 12 goto s_syntax SET v_mm2=%6 if %7 GTR 31 goto s_syntax SET v_dd2=%7 ::strip leading zeros ::SET /a v_mm2=%v_mm2% if %v_mm2:~0,1% EQU 0 set v_mm2=%v_mm2:~1% ::SET /a v_dd2=%v_dd2% if %v_dd2:~0,1% EQU 0 set v_dd2=%v_dd2:~1% call :s_julian_day %v_yy_int% %v_mm_int% %v_dd_int% SET v_sumdays1=%v_JulianDay% call :s_julian_day %v_yy2% %v_mm2% %v_dd2% SET v_sumdays2=%v_JulianDay% SET /a v_dd_int=%v_sumdays1% - %v_sumdays2% ECHO DATEMATH - Subtracting one date from another = days difference ECHO ~~~~~~ ECHO %v_dd_int% ECHO ~~~~~~ goto s_end_days :::::::::::::::::::::::::::::::::::::::::::::::::: :s_add_or_subtract_days if /i "%4"=="+" goto s_add_up_days :: Subtract all days :::::: SET /a v_dd=%v_dd% - %v_number_of_days% :s_adjust_month_year if %v_dd% GEQ 1 goto s_add_subtract_days_DONE SET /a v_mm=%v_mm% - 1 if %v_mm% GEQ 1 goto s_add_days_%v_mm% SET /a v_yy=%v_yy% - 1 SET /a v_mm=%v_mm% + 12 goto s_add_days_%v_mm% :s_add_days_2 SET /a v_dd=%v_dd% + 28 SET /a v_leapyear=%v_yy% / 4 SET /a v_leapyear=%v_leapyear% * 4 if %v_leapyear% NEQ %v_yy% goto s_adjust_month_year SET /a v_dd=%v_dd% + 1 goto s_adjust_month_year :s_add_days_4 :s_add_days_6 :s_add_days_9 :s_add_days_11 SET /a v_dd=%v_dd% + 30 goto s_adjust_month_year :s_add_days_1 :s_add_days_3 :s_add_days_5 :s_add_days_7 :s_add_days_8 :s_add_days_10 :s_add_days_12 SET /a v_dd=%v_dd% + 31 goto s_adjust_month_year :s_add_up_days :: add all days :::::: SET /a v_dd=%v_dd% + %v_number_of_days% :s_subtract_days_ goto s_subtract_days_%v_mm% :s_adjust_mth_yr SET /a v_mm=%v_mm% + 1 if %v_mm% LEQ 12 goto s_subtract_days_%v_mm% SET /a v_yy=%v_yy% + 1 SET /a v_mm=%v_mm% - 12 goto s_subtract_days_%v_mm% :s_subtract_days_2 SET /a v_leapyear=%v_yy% / 4 SET /a v_leapyear=%v_leapyear% * 4 If %v_leapyear% EQU %v_yy% goto s_subtract_leapyear if %v_dd% LEQ 28 goto s_add_subtract_days_DONE SET /a v_dd=%v_dd% - 28 goto s_adjust_mth_yr :s_subtract_leapyear if %v_dd% LEQ 29 goto s_add_subtract_days_DONE SET /a v_dd=%v_dd% - 29 goto s_adjust_mth_yr :s_subtract_days_4 :s_subtract_days_6 :s_subtract_days_9 :s_subtract_days_11 if %v_dd% LEQ 30 goto s_add_subtract_days_DONE SET /a v_dd=%v_dd% - 30 goto s_adjust_mth_yr :s_subtract_days_1 :s_subtract_days_3 :s_subtract_days_5 :s_subtract_days_7 :s_subtract_days_8 :s_subtract_days_10 :s_subtract_days_12 if %v_dd% LEQ 31 goto s_add_subtract_days_DONE SET /a v_dd=%v_dd% - 31 goto s_adjust_mth_yr :s_add_subtract_days_DONE SET /a v_dd_int=%v_dd% SET /a v_mm_int=%v_mm% SET /a v_yy_int=%v_yy% IF %v_dd% GTR 9 (SET v_dd_str=%v_dd%) ELSE (SET v_dd_str=0%v_dd%) IF %v_mm% GTR 9 (SET v_mm_str=%v_mm%) ELSE (SET v_mm_str=0%v_mm%) SET v_ymd_str=%v_yy%%v_mm_str%%v_dd_str% ECHO DATEMATH - add or subtract days from a date = new date goto s_end :::::::::::::::::::::::::::::::::::::::::::::::::: :s_julian_day SET v_year=%1 SET v_month=%2 SET v_day=%3 SET /a v_month=v_month SET /a v_day=v_day SET /A a = 14 - v_month SET /A a /= 12 SET /A y = v_year + 4800 - a SET /A m = v_month + 12 * a - 3 SET /A m = 153 * m + 2 SET /A m /= 5 SET /A v_JulianDay = v_day + m + 365 * y + y / 4 - y / 100 + y / 400 - 32045 ECHO The Julian Day is [%v_JulianDay%] goto :eof :::::::::::::::::::::::::::::::::::::::::::::::::: :s_end ECHO ~~~~~~~~~~~~ ECHO [%v_ymd_str%] YY=[%v_yy_int%] MM=[%v_mm_str%] DD=[%v_dd_str%] ECHO ~~~~~~~~~~~~ :s_end_days ENDLOCAL&SET /a v_yy_int=%v_yy_int%&SET /a v_mm_int=%v_mm_int%&SET /a v_dd_int=%v_dd_int%&SET v_ymd_str=%v_ymd_str%&SET v_mm_str=%v_mm_str%&SET v_dd_str=%v_dd_str%D:\>datemath 02 05 08 DATEMATH - Convert date only (no maths) ~~~~~~~~~~~~ [20020508] YY=[2002] MM=[05] DD=[08] ~~~~~~~~~~~~ D:\>datemath 2007 12 30 DATEMATH - Convert date only (no maths) ~~~~~~~~~~~~ [20071230] YY=[2007] MM=[12] DD=[30] ~~~~~~~~~~~~ D:\>datemath 27 12 01 - 02 11 02 The Julian Day is [2461741] The Julian Day is [2452581] DATEMATH - Subtracting one date from another = days difference ~~~~~~ 9160 ~~~~~~ D:\>datemath 02 11 02 + 9160 DATEMATH - add or subtract days from a date = new date ~~~~~~~~~~~~ [20271201] YY=[2027] MM=[12] DD=[01] ~~~~~~~~~~~~ D:\>datemath 12 09 08 - 11 09 08 The Julian Day is [2456179] The Julian Day is [2455813] DATEMATH - Subtracting one date from another = days difference ~~~~~~ 366 ~~~~~~ D:\>datemath 13 09 08 - 12 09 08 The Julian Day is [2456544] The Julian Day is [2456179] DATEMATH - Subtracting one date from another = days difference ~~~~~~ 365 ~~~~~~
And now, we can do someting with it.
@echo off&SETLOCAL :: DELOLDER.cmd days fullpath :: :: For example: :: DELOLDER 14 C:\temp\*.* :: DELOLDER 28 "C:\Log Files\" :: DELOLDER 28 "C:\Log Files\*.LOG" :: note: do not specify the Current Directory :: To use this batch for real, edit the last line below :: i.e. change [ECHO DELETE the file] to [DEL] or [MOVE] or whatever SET v_days_newer=%1 SET v_source=%2 :: get todays date from getdate.cmd CALL GetDate SET yy=%yy:~2,2% :: calculate new date using DateMath.cmd CALL DateMath %yy% %mm% %dd% - %v_days_newer% ECHO Files older than Year: [%v_yy_int%] Month: [%v_mm_str%] Day: [%v_dd_str%] :: Compare each file in the DIR with files that are newer than day X :: and delete all those that don't match (ie are older) FOR /f "tokens=*" %%G IN ('XCOPY %v_source% /L ^| FIND "\"') DO CALL :s_match_older "%%G" goto :eof :s_match_older FOR /f "tokens=*" %%G IN ('XCOPY %v_source% /D:%v_mm_str%-%v_dd_str%-%v_yy_int% /L ^| FIND "\"') DO IF %1=="%%G" (GOTO :eof) ECHO DELETE the file %1
Questions: