How to Check if a Year is a Leap Year in a Batch Script
A leap year, which occurs roughly every four years, contains an extra day (February 29th) to keep our calendar in sync with the Earth's orbit. Knowing whether a given year is a leap year is a crucial part of any script that performs date calculations, validation, or scheduling. While batch scripting has no built-in date functions to do this automatically, you can easily implement the logic using basic integer arithmetic.
This guide will teach you the rules that define a leap year and show you how to implement them in a batch script using the SET /A command with the modulo operator. You will learn how to create a simple and reliable function to check any year.
The Rules for a Leap Year
A year is a leap year if it meets the following criteria. The rules must be checked in this specific order:
- The year must be evenly divisible by 4.
- However, if the year is evenly divisible by 100, it is not a leap year...
- Unless the year is also evenly divisible by 400. Then it is a leap year.
Examples:
2020: Is divisible by 4, not by 100. It is a leap year.1900: Is divisible by 4 and 100, but not by 400. It is not a leap year.2000: Is divisible by 4, 100, and 400. It is a leap year.
The Core Method: Using SET /A and the Modulo Operator (%%)
To check if a number is "evenly divisible" by another, we use the modulo operator. This operator gives the remainder of a division. In batch, this is done with SET /A.
Syntax: SET /A "Remainder = Year %% Divisor"
- If
Remainderis0, the year is evenly divisible. - If
Remainderis not0, it's not evenly divisible.
This is the only tool we need to implement the leap year rules.
The Script: A Full Leap Year Checker
This script implements the three rules in the correct order using a series of IF statements.
@ECHO OFF
SETLOCAL
SET "YearToCheck=2024"
SET "IsLeapYear=0"
ECHO --- Leap Year Checker ---
ECHO Checking the year: %YearToCheck%
ECHO.
REM --- Step 1: Check if divisible by 4 ---
SET /A "IsDivBy4 = %YearToCheck% %% 4"
IF %IsDivBy4% NEQ 0 (
SET "IsLeapYear=0"
GOTO :Result
)
REM --- Step 2: Check if divisible by 100 ---
SET /A "IsDivBy100 = %YearToCheck% %% 100"
IF %IsDivBy100% NEQ 0 (
SET "IsLeapYear=1"
GOTO :Result
)
REM --- Step 3: Check if divisible by 400 ---
SET /A "IsDivBy400 = %YearToCheck% %% 400"
IF %IsDivBy400% NEQ 0 (
SET "IsLeapYear=0"
GOTO :Result
)
SET "IsLeapYear=1"
:Result
IF %IsLeapYear% EQU 1 (
ECHO %YearToCheck% is a leap year.
) ELSE (
ECHO %YearToCheck% is NOT a leap year.
)
ENDLOCAL
How the Script's Logic Works
The script is a direct translation of the rules using a "waterfall" logic with GOTO.
-
Check Rule 1 (Divisible by 4):
SET /A "IsDivBy4 = %YearToCheck% %% 4"- If the remainder is not 0 (
NEQ 0), we know it's not a leap year. We set the flag to0(false) and jump straight to the result.
-
Check Rule 2 (Divisible by 100):
- This part only runs if the first check passed.
SET /A "IsDivBy100 = %YearToCheck% %% 100"- If the remainder is not 0, it means it is divisible by 4 but not by 100. This is the most common case for a leap year. We set the flag to
1(true) and jump to the result.
-
Check Rule 3 (Divisible by 400):
- This part only runs if the year was divisible by both 4 and 100.
SET /A "IsDivBy400 = %YearToCheck% %% 400"- If the remainder is not 0, it's a "century" year that isn't a leap year (like 1900). We set the flag to
0(false). - If this check passes, it means the year is divisible by 400 (like 2000), so we set the flag to
1(true).
Common Pitfalls and How to Solve Them
-
Incorrect Logic Order: The order of the three checks is critical. Checking for divisibility by 100 before checking for 4 will produce incorrect results. Solution: Always follow the standard rule order: 4, then 100, then 400.
-
Modulo Syntax: The modulo operator is
%. However, inside a batch script, you must escape it by doubling it (%%).SET /A "Result = %Year% % 4"-> WRONGSET /A "Result = %Year% %% 4"-> CORRECT
-
User Input: If the user provides non-numeric input, the
SET /Acommand will treat it as a variable with a value of 0, leading to an incorrect result. Solution: You should always validate user input to ensure it is a number before performing calculations.
Practical Example: A "Days in February" Script
This script takes a year as an argument and uses the leap year logic to report whether February has 28 or 29 days that year. The logic is encapsulated in a reusable subroutine.
@ECHO OFF
SETLOCAL
SET "Year=%1"
IF NOT DEFINED Year SET "Year=2023"
CALL :IsLeapYear %Year% IsLeap
IF "%IsLeap%"=="1" (
ECHO In the year %Year%, February has 29 days.
) ELSE (
ECHO In the year %Year%, February has 28 days.
)
GOTO :EOF
:IsLeapYear <Year> <ReturnVar>
SETLOCAL
SET /A "y = %1"
SET "Result=0"
SET /A "mod4 = y %% 4"
SET /A "mod100 = y %% 100"
SET /A "mod400 = y %% 400"
IF %mod4% EQU 0 (
IF %mod100% EQU 0 (
IF %mod400% EQU 0 (
SET "Result=1"
)
) ELSE (
SET "Result=1"
)
)
ENDLOCAL & SET "%2=%Result%"
GOTO :EOF
This example uses a more nested IF/ELSE structure, which is an alternative to the GOTO method.
Conclusion
While batch scripting lacks a built-in function for date calculations, the logic for determining a leap year can be implemented easily and reliably.
- The core tool is the
SET /Acommand with the modulo operator (%%) to check for divisibility. - The key to success is to implement the three rules of leap years in the correct order.
- This logic can be placed in a reusable subroutine to create a clean, function-like check for your scripts.