Batch to output a list of dates from given for /L parameter

Deadly 提交于 2020-01-13 20:38:06

问题


Please consider the following codes:

@echo off
setlocal enabledelayedexpansion

FOR /L %%G IN (0,1,19) DO (
set /a "Dday=%_day%+%%G"

if %mth% equ sml (
    if !Dday! gtr 30 (
        set "_day=1"
        set /a "_month+=1"          
    )
    if !_month! gtr 12 (
        set "_month=1"
        set /a "_year+=1"
    )

) else (
    if %mth% equ big (
        if !Dday! gtr 31 (
            set "_day=1"
            set /a "_month+=1"
        ) 
        if !_month! gtr 12 (
            set "_month=1"
            set /a "_year+=1"
        )
    )
)

echo !Dday!/!_month!/!_year!.txt
)

Consider the following date: 20/04/2016

_day = 20; _month = 04; _year = 2016; mth=sml;

and my output is this:

It increases the day from 30 instead of changing it to 1. Can I know what have I done wrong? Please advise. Thanks


回答1:


There are two problems in this script. First as @SomethignDark pointed out, you need to use !_day! instead of %_day%.

Second when Dday is greater than 30, %%G is 12. So you expression of !_day!+%%G will be 13 instead of 1.

So you need something like

...
FOR /L %%G IN (0,1,19) DO (

set /a "Dday=!_day!+%%G"

if !_day! equ 1 set /a "Dday=!_day!+%%G-12"
...



回答2:


You know, pure batch is really cumbersome with date math. What will you do for months with 31 days? For February? During leap year? You should consider, if not altogether switching to another language with a proper date object, then at least borrowing from one. Here's a Batch + PowerShell hybrid example:

<# : batch portion
@echo off & setlocal

if "%~1"=="" (
    echo usage: %~nx0 startdate
    goto :EOF
)

set "startdate=%~1"
set "daysToAdd=19"

rem # evaluate PowerShell hybrid code and capture output as %%I
for /f "delims=" %%I in ('powershell -noprofile "iex (${%~f0} | out-string)"') do (

    rem # do something useful with %%I here
    echo %%I.txt
)

goto :EOF
: end batch / begin PowerShell hybrid code #>

# cast "startdate" environment variable value as a datetime object
[datetime]$d = $env:startdate

for ($i = 0; $i -le $env:daysToAdd; $i++) {
    $d.addDays($i).toString("dd-MM-yyyy")
}

Or if you prefer the speed of VBScript, here's a Batch + VBScript hybrid example. Its allowed date input is perhaps not quite as flexible as that of PowerShell, but it does execute nearly instantly.

<!-- : batch portion
@echo off & setlocal

if "%~1"=="" (
    echo usage: %~nx0 startdate
    goto :EOF
)

set "startdate=%~1"
set "daysToAdd=19"

rem # evaluate VBScript hybrid code and capture output as %%I
for /f "delims=" %%I in ('cscript /nologo "%~f0?.wsf" "%startdate%" "%daysToAdd%"') do (

    rem # do something useful with %%I here
    echo %%I.txt
)

goto :EOF
: end batch / begin VBScript -->
<job>
    <script language="VBScript">
        if not IsDate(WSH.Arguments(0)) then
            WSH.StdErr.WriteLine("Not a valid date.")
            WSH.Quit(1)
        end if

        d = CDate(WSH.Arguments(0))
        For i = 0 to WSH.Arguments(1)
            d2 = DateAdd("d", i, d)
            WSH.Echo(Day(d2) & "-" & Month(d2) & "-" & Year(d2))
        Next
    </script>
</job>

Or if you're more comfortable with JavaScript syntax, you could do a Batch + JScript hybrid solution.

@if (@CodeSection == @Batch) @then
@echo off & setlocal

if "%~1"=="" (
    echo usage: %~nx0 startdate
    goto :EOF
)

set "startdate=%~1"
set "daysToAdd=19"

rem // evaluate VBScript hybrid code and capture output as %%I
for /f "delims=" %%I in (
    'cscript /nologo /e:JScript "%~f0" "%startdate%" "%daysToAdd%"'
) do (

    rem // do something useful with %%I here
    echo %%I.txt
)

goto :EOF
@end // end batch / begin JScript

Date.prototype.addDays = function(num) {
    this.setDate(this.getDate() + num);
    return this;
}

for (var i=0; i<WSH.Arguments(1); i++) {
    var d = new Date(WSH.Arguments(0)).addDays(i);
    WSH.Echo([d.getDate(), (d.getMonth() + 1), d.getFullYear()].join('-'));
}

Either way, VBScript, JScript, and PowerShell will all let you add n days to a date object, and that date object automatically handles calendar quirks without your explicitly needing to script for them.



来源:https://stackoverflow.com/questions/36732545/batch-to-output-a-list-of-dates-from-given-for-l-parameter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!