在批处理文件中找出文件是否超过 4 小时 [英] Find out if file is older than 4 hours in Batch file

查看:29
本文介绍了在批处理文件中找出文件是否超过 4 小时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很简单,我如何确定文件夹中的特定文件是否超过 X 小时?文件名和位置将始终相同.

Quite simply, how would I find out if a specific file in a folder is older than X hours? The file name and location will always be the same.

谢谢

推荐答案

在将文件时间与批处理代码进行比较时,必须考虑以下几点:

On comparing file times with batch code following must be taken into account:

  1. 日期和时间格式设置
  2. 存储介质的文件系统
  3. 时区,夏令时
  4. 自动调整夏令时
  5. Windows 版本


  1. 日期和时间格式设置


有环境变量DATETIME,它们访问(而不是批处理执行开始时)返回当前 日期和时间的格式取决于 Windows 区域和语言设置.国家/地区定义日期和时间格式.


There are the environment variables DATE and TIME which on access (and not on start of batch execution) return current date and time in a format depending on Windows Region and Language settings. The country defines the date and time format.

甚至可以在那里定义例如带有 DD.MM.YYYY(带前导零的日期和月份)的德国短日期格式和带有 HH:mm:ss 的时间格式(24 小时格式,时、分和秒前导零).但这并不意味着DATETIME 的值真的使用这种格式.例如,TIME 的格式为 H:mm:ss,ms,即使在定义了 HH:mm:ss 的情况下,也选择了德国国家/地区,这意味着小时没有前导零,但在分钟和秒上,以及时间字符串中逗号后的毫秒数.根据地区设置,日期字符串也可以带或不带工作日.

It is even possible there to define for example for German short date format with DD.MM.YYYY (day and month with leading zero) and time format with HH:mm:ss (24 hour format with leading zero for hour, minute and second). But this does not mean that value of DATE and TIME are really using this format. For example TIME is in format H:mm:ss,ms when having selected a German country even with HH:mm:ss defined which means no leading zero on hour, but on minute and second, and additionally milliseconds after a comma in time string. The date string can be also with or without weekday depending on region settings.

还有一个模式 %~t 来获取目录或文件的最后修改日期和时间.在命令提示符窗口中运行 call/?for/? 并阅读为这两个命令显示的所有帮助页面以了解详细信息.%~t 返回的日期和时间字符串的格式以及显示在命令 DIR 的输出中也取决于 Windows 区域设置,但通常不等于格式变量 DATETIME.文件或目录的最后修改时间通常返回日期/时间字符串中没有第二个值.

And there is the pattern %~t to get last modification date and time of a directory or file. Run in a command prompt window call /? and for /? and read all help pages displayed for those two commands for details. The format of the date and time string returned by %~t as well as displayed on output of command DIR depends also on Windows region settings, but is usually not equal the format of variables DATE and TIME. The time of last modification time of a file or directory is usually returned without second value in date/time string.

最好在上午 10:00 之前通过以下批处理文件找出当前用户在当前机器上的格式是什么.

Best is to find out with following batch file best executed before 10:00 AM what are the formats on current machine for current user.

@echo off
echo Current date/time: %DATE% %TIME%
for %%I in ("%~f0") do echo Batch file time:   %%~tI
pause


  1. 存储介质的文件系统


在 Windows 文件系统上,两种存储格式用于 文件时间:

  • 在使用 NTFS 的存储介质上,NTFS 精确时间 使用它是自上午 12:00 以来经过的 100 纳秒间隔的 64 位数字1601 年 1 月 1 日协调世界时 (UTC).

  • On storage media using NTFS the NTFS precision time is used which is a 64-bit number of 100-nanosecond intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC).

在使用 FAT、FAT16、FAT32 或 exFAT 的存储介质上,文件时间使用 DOS 日期时间 格式,具有两个 16 位值,分辨率为 2 秒,并使用当前本地时间.

On storage media using FAT, FAT16, FAT32 or exFAT the file times are stored using DOS Date Time format with two 16-bit values with a resolution of 2 seconds and using current local time.

