我强烈同意@JosefZ,日期数学是一个复杂的问题。 Vbscript 和 PowerShell 将其合并,并且像黑匣子一样使用和依赖。
即使批处理只有 32 位有符号整数数学,这也足以解决这个问题。当打包到存储在批次末尾的可调用子例程中时,它不会太令人恼火。
甚至有一种方法可以将它们放入路径中某处的批处理库中,并且只需要一个小存根即可调用它们。
所以这里是只有批处理代码的变体(与 powershell oneliner 相比,开销很大) 对日期格式和语言没有限制。
输出:
Today Year: 2016 Month: 12 Day: 08
-38 Year: 2016 Month: 10 Day: 31
Batch
@Echo off
Call :GetDate yy mm dd
Echo Today Year: %yy% Month: %mm% Day: %dd%
Set /A n=-38
Call :DateAdd yy mm dd %n%
Echo %n% Year: %yy% Month: %mm% Day: %dd%
Pause
Goto :Eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:GetDate yy mm dd
::
:: Func: Loads local system date components into args 1 to 3.
::
:: Args: %1 var to receive year, 4 digits (by ref)
:: %2 var to receive month, 2 digits, 01 to 12 (by ref)
:: %3 Var to receive day of month, 2 digits, 01 to 31 (by ref)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SetLocal EnableExtensions
for /f "tokens=1-3 delims=.+-" %%A in (
'wmic os get LocalDateTime^|findstr ^^[0-9]'
) do Set _DT=%%A
Set "yy=%_DT:~0,4%"&Set "MM=%_DT:~4,2%"&Set "dd=%_DT:~6,2%"
endlocal&set %1=%yy%&set %2=%MM%&set %3=%dd%&goto :EOF
:: GetDate.cmd :::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:DateAdd yy mm dd #days
::
:: Func: Adds/subs Days from/to a given date by converting to a
:: Julian Day adding the offset and converting back.
:: Args:
:: %1 year component used to create JD, 4 digits (by ref)
:: %2 month component used to create JD, leading zero ret (by ref)
:: %3 day of month used to create MJD, leading zero ret (by ref)
:: %4 days offset may be positive or negative (by val)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SetLocal
Call set /A "yy=%%%1%%,mm=100%%%2%% %%%%100,dd=100%%%3%% %%%%100"
Set /A jd=(1461*(yy+4800+(mm-14)/12))/4
Set /A jd=jd+(367*(mm-2-12*((mm-14)/12)))/12
Set /A jd=jd-(3*((yy+4900+(mm-14)/12)/100))/4,jd=jd+dd-32075
Set /A jd=jd+%4
set /A l=jd+68569,n=(4*l)/146097,l=l-(146097*n+3)/4
Set /A i=(4000*(l+1))/1461001,l=l-(1461*i)/4+31,j=(80*l)/2447
Set /A dd=l-(2447*j)/80,l=j/11,mm=j+2-(12*l),yy=100*(n-49)+i+l
(if %mm% LSS 10 set mm=0%mm%)&(if %dd% LSS 10 set dd=0%dd%)
Endlocal&set %1=%yy%&set %2=%mm%&set %3=%dd%&Goto :Eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::