Here is the batch code to create for all files in current directory except the batch file and the created log file the output in CSV format with the columns:
- Name
- Modification Time
- Creation Time
- Days Old
The batch code with additional comments.
@echo off
setlocal
set "LogFile=temp_log.txt"
call :jdate tnow "%date%"
(
echo "Name","Modification Time","Creation Time","Days Old"
for %%F in (*) do call :GetDiffTime "%%F"
) >"%LogFile%"
endlocal
goto :EOF
:GetDiffTime
rem Do not add this batch file in log file.
if "%~1" == "%~nx0" goto :EOF
rem Do not add log file in log file.
if "%~1" == "%LogFile%" goto :EOF
rem Determine difference in days of last modification
rem date of current file with current date in days.
call :ftime tfile "%~1"
set /A diff=tnow-tfile
rem Get creation date of current file from output of DIR.
rem The tokens are:
rem a ... creation date
rem b ... creation time
rem c ... file size in bytes
rem d ... file name without path
for /F "tokens=1-3*" %%a in ('dir /t:c "%~1"') do (
if "%%d" == "%~1" (
echo "%~1","%~t1","%%~a %%~b",%diff%
goto :EOF
)
)
goto :EOF
::-----------------------------------------------------------------------------------
::-- Functions start below here
::-----------------------------------------------------------------------------------
:ftime JD filename attr -- returns the file time in julian days
:: -- JD [out] - valref file time in julian days
:: -- attr [in,opt] - time field to be used, creation/last-access/last-write, see 'dir /?', i.e. /tc, /ta, /tw, default is /tw
:$created 20060101 :$changed 20090322 :$categories DateAndTime
:$source http://www.dostips.com
SETLOCAL
set file=%~2
set attr=%~3
if not defined attr (
call :jdate JD "- %~t2"
) ELSE (
for /f %%a in ('"dir %attr% /-c "%file%"|findstr "^^[0-9]""') do call :jdate JD "%%a"
)
( ENDLOCAL & REM RETURN VALUES
IF "%~1" NEQ "" (SET %~1=%JD%) ELSE (echo.%JD%)
)
EXIT /b
:jdate JD DateStr -- converts a date string to julian day number with respect to regional date format
:: -- JD [out,opt] - julian days
:: -- DateStr [in,opt] - date string, e.g. "03/31/2006" or "Fri 03/31/2006" or "31.3.2006"
:$reference http://groups.google.com/group/alt.msdos.batch.nt/browse_frm/thread/a0c34d593e782e94/50ed3430b6446af8#50ed3430b6446af8
:$created 20060101 :$changed 20080219
:$source http://www.dostips.com
SETLOCAL
set DateStr=%~2&if "%~2"=="" set DateStr=%date%
for /f "skip=1 tokens=2-4 delims=(-)" %%a in ('"echo.|date"') do (
for /f "tokens=1-3 delims=/.- " %%A in ("%DateStr:* =%") do (
set %%a=%%A&set %%b=%%B&set %%c=%%C
)
)
set /a "yy=10000%yy% %%10000,mm=100%mm% %% 100,dd=100%dd% %% 100"
rem For German Windows comment line above and uncomment line below.
rem set /a "yy=10000%JJ% %%10000,mm=100%MM% %% 100,dd=100%TT% %% 100"
set /a JD=dd-32075+1461*(yy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yy+4900+(mm-14)/12)/100)/4
ENDLOCAL & IF "%~1" NEQ "" (SET %~1=%JD%) ELSE (echo.%JD%)
EXIT /b
Note:
Function jdate
is designed for dates like 12/30/2015
or Wed 12/30/2015
or 30.12.2015
, but does nevertheless not work for German Windows as output of command date is not dd-mm-yy
as expected by code. Command date outputs on German Windows TT-MM-JJ
as date format mask. Users of German Windows should read the two rem lines near end of batch script added by me.
Example:
Command DIR executed in directory C:\Temp
outputs on German Windows:
15.08.2015 22:01 2.286 about.txt
27.12.2014 21:28 8.871 help for.txt
15.03.2015 17:41 2.372 RegJump.bat
04.01.2016 12:24 2.937 Test.bat
10.11.2015 17:44 9.003.869 TV Manual.pdf
Running Test.bat
on German Windows with the code above adapted to German Windows results in file C:\Temp\temp_log.txt
with contents:
"Name","Modification Time","Creation Time","Days Old"
"about.txt","15.08.2015 22:01","04.01.2016 12:30",142
"help for.txt","27.12.2014 21:28","27.12.2014 21:28",373
"RegJump.bat","15.03.2015 17:41","15.03.2015 15:23",295
"TV Manual.pdf","10.11.2015 17:44","10.11.2015 17:40",55
File about.txt
has a creation date newer than last modification date because just copied to directory C:\Temp
for testing the batch file and therefore creation date was the current date on making this copy.
Here is an enhanced version of batch code above with following differences:
- Produces correct output even with
@echo on
in first line or without turning off command output.
- Runs recursive for all files in current directory and all subdirectories. The output file contains each file name with full path. Remove
/R
in line 6 to process only files in current directory.
- Works also for file and folder names containing characters with special meaning in batch processing like folder name
HLA Compiler (masm32+)
which contains an opening and a closing parenthesis.
This batch file writes the file names always with full path into the output file even on running on current directory only. But this can be changed in echo line in subroutine GetDiffTime
by using for example %~nx1
instead of %~1
which required improvements in subroutine ftime
.
@echo off
setlocal
set "LogFile=%CD%\temp_log.txt"
call :jdate tnow "%date%"
echo "Name","Modification Time","Creation Time","Days Old">"%LogFile%"
for /R %%F in (*) do call :GetDiffTime "%%~fF"
endlocal
goto :EOF
:GetDiffTime
rem Do not add this batch file in log file.
if "%~1" == "%~f0" goto :EOF
rem Do not add log file in log file.
if /I "%~1" == "%LogFile%" goto :EOF
rem Determine difference in days of last modification
rem date of current file with current date in days.
call :ftime tfile "%~1"
set /A diff=tnow-tfile
rem Get creation date of current file from output of DIR.
rem The tokens are:
rem a ... creation date
rem b ... creation time
rem c ... file size in bytes
rem d ... file name without path
for /F "tokens=1-3*" %%a in ('dir /t:c "%~1"') do (
if "%%d" == "%~nx1" (
>>"%LogFile%" echo "%~1","%~t1","%%~a %%~b",%diff%
goto :EOF
)
)
goto :EOF
::-----------------------------------------------------------------------------------
::-- Functions start below here
::-----------------------------------------------------------------------------------
:ftime JD filename attr -- returns the file time in julian days
:: -- JD [out] - valref file time in julian days
:: -- attr [in,opt] - time field to be used, creation/last-access/last-write, see 'dir /?', i.e. /tc, /ta, /tw, default is /tw
:$created 20060101 :$changed 20090322 :$categories DateAndTime
:$source http://www.dostips.com
SETLOCAL EnableDelayedExpansion
set "file=%~2"
set "attr=%~3"
if not defined attr (
call :jdate JD "- %~t2"
) ELSE (
for /f %%a in ('"dir %attr% /-c "!file!"|findstr "^^[0-9]""') do call :jdate JD "%%a"
)
( ENDLOCAL & REM RETURN VALUES
IF "%~1" NEQ "" (SET "%~1=%JD%") ELSE (echo.%JD%)
)
EXIT /b
:jdate JD DateStr -- converts a date string to julian day number with respect to regional date format
:: -- JD [out,opt] - julian days
:: -- DateStr [in,opt] - date string, e.g. "03/31/2006" or "Fri 03/31/2006" or "31.3.2006"
:$reference http://groups.google.com/group/alt.msdos.batch.nt/browse_frm/thread/a0c34d593e782e94/50ed3430b6446af8#50ed3430b6446af8
:$created 20060101 :$changed 20080219
:$source http://www.dostips.com
SETLOCAL
set "DateStr=%~2" & if "%~2"=="" set "DateStr=%date%"
for /f "skip=1 tokens=2-4 delims=(-)" %%a in ('"echo.|date"') do (
for /f "tokens=1-3 delims=/.- " %%A in ("%DateStr:* =%") do (
set "%%a=%%A" & set "%%b=%%B" & set "%%c=%%C"
)
)
set /a "yy=10000%yy% %%10000,mm=100%mm% %% 100,dd=100%dd% %% 100"
rem For German Windows comment line above and uncomment line below.
rem set /a "yy=10000%JJ% %%10000,mm=100%MM% %% 100,dd=100%TT% %% 100"
set /a JD=dd-32075+1461*(yy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yy+4900+(mm-14)/12)/100)/4
ENDLOCAL & IF "%~1" NEQ "" (SET %~1=%JD%) ELSE (echo.%JD%)
EXIT /b