这意味着 FAT 媒体上的文件不可能出现奇数秒,但在 NTFS 媒体上.将上次修改时间为奇数秒的 NTFS 驱动器上的文件复制到 FAT32 驱动器会导致上次修改时间相差 1 秒的相同文件.

This means an odd second is not possible for a file on FAT media, but on NTFS media. Copying a file on an NTFS drive with an odd second in last modification time to a FAT32 drive results in having identical files with 1 second difference in last modification time.

NTFS 媒体上的文件时间以 UTC 存储.因此,%~t 或命令 DIR 返回的内容以及例如在 Windows 资源管理器中显示的内容取决于

The file times on NTFS media are stored in UTC. So what is returned by %~t or command DIR as well as what is displayed for example in Windows Explorer depends on

  • 当前时区,
  • 该时区的夏令时,
  • 如果当前时间在夏令时期间,
  • 以及当前是否启用了夏令时的自动调整.

更改这 4 个参数中的任何一个都会立即更改 NTFS 存储介质上文件和目录的所有显示文件时间.

Changing any of those 4 parameters results in an immediate change of ALL displayed file times of files and directories on NTFS storage media.

FAT 媒体上的文件时间在创建、修改或上次访问时使用本地时间或多或少是恒定的,但请进一步阅读以了解详细信息.

File times on FAT media are more or less constant as using local time on creation, modification or last access, but read further for details.

  1. 时区,夏令时


由于 NTFS 媒体上的文件时间以 UTC 存储,但以本地时间显示,因此当前时区和该时区的夏令时对于文件时间比较很重要,尤其是对 NTFS 和 FAT32 驱动器上的文件进行比较时.


As file times on NTFS media are stored in UTC, but displayed in local time, the current time zone and the daylight saving time for this time zone are important for file time comparisons, especially when done for files on NTFS and FAT32 drives.

而且对于 FAT 媒体上的文件,时区和夏令时设置可能很重要,具体取决于 Windows 版本.阅读下文了解详情.

But also for files on a FAT media, the time zone and daylight saving time settings could be important depending on version of Windows. Read below for details.

  1. 自动调整夏令时


有自动调整夏令时的设置,这在默认启用时变得很重要,当前设置的时区定义了夏令时调整.


There is the setting for automatic adjustment for daylight saving time which becomes important when being enabled as by default and currently set time zone defines a daylight saving time adjustment.

例如,夏令时目前在欧洲有效.在 Windows 的时钟设置中禁用此选项会导致 NTFS 媒体上显示的文件时间立即更改 -1 小时,并且 FAT 媒体上的许多文件取决于 Windows 版本.

For example daylight saving time is active currently in Europe. Disabling this option in clock settings of Windows results in an immediate change of the displayed file times on NTFS media by -1 hour, and also many files on FAT media depending on version of Windows.

在比较 NTFS 和 FAT 媒体上的文件时间时,必须考虑夏令时调整导致的 1 小时时差.

This 1 hour time difference caused by the daylight saving time adjustment must be taken into account on comparing file times on NTFS and FAT media.

  1. Windows 版本


所有 Windows NT 版本都支持 NTFS.在支持 NTFS 的所有 Windows 版本上,文件和目录的文件时间行为是相同的.


NTFS is supported by all Windows NT versions. File times behavior is equal for files and directories on all Windows versions supporting NTFS.

但是如何解释 FAT 媒体上的文件时间取决于 Windows 版本.在 Windows Vista 之前,FAT 介质上的文件时间与时区更改、夏令时设置和夏令时自动调整无关.文件的最后修改日期/时间在 Windows 2000 和 Windows XP 上保持不变.

But how file times on FAT media are interpreted depends on version of Windows. Prior Windows Vista the file times on FAT media are independent on change of time zone, daylight saving time setting and automatic adjustment of daylight saving time. Last modification date/time of a file is constant on Windows 2000 and Windows XP.

