Високосный год пакетного файла?

Как мне создать программу пакетного файла, которая, если я введу год, программа определит, является ли он високосным годом или нет.

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

Ну, просто мне нужна помощь, например, предложения, что мне делать.


person San Ry    schedule 02.02.2016    source источник
comment
Как бы это решил человек?   -  person jeb    schedule 02.02.2016
comment
зависит от того, что он/она хочет ввести. например, если он / она вводит 2016, то это високосный год..   -  person San Ry    schedule 02.02.2016
comment
Ага, может быть, есть правило о високосных годах? Или это случайно? Вы знаете, будет ли 2028 год високосным?   -  person jeb    schedule 02.02.2016
comment
через 4 года. будет високосный год..   -  person San Ry    schedule 02.02.2016
comment
В моей версии википедии описаны правила. Если предположить, что вас интересуют только следующие 80 лет, то остается только одно правило   -  person jeb    schedule 02.02.2016


Ответы (3)


@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

Согласно Википедии, год считается високосным, если он делится на 4, за исключением случаев, когда он также делится на 100. , и в этом случае он является скачкообразным только в том случае, если он также делится на 400 («делимый» означает, что остаток от деления на данное число равен нулю). Таким образом, 2000 и 2400 годы являются високосными, потому что их остатки при делении на 400 равны нулю, а 2100, 2200 и 2300 — нет: это особые случаи, потому что их остатки при делении на 100 равны нулю.

В команде set /A логический оператор НЕ ! дает 1, если его операнд равен нулю, и возвращает 0 в любом другом случае, поэтому set /A "leap=!(year%%4)" дает 1, если год делится на 4, и ноль в любом другом случае; это дает первую часть результата.

После этого нам нужно вычесть из этого значения 1 в 2100, 2200 и 2300 годах, но ничего не вычесть в 2000 и 2400 годах; то есть:

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

Если год не делится на 100, то оба значения a и b равны 1, поэтому a-b равно нулю, а результат определяется только первоначальным остатком на 4.

Таким образом, формула set /A "leap=!(year%%4) + (!!(year%%100)-!!(year%%400))" дает полный результат.

person Aacini    schedule 02.02.2016
comment
@jeb: Готово! Не люблю, когда пояснений больше и их сложнее написать, чем само решение :/ - person Aacini; 03.02.2016
comment
отлично. Может быть, это будет работать еще быстрее set /A "leap=!(year&3) + (!!(year%100)-!!(year&15))" (побитно вместо проверки по модулю) - person npocmaka; 03.02.2016
comment
@npocmaka: мне нравится! Тем не менее, я призываю вас написать понятное объяснение такого метода для людей без опыта, таких как ОП... - person Aacini; 03.02.2016

Он не проверяет правильность ввода:

@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
person npocmaka    schedule 02.02.2016

Вы можете злоупотреблять конструктором даты PowerShell. Если возникает ошибка при попытке установить объект даты на 29 февраля nnnn, то это не високосный год.

@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

Вы можете сделать то же самое с гибридом JScript. Это немного больше кода, но это намного быстрее.

@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);
person rojo    schedule 02.02.2016