Windows控制台 %DATE% 数学

9
我希望能在Windows批处理文件中将日期设置为今天的7天前,格式如下。
set today=%date:~10,4%-%date:~4,2%-%date:~-7,2%

有什么办法可以在这里减去7天的时间差吗?


5
尝试使用批处理做任何事情是值得肯定的,你是一个受虐狂。 - ZnArK
3
你真的在使用DOS吗?还是在Windows中使用批处理文件? - dbenham
1
我在谷歌上搜索了DOS批处理添加日期,第一个链接将我带到了这里:http://www.robvanderwoude.com/datetimentmath.php - 这不是一件有趣的事情,但是它是可能的。 - SeanC
我正在Windows中使用批处理文件...抱歉,我以为这是DOS。 - aeupinhere
批处理脚本中没有日期/时间数学运算,但根据您要做什么,可能有不同的方法来实现相同的目的。您需要在哪里应用此计算结果? - Andriy M
6个回答

20

我一段时间之前在某个网站上发布了以下描述:


下面的批处理文件用于将日期转换为儒略日数字,反之亦然:

DATETOJULIAN.BAT:

@ECHO OFF
REM CONVERT DATE TO JULIAN DAY NUMBER
REM ANTONIO PEREZ AYALA
REM GET MONTH, DAY, YEAR VALUES
FOR /F "TOKENS=1-3 DELIMS=/" %%A IN ("%1") DO SET MM=%%A& SET DD=%%B& SET YY=%%C
REM ELIMINATE LEFT ZEROS
SET /A DD=10%DD% %% 100, MM=10%MM% %% 100
REM CALCULATE JULIAN DAY NUMBER
IF %MM% LSS 3 SET /A MM+=12, YY-=1
SET /A A=YY/100, B=A/4, C=2-A+B, E=36525*(YY+4716)/100, F=306*(MM+1)/10, JDN=C+DD+E+F-1524

JULIANTODATE.BAT:

=>

JULIANTODATE.BAT:

REM CONVERT JULIAN DAY NUMBER TO MONTH, DAY, YEAR
REM ANTONIO PEREZ AYALA
SET /A W=(%1*100-186721625)/3652425, X=W/4, A=%1+1+W-X, B=A+1524, C=(B*100-12210)/36525, D=36525*C/100, E=(B-D)*10000/306001, F=306001*E/10000, DD=B-D-F, MM=E-1, YY=C-4716
IF %MM% GTR 12 SET /A MM-=12, YY+=1
REM INSERT LEFT ZEROS, IF NEEDED
IF %DD% LSS 10 SET DD=0%DD%
IF %MM% LSS 10 SET MM=0%MM%
REM SHOW THE DATE
ECHO %MM%/%DD%/%YY%

要给日期添加/减去若干天,可以使用以下代码:

CALL DATETOJULIAN %DATE%
SET /A NEWDATE=JDN+DAYS
CALL JULIANTODATE %NEWDATE%

如果日期格式不是MM/DD/YYYY,您只需要调整它即可。

参考资料:http://quasar.as.utexas.edu/BillInfo/JulianDatesG.html


Regards...


0

我对http://www.robvanderwoude.com/datetimentmath.php中的JDateGDate子程序的代码进行了一些重构。

使用示例:

Enter ISO date:
Enter number of days to add: 7
2017-01-01 + 7 days = 2017-01-08

Enter ISO date:
Enter number of days to add:
2017-01-08 + 7 days = 2017-01-15

Enter ISO date:
Enter number of days to add:
2017-01-15 + 7 days = 2017-01-22

Enter ISO date:
Enter number of days to add:
2017-01-22 + 7 days = 2017-01-29

Enter ISO date:
Enter number of days to add:
2017-01-29 + 7 days = 2017-02-05

Enter ISO date: 2017-02-12
Enter number of days to add: -7
2017-02-12 + -7 days = 2017-02-05

代码:

"Date math.bat":

@echo off

call :main %*
goto :eof

:main
    setlocal

    call :initialize "2017-01-01" "1"

    endlocal
    goto :eof

:initialize
    setlocal
    set "previousDate=%~1"
    set /a "numberOfDays=%~2"

    set /p "previousDate=Enter ISO date: "
    set /p "numberOfDays=Enter number of days to add: "

    set "currentDate="
    call :addIsoDateDays "%previousDate%" "%numberOfDays%" currentDate

    echo %previousDate% + %numberOfDays% days = %currentDate%

    echo.

    call :initialize "%currentDate%" "%numberOfDays%"

    endlocal
    goto :eof