但是在 Windows Vista 和更高版本上,FAT 介质上显示的文件时间取决于夏令时和夏令时的自动调整.时区并不直接重要.选择当前使用的另一个时区不会像更改 NTFS 媒体上的文件那样更改 FAT 媒体上文件的显示文件时间.但是如果当前时间在活动时区的夏令时范围内并且启用了夏令时自动调整并且文件或目录的本地时间在夏令时范围内,则Windows Vista会添加+1小时然后.在标准时间内在 FAT 驱动器上最后修改的文件在一年中保持不变;仅显示在 DST 期间最后修改的文件,是否显示 +1 小时,具体取决于启用了自动 DST 调整的当前时间.

But on Windows Vista and later the displayed file times on FAT media depend on daylight saving time and automatic adjustment for daylight saving time. The time zone does not directly matter. Selecting another time zone as currently used does not change the displayed file times of files on FAT media as it does for files on NTFS media. But if current time is within daylight saving time period of the active time zone and the automatic adjustment for daylight saving time is enabled and the local time of the file or directory is within the daylight saving time period, +1 hour is added by Windows Vista and later. The files last modified on FAT drives within standard time are constant over the year; just the files last modified within DST period are displayed with or without +1 hour depending on current time with enabled automatic DST adjustment.

例如,当在 Windows 7 机器上的 FAT32 驱动器上共享文件夹并使用 Windows XP 机器连接到该公共文件夹时,这种不同的 FAT 文件时间管理可能会非常混乱.上次修改时间为 2015-09-19 17:39:08 存储在 Windows 7 PC 上的 FAT32 驱动器上的文件今天由 Windows 7 显示,文件时间为德国时区,文件时间为 19.09.2015 17:39:08,但在 2 个月后未使用 19.09.2015 16:39:08 进行修改,Windows XP 在今天和未来连接的 Windows 7 PC 上显示相同的文件,文件时间为 19.09.2015 17:39:08.

That different FAT file time management can be extremely confusing when having for example a public share of a folder on a FAT32 drive on a Windows 7 machine and being connected to this public folder with a Windows XP machine. A file last modified on 2015-09-19 17:39:08 stored on FAT32 drive on Windows 7 PC is displayed today by Windows 7 with German time zone with file time 19.09.2015 17:39:08, but in 2 months although not modified with 19.09.2015 16:39:08, and Windows XP displays same file on connected Windows 7 PC today and in future constant with file time 19.09.2015 17:39:08.

将存档(ZIP、RAR、...)中存储的文件的文件时间与 NTFS 或 FAT 媒体上的文件进行比较真的是一场噩梦.

Comparing file times of files stored in archives (ZIP, RAR, ...) with files on NTFS or FAT media can be really a nightmare.

  1. 比较文件时间和当前时间


对于将文件的最后修改时间与当前时间进行比较的任务,只需考虑日期和时间格式设置就足够了.


For this task comparing last modification time of a file with current time, it should be enough to just take date and time format settings into account.

下面的批处理代码使用了我在 批处理文件中的回答中详细解释的代码,用于删除超过 N 天的文件.在使用下面的代码之前应该阅读这个解释.

The batch code below uses code explained in detail in my answer on Batch file to delete files older than N days. This explanation should be read before using the code below.

取决于变量 DATETIME 的日期/时间格式以及 %~tI 为文件返回的日期/时间字符串本地 Windows PC,可能需要对代码进行小的修改.批代码注释行中给出了相应的提示.

Depending on date/time format of the variables DATE and TIME and date/time string returned by %~tI for the file on local Windows PC, it might be necessary to make small modifications to code. Appropriate hints are given in the comment lines of batch code.

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem Get seconds since 1970-01-01 for current date and time.
rem From date string only the last 10 characters are passed to GetSeconds
rem which results in passing dd/mm/yyyy or dd.mm.yyyy in expected format
rem to this subroutine independent on date string of environment variable
rem DATE is with or without abbreviated weekday at beginning.
call :GetSeconds "%DATE:~-10% %TIME%"

rem Subtract seconds for 4 hours (4 * 3600 seconds) from seconds value.
set /A "CompareTime=Seconds-4*3600"

rem Define batch file itself as the file to compare time by default.
set "FileToCompareTime=%~f0"

rem If batch file is started with a parameter and the parameter
rem specifies an existing file (or directory), compare with last
rem modification date of this file.
if not "%~1" == "" if exist "%~1" set "FileToCompareTime=%~1"

