如何比较两个文件的创建日期?

3

使用批处理程序(batch)如何比较两个文件的创建日期,并使用函数isMoreRecentThan(pathToFile1, pathToFile2)返回true或false?

解决方案应该在无管理员权限下运行(特别是不应使用wmic)。


这里有几个问题 - 文件是否在同一个目录中,您想要创建日期还是最后更新日期? - Magoo
你应该提供你的“日期”格式。 - Endoro
命令提示符 != DOS。 - Danny Beckett
@peter:1/ 不,这些文件不在同一个目录下,但我认为这并不重要,因为我有它们的完整路径,如果需要,您可以将它们暂时复制到临时文件夹中进行比较。2/ 我对创建日期感兴趣,但我认为最后更新日期应该是相似的,对吧? ........................ endoro: 请问我如何提供我的日期格式? - Car981
3个回答

2
@ECHO OFF
SETLOCAL
:: files to be compared
SET "filea=c:\mys\oldobj.txt"
SET "fileb=c:\mys\15850492.htm"
:: Create a tempdir
:Tloop
SET tempdir="%temp%\%random%"
IF EXIST %tempdir%* GOTO tloop
MD %tempdir%

MOVE "%filea%" %tempdir%\a >nul
MOVE "%fileb%" %tempdir%\b >NUL
SET file
ECHO.
FOR /f %%i IN ('dir /b /a-d /o-d /tc %tempdir%') DO SET first=%%i
ECHO first file (create date) was %first%
FOR /f %%i IN ('dir /b /a-d /o-d /tw %tempdir%') DO SET first=%%i
ECHO first file (write date) was %first%
MOVE %tempdir%\a "%filea%" >nul
MOVE %tempdir%\b "%fileb%" >nul
RD %tempdir%

ECHO.
ECHO create times=v=v=v=v=v=v=v=v=v=v=v
ECHO.
DIR %filea% %fileb% /od /tc
ECHO.
ECHO write times=v=v=v=v=v=v=v=v=v=v=v
ECHO.
DIR %filea% %fileb% /od /tw

测试结果:(无关行已删节)

filea=c:\mys\oldobj.txt
fileb=c:\mys\15850492.htm

first file (create date) was a
first file (write date) was b

create times=v=v=v=v=v=v=v=v=v=v=v

 Directory of c:\mys

07/07/2012  21:40           788,960 oldobj.txt
07/04/2013  19:06            16,295 15850492.htm

write times=v=v=v=v=v=v=v=v=v=v=v

 Directory of c:\mys

07/04/2013  19:06            16,295 15850492.htm
10/05/2013  14:04           788,960 oldobj.txt

所以,是的,这种方法非常关注文件是否在同一个目录中,因为它依赖于按相关日期对文件进行排序。

而且正如所示,创建日期和最后更新日期可能会有很大变化 - 这取决于文件的用途。甚至可能存在创建日期晚于最后更新日期的情况 - 实际上这是常见的,因为如果文件被复制,新文件就会获得它被创建的日期,但最后更新日期只是原始文件的最后更新日期。


你的回答证明了这种方法需要复制两个文件,因此比其他不需要复制的方法慢... - Aacini
@Aacini - 我是多么喜欢理论胡言乱语啊。你所提到的著名“复制”在哪里? - Magoo
哎呀,我的错误!没有“复制”命令,但有一个MD命令,四个MOVE命令和一个其他方法没有的RD命令。继续理论上的胡言乱语,这种方法避免了比较不同驱动器中文件日期的情况,除非其中一个被复制... ;) - Aacini

2
for /f "tokens=1,2,3 delims=/" %%T in ('forfiles /m file1 /C "cmd /c echo @fdate"') do set date1=%%V%%U%%T
for /f "tokens=1,2,3 delims=/" %%T in ('forfiles /m file2 /C "cmd /c echo @fdate"') do set date2=%%V%%U%%T
if %date2% GTR %date1% *some command here*

