diff --git a/Maths/IsLeapYear.ts b/Maths/IsLeapYear.ts
new file mode 100644
index 00000000..0d607bb5
--- /dev/null
+++ b/Maths/IsLeapYear.ts
@@ -0,0 +1,18 @@
+/**
+ * @function IsLeapYear
+ * @description Checks if a year is a leap year (Gregorian calendar).
+ * A year is a leap year if it is divisible by 4 but not by 400 or if it is divisible by 400.
+ * @param {number} year - A year, natural number > 0.
+ * @return {boolean} - True if given year is a leap year.
+ * @see https://en.wikipedia.org/wiki/Leap_year#Gregorian_calendar
+ * @example IsLeapYear(2000) = true
+ * @example IsLeapYear(2001) = false
+ */
+
+export const IsLeapYear = (year: number): boolean => {
+  if (year <= 0 || !Number.isInteger(year)) {
+    throw new Error("year must be a natural number > 0");
+  }
+
+  return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
+};
diff --git a/Maths/test/IsLeapYear.test.ts b/Maths/test/IsLeapYear.test.ts
new file mode 100644
index 00000000..79acb8bd
--- /dev/null
+++ b/Maths/test/IsLeapYear.test.ts
@@ -0,0 +1,66 @@
+import { IsLeapYear } from "../IsLeapYear";
+
+describe("IsLeapYear", () => {
+  test.each([4, 8, 12, 2004])(
+    "a year is a leap year it is divisible by 4 but not by 400 like %i",
+    (year) => {
+      expect(year % 4 === 0).toBe(true);
+      expect(year % 400 === 0).toBe(false);
+      expect(IsLeapYear(year)).toBe(true);
+    },
+  );
+
+  test.each([400, 800, 1200, 1600, 2000, 2400, 40000])(
+    "a year is a leap year it is divisible by 400 like %i",
+    (year) => {
+      expect(year % 400 === 0).toBe(true);
+      expect(IsLeapYear(year)).toBe(true);
+    },
+  );
+
+  test.each([1, 313, 1997, 2001, 2021, 13337])(
+    "a year is not a leap year if it is not divisible by 4 like %i",
+    (year) => {
+      expect(year % 4 === 0).toBe(false);
+      expect(IsLeapYear(year)).toBe(false);
+    },
+  );
+
+  test.each([100, 200, 300, 700, 2100])(
+    "a year is not a leap year if it is divisible by 100 but not by 400 like %i",
+    (year) => {
+      expect(year % 100 === 0).toBe(true);
+      expect(year % 400 === 0).toBe(false);
+      expect(IsLeapYear(year)).toBe(false);
+    },
+  );
+
+  test.each([1, 2022, 3000000])(
+    "a year is supported if it is a natural number > 0 like %i",
+    (year) => {
+      expect(year > 0).toBe(true);
+      expect(Number.isInteger(year)).toBe(true);
+      expect(() => IsLeapYear(year)).not.toThrow();
+    },
+  );
+
+  test.each([-1, -10, -Infinity])(
+    "a year is not supported if it is negative like %i",
+    (year) => {
+      expect(year < 0).toBe(true);
+      expect(() => IsLeapYear(year)).toThrow("year must be a natural number > 0");
+    },
+  );
+
+  test.each([0.1, 1.2, 4.2])(
+    "a year is not supported if it is not an integer %d",
+    (year) => {
+      expect(Number.isInteger(year)).toBe(false);
+      expect(() => IsLeapYear(year)).toThrow("year must be a natural number > 0");
+    },
+  );
+
+  test("a year is not supported if it is 0", () => {
+    expect(() => IsLeapYear(0)).toThrow("year must be a natural number > 0");
+  })
+});