rem Get seconds value for the specified file.
for %%F in ("%FileToCompareTime%") do call :GetSeconds "%%~tF:0"

rem Compare the two seconds values.
if %Seconds% LSS %CompareTime% (
    echo File %FileToCompareTime% was last modified for more than 4 hours.
) else (
    echo File %FileToCompareTime% was last modified within the last 4 hours.
)
endlocal
goto :EOF


rem No validation is made for best performance. So make sure that date
rem and hour in string is in a format supported by the code below like
rem MM/DD/YYYY hh:mm:ss or M/D/YYYY h:m:s for English US date/time.

:GetSeconds
rem If there is " AM" or " PM" in time string because of using 12 hour
rem time format, remove those 2 strings and in case of " PM" remember
rem that 12 hours must be added to the hour depending on hour value.
set "DateTime=%~1"
set "Add12Hours=0"
if not "%DateTime: AM=%" == "%DateTime%" (
    set "DateTime=%DateTime: AM=%"
) else if not "%DateTime: PM=%" == "%DateTime%" (
    set "DateTime=%DateTime: PM=%"
    set "Add12Hours=1"
)

rem Get year, month, day, hour, minute and second from first parameter.
for /F "tokens=1-6 delims=,-./: " %%A in ("%DateTime%") do (
    rem For English US date MM/DD/YYYY or M/D/YYYY
    set "Day=%%B" & set "Month=%%A" & set "Year=%%C"
    rem For German date DD.MM.YYYY or English UK date DD/MM/YYYY
    rem set "Day=%%A" & set "Month=%%B" & set "Year=%%C"
    set "Hour=%%D" & set "Minute=%%E" & set "Second=%%F"
)

rem Remove leading zeros from the date/time values or calculation could be wrong.
if "%Month:~0,1%"  == "0" if not "%Month:~1%"  == "" set "Month=%Month:~1%"
if "%Day:~0,1%"    == "0" if not "%Day:~1%"    == "" set "Day=%Day:~1%"
if "%Hour:~0,1%"   == "0" if not "%Hour:~1%"   == "" set "Hour=%Hour:~1%"
if "%Minute:~0,1%" == "0" if not "%Minute:~1%" == "" set "Minute=%Minute:~1%"
if "%Second:~0,1%" == "0" if not "%Second:~1%" == "" set "Second=%Second:~1%"

rem Add 12 hours for time range 01:00:00 PM to 11:59:59 PM,
rem but keep the hour as is for 12:00:00 PM to 12:59:59 PM.
if %Add12Hours% == 1 if %Hour% LSS 12 set /A Hour+=12

set "DateTime="
set "Add12Hours="

rem Must use two arrays as more than 31 tokens are not supported
rem by command line interpreter cmd.exe respectively command FOR.
set /A "Index1=Year-1979"
set /A "Index2=Index1-30"

if %Index1% LEQ 30 (
    rem Get number of days to year for the years 1980 to 2009.
    for /F "tokens=%Index1% delims= " %%Y in ("3652 4018 4383 4748 5113 5479 5844 6209 6574 6940 7305 7670 8035 8401 8766 9131 9496 9862 10227 10592 10957 11323 11688 12053 12418 12784 13149 13514 13879 14245") do set "Days=%%Y"
    for /F "tokens=%Index1% delims= " %%L in ("Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N") do set "LeapYear=%%L"
) else (
    rem Get number of days to year for the years 2010 to 2038.
    for /F "tokens=%Index2% delims= " %%Y in ("14610 14975 15340 15706 16071 16436 16801 17167 17532 17897 18262 18628 18993 19358 19723 20089 20454 20819 21184 21550 21915 22280 22645 23011 23376 23741 24106 24472 24837") do set "Days=%%Y"
    for /F "tokens=%Index2% delims= " %%L in ("N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N") do set "LeapYear=%%L"
)

