Windows 如何在批处理文件中获取一年中的某一天
如何从Windows批处理文件中的当前日期获取一年中的某一天 我试过了Windows 如何在批处理文件中获取一年中的某一天,windows,date,batch-file,Windows,Date,Batch File,如何从Windows批处理文件中的当前日期获取一年中的某一天 我试过了 SET /A dayofyear=(%Date:~0,2%*30.5)+%Date:~3,2% 但它不适用于闰年,它总是在几天内关闭。我不想使用任何第三方可执行文件。如果您想要儒略日编号,可以使用上一链接中给出的方法。然而,“一年中的某一天”只是一个介于1和365之间的数字(闰年为366)。下面的批处理文件将正确计算它: @echo off setlocal EnableDelayedExpansion set /A i
SET /A dayofyear=(%Date:~0,2%*30.5)+%Date:~3,2%
但它不适用于闰年,它总是在几天内关闭。我不想使用任何第三方可执行文件。如果您想要儒略日编号,可以使用上一链接中给出的方法。然而,“一年中的某一天”只是一个介于1和365之间的数字(闰年为366)。下面的批处理文件将正确计算它:
@echo off
setlocal EnableDelayedExpansion
set /A i=0, sum=0
for %%a in (31 28 31 30 31 30 31 31 30 31 30 31) do (
set /A i+=1
set /A accum[!i!]=sum, sum+=%%a
)
set /A month=1%Date:~0,2%-100, day=1%Date:~3,2%-100, yearMOD4=%Date:~6,4% %% 4
set /A dayOfYear=!accum[%month%]!+day
if %yearMOD4% equ 0 if %month% gtr 2 set /A dayOfYear+=1
echo %dayOfYear%
注意:这取决于日期格式MM/DD/YYYY
编辑2020/08/10:添加了更好的方法
我修改了这个方法,现在它使用wmic
来获取日期。新方法也缩短了,但并不简单;)代码>
:
@echo off
setlocal
set "daysPerMonth=0 31 28 31 30 31 30 31 31 30 31 30"
for /F "tokens=1-3" %%a in ('wmic Path Win32_LocalTime Get Day^,Month^,Year') do (
set /A "dayOfYear=%%a, month=%%b, leap=!(%%c%%4)*(((month-3)>>31)+1)" 2>NUL
)
set /A "i=1, dayOfYear+=%daysPerMonth: =+(((month-(i+=1))>>31)+1)*%+leap"
echo %dayOfYear%
@Aacini’s有两个弱点(尽管它足以满足许多应用,毕竟它是一个很好的方法!):
MM/DD/YYYY
,但%date%
依赖于区域设置李>
中的/l%%l,这将使用可编辑循环中的圈数年数强>
@echo off&setlocal enabledelayedexpansion&set“\u cmd=Get Day^,Month^,Year^”
对于(2020 4 2100)中的/l%%l,请设置“\u数组\u闰年\u=!\ u数组\u闰年\u!%%l,”
对于/f“tokens=1-3delims=“%%a in('wmic Path Win32_LocalTime!_cmd!^ findstr/r“[0-9]”)do(
设置“\u yy=%%c”&设置“\u mm=0%%b”&设置“\u dd=0%%a”&设置“\u mm=!\u mm:~-2!”&设置“\u dd=!\u dd:~-2!”&设置日期=!\u yy!\u dd!”)
回声_数组(闰年)(年)|findstr/lic:“!”日期:~0,4!“>nul&&(设置“闰年”29和设置“闰年”=366”);(设置“闰年”28和设置“闰年”=365”)
设置“\u mm\u dd\u year\u=01-31,02-!\u leap\u!”,03-31,04-30,05-31,06-30,07-31,08-31,09-30,10-31,11-30,12-31”&设置/a“\u cnt=0”和设置/a“\u loop=!\u mm!*6”
(对于(0 6!循环!)中的/l%%d,设置“\u sum=!\u mm\u dd\u year:~%d,5!”&如果“9!”\u sum:~,2!”lss“9!\u mm!”设置/a“\u day\u year+=!\u sum:~-2!”)
set/a“\u day\u year”+=!\u dd!”&&set/a“\u remain=!\u day\u year!-!\u year!”&&echo/今天:_日期年月日:_日(年)剩余天数:_保持:-=!
|结果|
今天:2019年04月21日一年中的第111天剩余天数:254天
常规格式:
@echo off&setlocal enabledelayedexpansion
设置“_cmd=Get Day^,Month^,Year^”
对于(2020 4 2100)中的/l%%l,请设置“\u数组\u闰年\u=!\ u数组\u闰年\u!%%l,”
对于/f“tokens=1-3delims=“%%a in('wmic Path Win32_LocalTime!_cmd!^ findstr/r“[0-9]”)do(
设置“_yy=%%c”
设置“_mm=0%%b”
设置“\u dd=0%%a”
设置“\u-mm=!\u-mm:~-2!”
设置“\u dd=!\u dd:~-2!”
设置日期=!\uyy!\umm!\udd!
)
回声_数组(闰年)(年)|findstr/lic:“!”日期:~0,4!“>nul&&(
设置“_leap_=29”和设置“_year_=366”)| |(设置“_leap_=28”和设置“_year_=365”)
设置“\u mm\u dd\u year\u=01-31,02-!\u leap\u331,03-31,04-30,05-31,06-30,07-31,08-31,09-30,10-31,11-30,12-31”
设置/a“\u循环=!\u毫米!*6”
对于(0 6!循环!)中的/l%%d,请设置“\u sum=!\u mm\u dd\u year:~%d,5!”&”(
如果“9!\u sum:~,2!”lss“9!\u mm!”设置/a“\u day\u year\u+=!\u sum:~-2!”)
设置/a“\u天\u年”+=!\u日
设置/a“\u剩余=!\u天\u年!-!\u年!”
回声/今天:_日期年月日:_日(年)剩余天数:_保持:-=!
你是说朱利安的约会吗?如果是,是的。这个答案对我有用。非常感谢@我认为GhostGhost的评论应该被提升为一个答案。我添加了一个关于你们的方法对系统日期格式的依赖性的注释。要以标准格式检索系统日期,可以分析wmic OS GET LocalDateTime的输出。在2位数字前面加上1
并在其后减去100
的目的是什么,比如在set/A month=1%日期:~0,2%-100
?我刚刚发现:set/A
将以0
开头的数字解释为八进制数字,比如month07
或08
;后者是无效的八进制数;前缀为1
使其成为有效的十进制数108
,减去100
将得到8
。@Aacini在linux上的bash中也有这样做的方法吗?发布单独答案而不是编辑的理由:参考您是对的:我计算一年中某一天的方法将在2100年3月失败,但不要担心:我计划在1月/2100日进行提醒,因此我将在这里发布所需的修改,并为OP提供实施建议。这样,OP将节省大量计算机时间,避免在未来85年内执行无用的操作<代码>;)代码>太好了,谢谢!;-)最近一年你的实现失败是1900年——但我知道,当时计算机并不那么普遍。。。对于仅关注当前日期的问题,偏差当然不相关;但是,对于其他日期,它可能会成为一个问题…在Windows Server 2008标准版中效果非常好。为两个调用返回相同的、正确的一年中的某一天,带或不带YYYYMMDD输入参数。
@echo off
setlocal EnableDelayedExpansion
set /A i=0, sum=0
rem accumulate day-offsets for every month in %accum[1...12]%
for %%a in (31 28 31 30 31 30 31 31 30 31 30 31) do (
set /A i+=1
set /A accum[!i!]=sum, sum+=%%a
)
rem check for availability of alternative date value given via (1st) command line argument,
rem just for convenient batch testing
if "%1"=="" (
rem WMIC retrieves current system date/time in standardised format;
rem parse its output by FOR /F, then store it in %CurrDate%
for /F "tokens=2 delims==" %%D in ('wmic OS GET LocalDateTime /VALUE ^| find "="') do (
set CurrDate=%%D
)
) else (
rem apply date value from command line in YYYYMMDD format (not checked for validity)
set CurrDate=%1
)
rem extract %month% and %day%;
set /A month=1%CurrDate:~4,2%-100, day=1%CurrDate:~6,2%-100
rem compute several moduli needed for determining whether year is leap year
set /A yearMOD4=%CurrDate:~0,4% %% 4
set /A yearMOD100=%CurrDate:~0,4% %% 100, yearMOD400=%CurrDate:~0,4% %% 400
rem calculate %dayOfYear% as it were not a leap year
set /A dayOfYear=!accum[%month%]!+day
rem adapt %dayOfYear% only in case %month% is past February (29th)
if %month% gtr 2 (
rem check for leap year and adapt %dayOfYear% accordingly
if %yearMOD4% equ 0 set /A dayOfYear+=1
if %yearMOD400% neq 0 if %yearMOD100% equ 0 set /A dayOfYear-=1
)
rem compound statement to let %dayOfYear% survive SETLOCAL/ENDLOCAL block
endlocal & set dayOfYear=%dayOfYear%
rem return result
echo %dayOfYear%