:stripLeadingZero
    setlocal
    set "number=%~1"
    if %number:~0,1% equ 0 (
        set "number=%number:~1%"
    )
    (
        endlocal
        set "%~2=%number%"
    )
    goto :eof

:addLeadingZero
    setlocal
    set "number=%~1"
    if %number% lss 10 (
        set "number=0%number%"
    )
    (
        endlocal
        set "%~2=%number%"
    )
    goto :eof

:gregorianToJulianDate
    setlocal
    set "gregorianYear=%~1"
    set "gregorianMonth=%~2"
    set "gregorianDay=%~3"

    call :stripLeadingZero "%gregorianMonth%" gregorianMonth
    call :stripLeadingZero "%gregorianDay%" gregorianDay

    set /a "julianYear=(%gregorianYear% + 4800)"
    set /a "julianMonth=((%gregorianMonth% - 14) / 12)"
    set /a "julianDate=((1461 * (%julianYear% + %julianMonth%) / 4) + (367 * (%gregorianMonth% - 2 - (12 * %julianMonth%)) / 12) - ((3 * ((%julianYear% + %julianMonth% + 100) / 100)) / 4) + (%gregorianDay% - 32075))"

    (
        endlocal
        set "%~4=%julianDate%"
    )
    goto :eof

:isoToJulianDate
    setlocal
    set "date=%~1"
    set "year="
    set "month="
    set "day="

    for /f "tokens=1-3 delims=-" %%a in ("%date%") do (
        set "year=%%a"
        set "month=%%b"
        set "day=%%c"
    )

    set /a "julianDate=0"
    call :gregorianToJulianDate "%year%" "%month%" "%day%" julianDate

    (
        endlocal
        set "%~2=%julianDate%"
    )
    goto :eof

:julianToGregorianDate
    setlocal
    set /a "julianDate=%~1"

    set /a "p=(%julianDate% + 68569)"
    set /a "q=(4 * %p% / 146097)"
    set /a "r=(%p% - ((146097 * %q%) + 3) / 4)"
    set /a "s=(4000 * (%r% + 1) / 1461001)"
    set /a "t=(%r% - ((1461 * %s%) / 4) + 31)"
    set /a "u=(80 * %t% / 2447)"
    set /a "v=(%u% / 11)"

    set /a "gregorianYear=((100 * (%q% - 49)) + %s% + %v%)"
    set /a "gregorianMonth=(%u% + 2 - (12 * %v%))"
    set /a "gregorianDay=(%t% - (2447 * %u% / 80))"

    call :addLeadingZero "%gregorianMonth%" gregorianMonth
    call :addLeadingZero "%gregorianDay%" gregorianDay

    (
        endlocal
        set "%~2=%gregorianYear%"
        set "%~3=%gregorianMonth%"
        set "%~4=%gregorianDay%"
    )
    goto :eof

:julianToIsoDate
    setlocal
    set /a "julianDate=%~1"

    set "year="
    set "month="
    set "day="

    call :julianToGregorianDate "%julianDate%" year month day

    set "isoDate=%year%-%month%-%day%"

    (
        endlocal
        set "%~2=%isoDate%"
    )
    goto :eof

:addIsoDateDays
    setlocal
    set "previousIsoDate=%~1"
    set /a "numberOfDays=%~2"

    set /a "previousJulianDate=0"
    call :isoToJulianDate "%previousIsoDate%" previousJulianDate

    set /a "currentJulianDate=(%previousJulianDate% + %numberOfDays%)"

    set "currentIsoDate="
    call :julianToIsoDate "%currentJulianDate%" currentIsoDate

    (
        endlocal
        set "%~3=%currentIsoDate%"
    )
    goto :eof

0

AdamEstrada 询问了日期相减的问题。

由于 Julian 函数中的 SETLOCAL,我在计算两个儒略日之间的差值时遇到了困难。最终我通过调用一个函数来解决了这个问题。

call:sub_Julians !Julian! %Today_Julian%

:sub_Julians

set /a delta_dates=%~1-%~2

...

goto:eof ::end:age_of_EPSdate


0

好的,我需要一个批处理文件来显示一个DoD操作中心的当前JDAY。您可以双击文件,它将在CMD窗口中显示。然后,按任意键退出。

这是我的成果:

@echo off
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value')     do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set     "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"

:: Call the day ordinal number subroutine
call :JDdayNumber %DD% %MM% %YYYY% DayOrdinalNumber