rem Add the days to month in year.
if "%LeapYear%" == "N" (
    for /F "tokens=%Month% delims= " %%M in ("0 31 59 90 120 151 181 212 243 273 304 334") do set /A "Days+=%%M"
) else (
    for /F "tokens=%Month% delims= " %%M in ("0 31 60 91 121 152 182 213 244 274 305 335") do set /A "Days+=%%M"
)

rem Add the complete days in month of year.
set /A "Days+=Day-1"

rem Calculate the seconds which is easy now.
set /A "Seconds=Days*86400+Hour*3600+Minute*60+Second"

rem Exit this subroutine.
goto :EOF

rojo 添加了有关如何使用 wmic - Windows Management Instrumentation 命令行实用程序.

rojo added information on how date and time format settings, file system and Windows version can be ignored by using wmic - the Windows Management Instrumentation command-line utility.

使用 wmic 的优点是日期/时间字符串格式固定,因此批处理代码适用于所有 Windows 计算机,无需适应本地日期/时间格式.

Using wmic has the advantage of fixed format for the date/time strings and therefore the batch code works on all Windows computers without adaptations to local date/time format.

Windows 的版本也与使用 wmic 无关,因为 GetFileTime 函数(最有可能).

Also version of Windows does not matter on using wmic because of internal usage of GetFileTime function (most likely).

文件系统仅在评估本地时间/文件时间与 UTC 的分钟偏移量时才变得重要.命令 wmic 在 FAT 驱动器上返回 +*** 分钟偏移量到 UTC 而分钟偏移量对于 NTFS 驱动器上文件的最后修改文件时间是正确的.

The file system becomes only important on evaluating also minutes offset of local time / file time to UTC. Command wmic returns on FAT drives just +*** for the minutes offset to UTC while the minutes offset is correct for the last modification file time of a file on an NTFS drive.

NTFS 和 FAT32 驱动器上相同文件的示例:

Example for same file on NTFS and FAT32 drive:

NTFS:  20071011192622.000000+120
FAT32: 20071011192622.000000+***

+120 是 CET(中欧时间)+60 分钟和有效夏令时 +60 分钟的总和,换言之,CEST(中欧夏令时)+120 分钟.

+120 is sum of +60 minutes for CET (Central European Time) and +60 minutes for active daylight saving time, or in other words +120 minutes for CEST (Central European Summer Time).

因此,下面的批处理代码不会评估与 UTC 的分钟偏移量,这在将文件的最后修改文件时间与当前本地时间进行比较时不需要.

Therefore the batch code below does not evaluate the minutes offset to UTC which is not needed on comparing last modification file time of a file with current local time.

此外,必须在 wmic 命令行中始终使用完整路径指定文件名.仅指定当前目录中文件的文件名或具有相对路径的文件名是行不通的.并且每个反斜杠必须在带有路径的文件名中多一个反斜杠转义.

Further the file name must be specified always with full path in wmic command line. Just specifying the file name for a file in current directory or a file name with relative path does not work. And each backslash must be escaped with one more backslash in file name with path.

使用 wmic 的主要缺点是速度.根据Process Monitor<,上述批处理代码在我的计算机上需要大约 50 毫秒才能完成/a> log(多次运行的平均值).下面的批处理代码两次调用 wmic 完成同一任务需要大约 1500 毫秒(也是平均值).因此,如果可以避免,在大量文件上使用 wmic 绝对不是一个好主意,因为本地日期/时间格式是已知的.

The main disadvantage on using wmic is the speed. The batch code above needs on my computer about 50 ms to finish according to Process Monitor log (average of several runs). The batch code below calling wmic twice needs for the same task about 1500 ms to finish (also an average value). Therefore using wmic on a large number of files is definitely not a good idea if it can be avoided because local date/time format is known.

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem Get seconds since 1970-01-01 for current date and time.
for /F "tokens=2 delims==." %%T in ('%SystemRoot%System32wbemwmic.exe OS GET LocalDateTime /VALUE') do call :GetSeconds %%T

rem Subtract seconds for 4 hours (4 * 3600 seconds) from seconds value.
set /A "CompareTime=Seconds-4*3600"

rem Define batch file itself as the file to compare time by default.
set "FileToCompareTime=%~f0"

