gpt4 book ai didi

batch-file - 在批处理文件中查找文件是否早于4小时

转载 作者:行者123 更新时间:2023-12-04 09:55:52 25 4
gpt4 key购买 nike

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

谢谢

最佳答案

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


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




1.日期和时间格式设置

有一些环境变量DATE和TIME,它们在访问时(而不是在批处理开始时)以Windows Region and Language settings格式返回当前日期和时间。国家/地区定义日期和时间格式。

甚至可以在其中定义例如带有DD.MM.YYYY的德国短日期格式(日期和月份的前导零)和带有HH:mm:ss的时间格式(24小时格式的小时,分​​钟和秒的前导零)。但这并不意味着DATE和TIME的值确实在使用这种格式。例如,即使选择了定义为H:mm:ss,ms的德国国家/地区,TIME的格式也为HH:mm:ss,这意味着小时中没有前导零,但分秒和秒,以及时间字符串中的逗号后还没有毫秒。日期字符串也可以带有或不带有工作日,具体取决于区域设置。

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

最好的做法是找出下列批处理文件,这些批处理文件最好在上午10:00之前执行,当前用户在当前计算机上的格式是什么。

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




2.存储介质文件系统

在Windows文件系统上, file times使用两种存储格式:


在使用NTFS的存储介质上,使用 NTFS precision time,这是自凌晨12:00开始经过的64位100纳秒间隔。 1601年1月1日,世界标准时间(UTC)。
在使用FAT,FAT16,FAT32或exFAT的存储介质上,文件时间以 DOS Date Time格式存储,具有两个16位值(分辨率为2秒),并使用当前本地时间。


这意味着对于FAT介质上的文件来说,不可能是奇数秒,但是对于NTFS介质上的文件来说,是不可能的。将最后修改时间为奇数秒的NTFS驱动器上的文件复制到FAT32驱动器,将导致具有相同文件的文件的最后修改时间相差1秒。

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


当前时区
该时区的夏令时,
如果当前时间在夏令时之内,
如果当前启用了夏令时自动调整功能。


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

FAT媒体上的文件时间或多或少地与创建,修改或最后访问时使用本地时间相同,但是请进一步阅读以获取详细信息。



3.时区,夏令时

由于NTFS介质上的文件时间存储在UTC中,但以本地时间显示,因此当前时区和该时区的夏令时对于文件时间比较很重要,尤其是在NTFS和FAT32驱动器上的文件完成时。

但是对于FAT介质上的文件,时区和夏时制设置也可能很重要,具体取决于Windows的版本。请阅读下面的详细信息。



4.自动调整夏令时

夏令时自动调整的设置在默认情况下启用时非常重要,当前设置的时区定义了夏令时调整。

例如,夏令时在欧洲当前处于活动状态。在Windows的时钟设置中禁用此选项会导致NTFS介质上的显示文件时间立即更改-1小时,并且FAT介质上的许多文件也取决于Windows版本。

在比较NTFS和FAT介质上的文件时间时,必须考虑到由夏令时调整引起的1小时时差。



5. Windows版本

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

但是,如何解释FAT介质上的文件时间取决于Windows的版本。在Windows Vista之前的版本中,FAT介质上的文件时间与时区的更改,夏令时设置以及夏令时时间的自动调整无关。在Windows 2000和Windows XP上,文件的最后修改日期/时间是恒定的。

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

例如,在Windows 7计算机上的FAT32驱动器上具有文件夹的公共共享,并通过Windows XP计算机将其连接到该公用文件夹时,这种不同的FAT文件时间管理可能会非常混乱。 Windows 7今天以德语时区显示文件时间为19.09.2015 17:39:08的Windows 7 PC的FAT32驱动器上存储于2015-09-19 17:39:08的最后修改日期,但在2个月内而不用19.09.2015 16:39:08修改,并且Windows XP在连接的Windows 7 PC上今天和将来以文件时间19.09.2015 17:39:08不变地显示同一文件。

比较存储在档案(ZIP,RAR等)中的文件与NTFS或FAT介质上的文件的文件时间确实是一场噩梦。



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

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

以下批处理代码使用在我对 Batch file to delete files older than N days的答复中详细解释的代码。使用以下代码之前,应先阅读此说明。

根据本地Windows PC上文件的DATE和TIME变量的日期/时间格式以及 %~tI返回的日期/时间字符串,可能需要对代码进行一些小的修改。批处理代码的注释行中给出了适当的提示。

@echo off
setlocal EnableExtensions

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 "%DateTime: AM=%" NEQ "%DateTime%" (
set "DateTime=%DateTime: AM=%"
) else if "%DateTime: PM=%" NEQ "%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%" EQU "0" ( if "%Month:~1%" NEQ "" set "Month=%Month:~1%" )
if "%Day:~0,1%" EQU "0" ( if "%Day:~1%" NEQ "" set "Day=%Day:~1%" )
if "%Hour:~0,1%" EQU "0" ( if "%Hour:~1%" NEQ "" set "Hour=%Hour:~1%" )
if "%Minute:~0,1%" EQU "0" ( if "%Minute:~1%" NEQ "" set "Minute=%Minute:~1%" )
if "%Second:~0,1%" EQU "0" ( if "%Second:~1%" NEQ "" 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 2 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添加了有关如何使用Windows Management Instrumentation命令行实用程序 wmic忽略日期和时间格式设置,文件系统和Windows版本的信息。

使用wmic具有日期/时间字符串固定格式的优点,因此批处理代码可在所有Windows计算机上工作,而无需适应本地日期/时间格式。

此外,由于 GetFileTime函数的内部用法(最有可能),Windows版本对于使用wmic也不重要。

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

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

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


+120是CET(欧洲中部时间)+60分钟和+60分钟(用于夏令时)的总和,换句话说,CEST(中欧夏季时间)是+120分钟。

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

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

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

@echo off
setlocal EnableExtensions

rem Get seconds since 1970-01-01 for current date and time.
for /F "tokens=2 delims==." %%T in ('%SystemRoot%\System32\wbem\wmic.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%\System32\wbem\wmic.exe DATAFILE where "name='%DataFile%'" GET LastModified /VALUE`) do echo 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%" EQU "0" ( if "%Month:~1%" NEQ "" set "Month=%Month:~1%" )
if "%Day:~0,1%" EQU "0" ( if "%Day:~1%" NEQ "" set "Day=%Day:~1%" )
if "%Hour:~0,1%" EQU "0" ( if "%Hour:~1%" NEQ "" set "Hour=%Hour:~1%" )
if "%Minute:~0,1%" EQU "0" ( if "%Minute:~1%" NEQ "" set "Minute=%Minute:~1%" )
if "%Second:~0,1%" EQU "0" ( if "%Second:~1%" NEQ "" set "Second=%Second:~1%" )

rem Must use 2 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

关于batch-file - 在批处理文件中查找文件是否早于4小时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6928552/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com