{"record":{"id":"c4648399cb753007","repo":"TheAlgorithms/Java","slug":"invalid-date","errorCode":null,"errorMessage":"Invalid date.","messagePattern":"Invalid date\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/maths/ZellersCongruence.java","lineNumber":55,"sourceCode":"    public static String calculateDay(String input) {\n        if (input == null || input.length() != 10) {\n            throw new IllegalArgumentException(\"Input date must be 10 characters long in the format MM-DD-YYYY or MM/DD/YYYY.\");\n        }\n\n        int month = parsePart(input.substring(0, 2), 1, 12, \"Month must be between 1 and 12.\");\n        char sep1 = input.charAt(2);\n        validateSeparator(sep1);\n\n        int day = parsePart(input.substring(3, 5), 1, 31, \"Day must be between 1 and 31.\");\n        char sep2 = input.charAt(5);\n        validateSeparator(sep2);\n\n        int year = parsePart(input.substring(6, 10), 46, 8499, \"Year must be between 46 and 8499.\");\n\n        try {\n            Objects.requireNonNull(LocalDate.of(year, month, day));\n        } catch (DateTimeException e) {\n            throw new IllegalArgumentException(\"Invalid date.\", e);\n        }\n        if (month <= 2) {\n            year -= 1;\n            month += 12;\n        }\n\n        int century = year / 100;\n        int yearOfCentury = year % 100;\n        int t = (int) (2.6 * month - 5.39);\n        int u = century / 4;\n        int v = yearOfCentury / 4;\n        int f = (int) Math.round((day + yearOfCentury + t + u + v - 2 * century) % 7.0);\n\n        int correctedDay = (f + 7) % 7;\n\n        return \"The date \" + input + \" falls on a \" + DAYS[correctedDay] + \".\";\n    }\n","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/maths/ZellersCongruence.java#L37-L73","documentation":"Thrown by ZellersCongruence.calculateDay when LocalDate.of(year, month, day) raises a DateTimeException. This is the second-stage check that catches semantically invalid dates that passed the coarse range checks: e.g., Feb 30, Apr 31, Feb 29 on a non-leap year. The original DateTimeException is chained as the cause.","triggerScenarios":"Call calculateDay(\"02-30-2021\"), calculateDay(\"04-31-2020\"), calculateDay(\"02-29-2023\") (2023 is not a leap year), or any date whose day exceeds the actual days-in-month.","commonSituations":"Accepting day values up to 31 unconditionally (the coarse check allows 1-31 for every month), user-entered dates without calendar awareness, or test fixtures that pick round numbers.","solutions":["Validate the date with java.time.LocalDate.of(...) yourself before calling; if it constructs, the util will accept it.","Use a DatePicker/calendar control that disallows impossible days.","Catch IllegalArgumentException around the call and present a user-facing 'invalid calendar date' message."],"exampleFix":"// before\nString d = ZellersCongruence.calculateDay(input);\n\n// after\n// pre-validate so the error is yours, not the util's\nLocalDate.of(year, month, day); // throws DateTimeException if invalid\nString d = ZellersCongruence.calculateDay(input);","handlingStrategy":"validation","validationCode":"try {\n    LocalDate.of(year, month, day); // throws DateTimeException if not a real calendar date\n} catch (java.time.DateTimeException e) {\n    throw new IllegalArgumentException(\"Not a real calendar date\", e);\n}\nString d = ZellersCongruence.calculateDay(input);","typeGuard":null,"tryCatchPattern":"try {\n    String d = ZellersCongruence.calculateDay(input);\n} catch (IllegalArgumentException e) {\n    // could be format, range, OR invalid calendar date; chain has the cause\n    return Result.invalid(e.getMessage());\n}","preventionTips":["Never trust a 1-31 day check alone; always validate against the actual month/leap-year via LocalDate.","Prefer constructing the input string from a LocalDate so calendar validity is guaranteed upstream."],"tags":["date","zellers-congruence","calendar","argument-validation"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}