rem If batch file is started with a parameter and the parameter
rem specifies an existing file (or directory), compare with last
rem modification date of this file.
if not "%~1" == "" if exist "%~f1" set "FileToCompareTime=%~f1"

rem Get seconds value for the specified file.
set "DataFile=%FileToCompareTime:=\%"
for /F "usebackq tokens=2 delims==." %%T in (`%SystemRoot%System32wbemwmic.exe DATAFILE where "name='%DataFile%'" GET LastModified /VALUE`) do call :GetSeconds %%T

rem Compare the two seconds values.
if %Seconds% LSS %CompareTime% (
    echo File %FileToCompareTime% was last modified for more than 4 hours.
) else (
    echo File %FileToCompareTime% was last modified within the last 4 hours.
)
endlocal
goto :EOF


rem Date/time format used by the command line utility of Windows
rem Management Instrumentation is always YYYYMMDDHHmmss with a
rem dot and a 6 digit microsecond value and plus/minus 3 digit
rem time offset to UTC in minutes independent on region and
rem language settings. Microsecond is always 000000 for a file
rem time. The minutes offset including time zone offset and
rem current daylight saving time offset is returned for a file
rem time only for a file on an NTFS drive. Minutes offset is
rem +*** for a file on a FAT drive (at least on Windows XP).

:GetSeconds
rem Get year, month, day, hour, minute and second from first parameter.
set "DateTime=%~1"
set "Year=%DateTime:~0,4%"
set "Month=%DateTime:~4,2%"
set "Day=%DateTime:~6,2%"
set "Hour=%DateTime:~8,2%"
set "Minute=%DateTime:~10,2%"
set "Second=%DateTime:~12,2%"
rem echo Date/time is: %Year%-%Month%-%Day% %Hour%:%Minute%:%Second%

rem Remove leading zeros from the date/time values or calculation could be wrong.
if %Month:~0,1%  == 0 set "Month=%Month:~1%"
if %Day:~0,1%    == 0 set "Day=%Day:~1%"
if %Hour:~0,1%   == 0 set "Hour=%Hour:~1%"
if %Minute:~0,1% == 0 set "Minute=%Minute:~1%"
if %Second:~0,1% == 0 set "Second=%Second:~1%"

rem Must use two arrays as more than 31 tokens are not supported
rem by command line interpreter cmd.exe respectively command FOR.
set /A "Index1=Year-1979"
set /A "Index2=Index1-30"

if %Index1% LEQ 30 (
    rem Get number of days to year for the years 1980 to 2009.
    for /F "tokens=%Index1% delims= " %%Y in ("3652 4018 4383 4748 5113 5479 5844 6209 6574 6940 7305 7670 8035 8401 8766 9131 9496 9862 10227 10592 10957 11323 11688 12053 12418 12784 13149 13514 13879 14245") do set "Days=%%Y"
    for /F "tokens=%Index1% delims= " %%L in ("Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N") do set "LeapYear=%%L"
) else (
    rem Get number of days to year for the years 2010 to 2038.
    for /F "tokens=%Index2% delims= " %%Y in ("14610 14975 15340 15706 16071 16436 16801 17167 17532 17897 18262 18628 18993 19358 19723 20089 20454 20819 21184 21550 21915 22280 22645 23011 23376 23741 24106 24472 24837") do set "Days=%%Y"
    for /F "tokens=%Index2% delims= " %%L in ("N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N") do set "LeapYear=%%L"
)

rem Add the days to month in year.
if "%LeapYear%" == "N" (
    for /F "tokens=%Month% delims= " %%M in ("0 31 59 90 120 151 181 212 243 273 304 334") do set /A "Days+=%%M"
) else (
    for /F "tokens=%Month% delims= " %%M in ("0 31 60 91 121 152 182 213 244 274 305 335") do set /A "Days+=%%M"
)

rem Add the complete days in month of year.
set /A "Days+=Day-1"

rem Calculate the seconds which is easy now.
set /A "Seconds=Days*86400+Hour*3600+Minute*60+Second"

rem Exit this subroutine.
goto :EOF

这篇关于在批处理文件中找出文件是否超过 4 小时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