你还可以使用@ftime进行更精确的比较。而且,forfiles不是Windows XP和2003的本机命令。如果你不使用更新的操作系统,你需要下载并安装Windows 2003资源工具包。 编辑(适用于XP和2003):
setlocal enabledelayedexpansion
for /f "tokens=1,2,3,4,5,6 delims=/: " %%T in ('for %%a in ^(FILE1^) do echo %%~ta') do (
 if "%%Y" EQU "PM" (
  set /a "hour=%%W+12"
 ) else (
    set hour=%%W
 )
 set time1=%%V%%U%%T!hour!%%Y
 )

 for /f "tokens=1,2,3,4,5,6 delims=/: " %%T in ('for %%a in ^(FILE2^) do echo %%~ta') do (
 if "%%Y" EQU "PM" (
  set /a "hour=%%W+12"
 ) else (
    set hour=%%W
 )
 set time2=%%V%%U%%T!hour!%%Y
 )
 if !time1! GTR !time2! *do something*

 endlocal 

您需要用相关值更改FILE1和FILE2

最后编辑

@echo off


call :isOlder     "C:\test.file1" "C:\test.file2"

goto :eof

:isOlder [%1 path to first file ; %2 path to second file]
    setlocal
    call :get_file_c_time  "%~1" time1
    call :get_file_c_time  "%~2" time2
    if "%time1%" LEQ "%time2%"  ( 
      echo YES 
     ) else (
      echo NO
     )
goto :eof

:get_file_c_time [ %1 path to file; %2 variable to assign value  ]
    set file_path=%~1

    if not exist "%file_path%" echo file %1 does not exist&& exit /b 1

    if "%~2" equ "" echo need a secont parameter && exit /b 2

    setlocal enableDelayedExpansion

    for /f "skip=5 tokens=1,2,3,4,5,6 delims=/:.гчЈз " %%T in ('dir /tc "%file_path%"') do (
     if "%%Y" EQU "PM" (
      set /a "hour=%%W+12"
     ) else (
        set hour=%%W
     )
     set ftime=%%V%%U%%T!hour!%%X
     goto :endfor
    )
:endfor

endlocal & set "%~2=%ftime%"
goto :eof

现在您可以使用:isOlder子程序。


1
抱歉,但 forfiles 显示的是文件的 最后修改日期,而不是 创建日期 - Endoro
你可以在没有使用"wmic"命令的情况下获取"创建日期",但是原帖作者必须提供他的完整日期和时间格式。 - Endoro
@Car981 是的,这是可能的...稍后会处理它。请耐心等待 :) - npocmaka
现在我添加了一个带有子程序的脚本,用于比较两个文件的创建。你可以在你的机器上测试一下,看看是否需要进行调整? - npocmaka
1
我已经有了分钟数 %%X,但这可以修复 :) - Endoro
显示剩余8条评论

2
这是npocmaka答案的最终编辑版本,但稍作修改。我已经将这些Car981的信息引入了代码中:
  • 一个名为isMoreRecentThan(file1,file2)的函数,如果file1比file2更近,则返回true,否则返回false
  • dir中的日期格式为17/05/2013 15:01
isMoreRecentThan子程序返回一个%ERRORLEVEL%,如果第一个文件比第二个文件更近,则等于1(true),在任何其他情况下都为0,包括任何文件不存在的情况。
@echo off

call :isMoreRecentThan "C:\path1\file1.ext" "C:\path2\file2.ext"
if %errorlevel% equ 1 echo File1 is more recent than File2
goto :eof


:isMoreRecentThan [%1=path to first file ; %2=path to second file]
setlocal
call :get_file_c_time "%~1" time1
call :get_file_c_time "%~2" time2
set exitCode=0
if %time1% neq 0 if %time2% neq 0 if "%time1%" gtr "%time2%" set exitCode=1
exit /B %exitCode%


:get_file_c_time [ %1 path to file; %2 variable to assign value  ]
set %2=0
if not exist %1 exit /B
for /F "skip=5 tokens=1-5 delims=/: " %%a in ('dir /TC %1') do (
   set %2=%%c%%b%%a%%d%%e
   exit /B
)

+1,这样更整洁。但我仍然希望能够更独立于时间设置。可能需要检查注册表才能实现。 - npocmaka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接