:: Display the result
echo.
echo Today is JDay %DayOrdinalNumber%
echo.
pause,
endlocal & goto :EOF

:: set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%"
:: set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%"
:: echo datestamp: "%datestamp%"
:: echo timestamp: "%timestamp%"
:: echo fullstamp: "%fullstamp%"

:: ============================================================
:: Subroutine: Calculate a day's ordinal number within the year
::JDdayNumber day month year return_
setlocal enableextensions enabledelayedexpansion
if %2 LEQ 2 (
set /a f=%1-1+31*^(%2-1^)
) else (
set /a a=%3
set /a b=!a!/4-!a!/100+!a!/400
set /a c=^(!a!-1^)/4-^(!a!-1^)/100+^(!a!-1^)/400
set /a s=!b!-!c!
set /a f=%1+^(153*^(%2-3^)+2^)/5+58+!s!
)
set /a return_=%f%+1
endlocal & set "%4=%return_%" & goto :EOF

0

有一个使用PowerShell的答案。 尽管仍有一些机器没有安装PowerShell(在撰写本文时,XP、Vista、Windows7、Windows2003和Windows2008仍具有相当大的操作系统份额,并且没有安装PowerShell)

另一个选择是在批处理脚本中使用jscript

这里是dayAdder.bat,它只接受一个参数-您要添加到当前日期的天数,并打印结果:

  @if (@X) == (@Y) @end /* JScript comment 
    @echo off   
    cscript //E:JScript //nologo "%~f0" %*
    exit /b %errorlevel%       
@if (@X)==(@Y) @end JScript comment */

var days=parseInt(WScript.Arguments.Item(0));


Date.prototype.addDays = function(days) {
    var date = new Date(this.valueOf());
    date.setDate(date.getDate() + days);
    return date;
}

var date = new Date();

WScript.Echo(date.addDays(5));
WScript.Echo("Year: " + date.getFullYear());
WScript.Echo("Month: " + date.getMonth());
WScript.Echo("DayOfTeWEek: " + date.getDay());

使用方法和输出:

E:\scripts>call dayAdder.bat 7
Sun Nov 8 16:27:48 UTC+0200 2020
Year: 2020
Month: 10
DayOfTeWEek: 2
DayOfTheMonth: 3

您可以根据自己的需要进行修改。


0
一个更简单的选项是在批处理脚本中调用PowerShell命令来操作日期。批处理脚本可以使用一行代码将日期设置为7天前。
powershell -command "((Get-date).AddDays(-7)).ToString('yyyy-MM-dd')">captureVar && set /p Today=<captureVar

这行代码首先指示命令行在双引号内的命令使用PowerShell。

powershell -command "the powershell command(s)"

接下来,它使用 PowerShell 命令 Get-Date,并使用 AddDays 来更改当前日期的值。负数将减去天数,正数将增加天数。默认格式如下:
Friday, December 20, 2019 6:18:29 PM

要更改格式,您必须使用格式说明将日期转换为字符串

.ToString('dddd MM/dd/yyyy HH:mm:ss.ffff K')

PowerShell命令的输出被重定向到名为captureVar的文件中。另一个选项是让PowerShell将其写入文件中。
powershell -command "((Get-date).AddDays(-7)).ToString('yyyy-MM-dd') | set-content 'captureVar'" && set /p Today=<captureVar

我使用了“&&”来使其成为一行代码。但是,您可以在文件的值被写入后随时设置变量。

set /p Today=<captureVar

你应该使用你最熟悉的脚本语言进行编写。但是请记住,在编写批处理脚本时,你的选项不仅限于批处理命令。Windows 已经非常容易在批处理脚本中随时调用 PowerShell 命令。你可以经常在 PowerShell 中找到解决给定障碍的简单方法,将该命令插入到你的脚本中,然后像往常一样继续完成批处理脚本。

在将 PowerShell 引入批处理脚本时,请记住以下几点:

批处理将双引号中的所有内容视为 PowerShell 命令。如果你发现一个使用双引号的 PowerShell 命令的解决方案,则必须将其替换为单引号。要转义字符,请遵循批处理脚本规则。批处理变量可以在 PowerShell 命令中以与批处理相同的方式读取(%var%)。但是在 PowerShell 中创建的值必须重定向以便稍后在批处理脚本中使用。任何在 PowerShell 命令中创建的 $var 在关闭引号结束 PowerShell 会话后都会丢失。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接