Batch file leap year?

2019-09-20 01:57发布

问题:

How should I create a batch file program that if I input a year the program will identify if it is a leap year or not.

@echo off
cls
echo.  LEAP YEAR
echo. Enter Year:
exit /b 0

Well, its just that i need help like suggestions to what should i do.

回答1:

@echo off
setlocal

set /P "year=Enter year: "
set /A "leap=!(year%%4) + (!!(year%%100)-!!(year%%400))"
if %leap% equ 1 echo Is leap year

Accordingly to Wikipedia a year is leap if it is divisible by 4 excepting if it is also divisible by 100, in which case it is leap only if it is also divisible by 400 ("divisible" means that the remainder of the division by the given number is zero). This way, 2000 and 2400 are leap years because their remainders when they are divided by 400 are zero, but 2100, 2200 and 2300 are not: these are special cases because their remainders when they are divided by 100 are zero.

In set /A command the ! boolean NOT operator gives 1 if its operand is zero and gives 0 in any other case, so set /A "leap=!(year%%4)" gives 1 if the year is divisible by 4 and zero in any other case; this gives the first part of the result.

After that we need to subtract 1 from this value in years 2100, 2200 and 2300, but subtract nothing in years 2000 and 2400; that is:

year    year%%100    a=!!(year%%100)    year%%400    b=!!(year%%400)    a-b
2000    0              0                0              0                 0
2100    0              0                100            1                 -1
2200    0              0                200            1                 -1
2300    0              0                300            1                 -1
2400    0              0                0              0                 0

If the year is not divisible by 100 then both a and b values are equal to 1, so a-b is zero and the result is given just by the original remainder by 4.

This way, the formula set /A "leap=!(year%%4) + (!!(year%%100)-!!(year%%400))" gives the complete result.



回答2:

It does not check if the input is correct:

@echo off
set /p year=enter a year:

call :isLeap %year%

exit /b 0
:isLeap
setlocal

set "year=%~1"
set /a _4=year%%4
set /a _100=year%%100
set /a _400=year%%400

::set _

if not %_4% equ 0 (
  echo not leap
  exit /b 0
)

if %_100% equ 0 (

        if not %_400% equ 0 (
           echo not leap
           exit /b 0
        )
)

echo leap
exit /b 0


回答3:

You could abuse PowerShell's date constructor. If it errors attempting to set the date object to February 29 of nnnn, then it's not a leap year.

@echo off
setlocal

if "%~1"=="" (
    echo Usage: %~nx0 year
    goto :EOF
)

>NUL 2>NUL powershell "get-date -date '%~1.2.29'" && (
    echo Leap year!
) || (
    echo Not leap year.
)

goto :EOF

You can do the same with a JScript hybrid. It's a little more code, but it's much faster.

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

if "%~1"=="" (
    echo Usage: %~nx0 year
    goto :EOF
)

cscript /nologo /e:Jscript "%~f0" "%~1" && (
    echo Leap year!
) || (
    echo Not leap year.
)

goto :EOF
@end
WSH.Quit(new Date(WSH.Arguments(0), 1, 29).getDate() - 29);