我想在批处理脚本中生成日期前四天。我检查了可用的解决方案但看起来很复杂。任何帮助将不胜感激。
答案 0 :(得分:3)
我非常同意@JosefZ,日期数学是一个复杂的问题。 Vbscript和PowerShell结合使用,它像黑盒一样使用和依赖 即使批量只有32位有符号整数数学,这足以解决这个问题。当打包到存储在批次末尾的可调用子例程时,它不应该太刺激。
甚至有一种方法可以将它们放入路径中的某个批处理库中,只需要一个小存根来调用它们。
所以这里只有批量代码的变体(与powershell one liner相比有很大的开销)对日期格式和语言没有限制。
输出:
Today Year: 2016 Month: 12 Day: 08
-38 Year: 2016 Month: 10 Day: 31
批量
@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
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
答案 1 :(得分:2)
使用.bat
扩展程序保存此内容:
@if (@x)==(@y) @end /***** jscript comment ******
@echo off
cscript //E:JScript //nologo "%~f0" "%~nx0"
exit /b %errorlevel%
@if (@x)==(@y) @end ****** end comment *********/
var d = new Date();
d.setDate(d.getDate()-4);
WScript.Echo("berfore 4 days : "+d);
答案 2 :(得分:2)
要在严格批处理中执行此操作,您必须在%date%
上使用标记化或子字符串提取。但是,由于区域设置等原因导致的更改,因此存在问题。如果你想根据另一个日期获得一个相对日期,那就更成问题了,因为如上所述,在时间跨度计算的批次中没有理解,考虑到数月,年,闰年,夏令时等等。
所以最好的答案通常是依赖外部语言或库,比如另一个答案中的JScript,或者我最喜欢的:Powershell。
for /f %%a in ('"powershell [DateTime]::Now.AddDays(-4).ToString('dd-MMM-yy')"') do echo %%a
这是一个单行程序,从Powershell获取日期,减去4天,并将其作为%%a
的dd-MMM-yy格式。您可以使用%%a
执行任何操作,并根据需要更改格式。
答案 3 :(得分:2)
是的,有复杂的纯批处理文件方法将日期转换为Julian Day Number,减去天数并将结果转换回日期。还有其他方法使用其他编程语言的日期函数,如PowerShell或VBScript / JScript,如其他答案所示。
我希望下面的六行纯批处理方法看起来不那么复杂。
@echo off
setlocal EnableDelayedExpansion
set N=4
set i=100
for %%a in (31 28 31 30 31 30 31 31 30 31 30 31) do set /A "i+=1" & set "dpm[!i!]=%%a"
for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
set /A "DD=1%%b-N, I=^!(((DD-101)>>31)+1), MM=1%%a-I, J=^!(MM-100), MM+=J*12"
set /A "YYYY=%%c-J, dpm[102]+=^!(YYYY%%4), DD+=I*dpm[!MM!]"
)
set "newDate=%MM:~1%/%DD:~1%/%YYYY%
echo %newDate%
此方法适用于%DATE%
格式的MM / DD / YYYY;如果您的日期格式不同,只需更改表达式中%%a
和%%b
参数的位置以及结果中MM
和DD
的顺序。
此方法可以从当前日期减去最多一个月。
答案 4 :(得分:0)
这是一个更复杂的批处理方式来获取日期减去天数。这使用XCOPY技巧来验证日期是否有效。
{{1}}