{"id":23282775,"url":"https://github.com/itsallcode/holiday-calculator","last_synced_at":"2026-03-06T02:36:51.980Z","repository":{"id":40423263,"uuid":"371418328","full_name":"itsallcode/holiday-calculator","owner":"itsallcode","description":"A Java library for calculating dates of public holidays","archived":false,"fork":false,"pushed_at":"2024-07-07T05:54:10.000Z","size":455,"stargazers_count":9,"open_issues_count":3,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-07-07T19:15:26.416Z","etag":null,"topics":["easter-sunday","holiday-calculation","holidays","public-holidays"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/itsallcode.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-27T15:18:55.000Z","updated_at":"2024-07-07T05:51:32.000Z","dependencies_parsed_at":"2024-01-21T11:25:25.180Z","dependency_job_id":"30d47be4-8570-45d9-a634-f3a97b8c1074","html_url":"https://github.com/itsallcode/holiday-calculator","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsallcode%2Fholiday-calculator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsallcode%2Fholiday-calculator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsallcode%2Fholiday-calculator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsallcode%2Fholiday-calculator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itsallcode","download_url":"https://codeload.github.com/itsallcode/holiday-calculator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230519218,"owners_count":18238839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["easter-sunday","holiday-calculation","holidays","public-holidays"],"created_at":"2024-12-20T00:29:39.754Z","updated_at":"2026-03-06T02:36:46.948Z","avatar_url":"https://github.com/itsallcode.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# holiday-calculator\nCalculate holidays from flexible formulas in a configuration file.\n\n[![Build](https://github.com/itsallcode/holiday-calculator/workflows/Build/badge.svg)](https://github.com/itsallcode/holiday-calculator/actions?query=workflow%3ABuild)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=org.itsallcode%3Aholiday-calculator\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=org.itsallcode%3Aholiday-calculator)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=org.itsallcode%3Aholiday-calculator\u0026metric=coverage)](https://sonarcloud.io/dashboard?id=org.itsallcode%3Aholiday-calculator)\n[![Maven Central](https://img.shields.io/maven-central/v/org.itsallcode/holiday-calculator?label=Maven%20Central)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.itsallcode%22%20a%3A%22holiday-calculator%22)\n\nEach holiday is meant to repeat every year and is defined by a formula in\norder to compute a concrete holiday instance for a given year.\nHoliday-calculator supports the following formula flavors:\n\n- a fixed date identical for every year\n- a floating date defined by a pivot date, specified as month and day and an\n  offset restricted to a particular day of the week, e.g. fourth Sunday before\n  Christmas, i.e. December 24th\n- a date defined relatively to Easter Sunday with a positive or negative offset of days\n- a fixed date with a condition to make the holiday effective\n- a fixed date with an alternative date as replacement under the given condition\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md).\n\n## Usage\n\nInclude holiday-calculator as a dependency into your project:\n\n### Gradle\n\n```groovy\nrepositories {\n    mavenCentral()\n}\ndependencies {\n    compile 'org.itsallcode:holiday-calculator:0.2.1'\n}\n```\n\n### Maven\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.itsallcode\u003c/groupId\u003e\n    \u003cartifactId\u003eholiday-calculator\u003c/artifactId\u003e\n    \u003cversion\u003e0.2.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Calculating holidays\n\nIn order to calculate holidays you must create a holiday definition.\nHoliday-calculator supports six different flavors of holiday definitions.\nFor each flavor there is a dedicated class in package `org.itsallcode.holidays.calculator.logic`:\n\n1. `FixedDateHoliday` defines a holiday with a fixed date.\n2. `FloatingHoliday` defines a holiday with a floating date.\n3. `EasterBasedHoliday` defines an Easter-based holiday.\n4. `OrthodoxEasterBasedHoliday` defines an Orthodox-Easter-based holiday\n5. `ConditionalHoliday` defines a conditional holiday, effective under the given condition\n6. `HolidayWithAlternative` defines a holiday with an alternative date, effective under the given condition\n\nSection [Configuration file](README.md#flavors) describes the details and parameters for each flavor.\n\n#### Instantiating subclasses of Holiday\n\nThe following code sample instantiates one holiday for each of these flavors:\n\n```java\nimport org.itsallcode.holidays.calculator.logic.variants.FixedDateHoliday;\nimport org.itsallcode.holidays.calculator.logic.variants.FloatingHoliday;\nimport org.itsallcode.holidays.calculator.logic.variants.EasterBasedHoliday;\nimport org.itsallcode.holidays.calculator.logic.variants.OrthodoxEasterBasedHoliday;\nimport org.itsallcode.holidays.calculator.logic.variants.ConditionalHoliday;\nimport org.itsallcode.holidays.calculator.logic.variants.HolidayWithAlternative;\nimport org.itsallcode.holidays.calculator.logic.conditions.DayOfWeekCondition;\n\nclass MyClass {\n\n    public MyClass() {\n        Holiday h1 = new FixedDateHoliday(\"holiday\", \"Christmas Eve\", MonthDay.of(12, 24));\n\n        Holiday h2 = new FloatingHoliday(\n            \"holiday\", \"Father's Day\", 3, DayOfWeek.SUNDAY, Direction.AFTER, MonthDay.of(6, 1));\n\n        Holiday h3 = new EasterBasedHoliday(\"holiday\", \"Good Friday\", -2);\n\n        Holiday h4 = new OrthodoxEasterBasedHoliday(\n            \"holiday\", \"Orthodox Good Friday\", -2);\n\n        ConditionBuilder dec25SatSun = new ConditionBuilder()\n            .withDaysOfWeek(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY)\n            .withPivotDate(MonthDay.of(12, 25));\n        Holiday h5_default = new FixedDateHoliday(\"holiday\", \"Bank Holiday 1\", MonthDay.of(12, 27));\n        Holiday h5 = new ConditionalHoliday(dec25SatSun, h5_default);\n        \n        Holiday h6_default = new FixedDateHoliday(\"holiday\", \"Koningsdag\", MonthDay.of(4, 27));\n            ConditionBuilder isSunday = new ConditionBuilder().withDaysOfWeek(DayOfWeek.SUNDAY);\n            Holiday h6 = new HolidayWithAlternative(defaultKoningsdag, isSunday, MonthDay.of(4, 26));\n\n        Holiday h7 = new FloatingHoliday(\"holiday\", \"Midsommarafton\",\n            1, DayOfWeek.SATURDAY, Direction.BEFORE, MonthDay.of(6, 26))\n            .withOffsetInDays(-1);\n    }\n}\n```\n\n- Holiday `h5` is a conditional holiday with a negated condition, see [below](README.md#conditional-holidays).\n- Holiday `h6` is a holiday with an alternative date, see [below](README.md#alternative-holidays).\n- Holiday `h7` is a floating holiday with an additional offset in days, see [below](README.md#floating-holidays).\n\n#### Parsing a configuration File\n\nBesides creating instances of the subclasses of `Holiday` you can also use a configuration file to define your personal selection of holidays. Class `HolidaysFileParser` then parses the file and returns a list of holidays:\n\n```java\nimport org.itsallcode.holidays.calculator.logic.parser.HolidaysFileParser\n\nclass MyClass {\n    public MyClass() {\n        List\u003cHoliday\u003e holidays = new HolidaysFileParser.parse(\"/path/to/holidays.cfg\")\n    }\n}\n```\n\nFor the seven example holidays instantiated above, the content of the file could look like this:\n\n```\n# my holidays\n\nholiday fixed  12 24 Christmas Eve\nholiday float      3 SUN after 6 1 Father's Day\nholiday easter    -2 Good Friday\nholiday orthodox-easter -2 Orthodox Good Friday\nholiday if    DEC 25 is Sat,Sun then fixed DEC 27 Bank Holiday\nholiday either fixed 4 27 or if SUN then fixed 4 26 Koningsdag\nholiday float     1 day before 1 Sat before JUN 26 Midsommarafton\n```\n\nSection [Configuration file](README.md#flavors) describes the syntax in detail.\n\n#### Evaluating a specific holiday for a specific year\n\nIn order to evaluate a holiday for the current or any other year and hence get an instance of this\nholiday with a concrete date, you can just call method `Holiday.of()`, supplying the year as argument:\n\n```java\nHoliday goodFriday = new EasterBasedHoliday(\"holiday\", \"Good Friday\", -2);\nLocalDate gf_2021 = goodFriday.of(2021); // 2021 April 4th\n```\n\n### Configuration file\n\nUser can set up his or her individual personal list of favorite holidays using the supported formula flavors.\nHoliday-calculator already provides configuration files for a growing list of countries in folder [holidays](./holidays/).\n\n#### \u003ca name=\"flavors\"\u003e\u003c/a\u003eContent of configuration file\n\nThe configuration file is organized in lines. Each line can contain one of 7 types of content:\n\n1. Empty\n2. Definition of a holiday with a fixed date\n3. Definition of a holiday with a floating date\n4. Definition of an Easter-based holiday \n5. Definition of an Orthodox-Easter-based holiday\n6. Definition of a conditional holiday\n7. Definition of a holiday with an alternative date\n\nAll other lines are rated as illegal and ignored by holiday-calculator, logging an error message.\n\nWhitespace is allowed in most places without changing the nature of the\nline. Hence, a line containing nothing but tabs and spaces is still rated to\nbe an empty line.\n\n##### Comments\n\nEach line can contain an optional comment starting with hash mark `#`.\nHoliday-calculator will ignore the rest of the line after and including the\nhash mark.\n\n##### Holiday definitions\n\nThe definition of any holiday starts with a *category*. The category is an arbitrary\nstring of non-whitespace characters. The application evaluating your holidays\nmight support different categories of holidays, e.g. birthdays, anniversaries,\netc. and may display them in different colors. As a default we propose to use\ncategory \"holiday\".\n\nThe category is followed by a *tag* identifying the flavor of the holiday\ndefinition and additional arguments depending on the flavor. The last argument\nis always a string containing the name of the holiday.\n\nGeneral rules\n- All strings except the name of the holiday are case-insensitive.\n- In all definitions including a month the month must be specified by\n    - either using its English name January, February, March, April, May, June, July, August, September, October, November, December\n    - or a unique abbreviation of the name \n    - or the number of a month\n  with 1 for January and 12 for December.\n- Day of month is an integer from 1 to 31.\n- Day of week is \n    - either one of the English names Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday\n    - or a unique abbreviation of it\n\nIn the following cases holiday-calculator will log an error message and ignore\nthe holiday definition:\n- if the tag does not match any of the three supported tags\n  \"fixed\", \"float\", \"easter\"\n- if the holiday definition contains illegal numbers, such as month 0 or 13,\n  day 32, or day 30 for February\n- if the day of week does not match the abbreviation of any of the English names \n- if the day of week is abbreviated ambiguously, e.g. \"T\" or \"S\"\n- if the name of a month does not match the abbreviation of any of the English names \n- if the name of a month is abbreviated ambiguously, e.g. \"Ma\" or \"Ju\"\n\n##### Fixed date holiday definition\n\nA fixed date holiday definition has the tag \"fixed\", followed by the month and day of month.\n\nSyntax: `holiday fixed \u003cmonth\u003e \u003cday\u003e \u003cname\u003e`\n\nSamples:\n- `holiday fixed   1  1 New Year`\n- `holiday fixed Dec 12 Christmas Eve`\n\n##### \u003ca name=\"floating-holidays\"\u003e\u003c/a\u003eFloating holiday definition\n\nA floating holiday definition has the tag \"float\", followed by the offset, the\nday of week, the direction \"before\" or \"after\", the month and day\nof month. Month and day of month specify a *pivot date*.\n\nIf the day of week of the pivot date is identical to the specified one then\nthe offset starts to count on the pivot date, otherwise on the next instance\nof the specified weekday before or after the pivot date.\n\nInstead of a number the day of month can also be the special string \"last-day\".\n\nSyntax: `holiday float \u003coffset\u003e \u003cdirection\u003e \u003cday of week\u003e \u003cmonth\u003e \u003cday\u003e \u003cname\u003e`\n\nSamples:\n- `holiday float 1 W after 1 1 First Wednesday on or after New Year`\n- `holiday float 2 MON before DEC last-day Second Monday before New Year's eve, December the 31st`\n- `holiday float 4 SUNDAY before 12 24 First Advent`\n\n##### Floating holiday with additional offset in days\n\nOptionally a floating holiday definition can contain an additional offset in days. \nThis is especially required for Swedish holiday \"Midsommarafton\", which is 1 day before midsummer day, \nwhich in turn is the first Saturday on or before June, 26th.\n\nSyntax: `holiday float \u003coffset2\u003e day[s] \u003cdirection2\u003e \u003coffset\u003e \u003cdirection\u003e \u003cday of week\u003e \u003cmonth\u003e \u003cday\u003e \u003cname\u003e`\n\nSamples:\n- `holiday float 1 day before 1 Sat before JUN 26 Midsommarafton`\n\n##### Easter-based holiday definition\n\nAn Easter-based holiday definition has the tag \"easter\", followed by the\noffset. The offset is the number of days from Easter Sunday. If offset is\nnegative then the holiday is before Easter Sunday, otherwise after.\n\nSyntax: `holiday easter \u003coffset\u003e \u003cname\u003e`\n\nSamples:\n- `holiday easter   0 Easter Sunday`\n- `holiday easter  -2 Good Friday`\n- `holiday easter +49 Pentecost Sunday`\n\n##### Orthodox-Easter-based holiday definition\n\nAn Orthodox-Easter-based holiday definition has the tag \"orthodox-easter\", followed by the\noffset. The offset is the number of days from Easter Sunday. If offset is\nnegative then the holiday is before Orthodox-Easter Sunday, otherwise after.\n\nSyntax: `holiday orthodox-easter \u003coffset\u003e \u003cname\u003e`\n\nSamples:\n- `holiday orthodox-easter   0 Orthodox Easter Sunday`\n- `holiday orthodox-easter  -2 Orthodox Good Friday`\n- `holiday orthodox-easter +49 Orthodox Pentecost Monday`\n\n\n##### \u003ca name=\"conditional-holidays\"\u003e\u003c/a\u003eConditional holidays\n\nSome countries have a few holidays that do not occur every year but only if a specific condition is met.\nExamples are the bank holidays in the UK.\nHoliday-calculator calls such holidays *conditional holidays*.\n\nA conditional holiday definition has the tag \"if\", followed by\n- pivot month \n- pivot day of month\n- \"is\"\n- \"not\" (optional)\n- comma-separated list of pivot days of week, e.g. \"Wed,Fri\", not containing any whitespace.\n- \"then\"\n- \"fixed\"\n- month \n- day of month\n- name\n\nThe conditional holiday is only effective, if the pivot-date of the conditions falls on one of the specified days of week.\nIf the definition contains the optional \"not\", then the pivot day must *not fall* on one of the specified days of week.\n\nSyntax: `holiday if \u003cpivot month\u003e \u003cpivot day\u003e is [not] \u003cdays of week\u003e then fixed \u003cmonth\u003e \u003cday\u003e \u003cname\u003e`\n\nSamples:\n- `holiday if DEC 25 is Sat,Sun then fixed DEC 27 Bank Holiday`\n- `holiday if DEC 25 is not Fri,Sat then fixed DEC 26 Boxing day is extra day off`\n\n##### \u003ca name=\"alternative-holidays\"\u003e\u003c/a\u003eAlternative date Holidays\n\nSome countries have holidays that are moved to another date in case a specific condition is met.\nAn example is the \"Koningsdag\" in the Netherlands which occurs on April, 27th but is moved to April, 26 in case April, 27th is a Sunday.\n\nA holiday with an alternative has the tag \"either\", followed by\n- month\n- day\n- \"or\"\n- \"if\"\n- \"not\" (optional)\n- comma-separated list of pivot days of week, e.g. \"Wed,Fri\", not containing any whitespace.\n- \"then\"\n- \"fixed\"\n- alternative month\n- alternative day of month\n- name\n\nSyntax: `holiday either \u003cmonth\u003e \u003cday\u003e of if [not] \u003cdays of week\u003e then fixed \u003calternative month\u003e \u003calternative day\u003e \u003cname\u003e`\n\nSamples:\n- `holiday either 4 27 or if SUN then fixed 4 26 Koningsdag`\n- `holiday either 4 27 or if not Mon,Tue,We,Thu,Fri,Sat then fixed 4 26 Koningsdag`\n\n\n## Development\n\n### Generate / update license header\n\n```sh\n./gradlew licenseFormat\n```\n\n### Check if dependencies are up-to-date\n\n```sh\n./gradlew dependencyUpdates\n```\n\n### Building\n\nInstall to local maven repository:\n\n```sh\n./gradlew clean publishToMavenLocal\n```\n\n### Publish to Maven Central\n\n#### Preparations\n\n1. Checkout the `main` branch, create a new branch.\n2. Update version number in `build.gradle` and `README.md`.\n3. Add changes in new version to `CHANGELOG.md`.\n4. Commit and push changes.\n5. Create a new pull request, have it reviewed and merged to `main`.\n\n#### Perform the Release\n\n1. Start the release workflow\n  * Run command `gh workflow run release.yml --repo itsallcode/holiday-calculator --ref main`\n  * or go to [GitHub Actions](https://github.com/itsallcode/holiday-calculator/actions/workflows/release.yml) and start the `release.yml` workflow on branch `main`.\n2. Update title and description of the newly created [GitHub release](https://github.com/itsallcode/holiday-calculator/releases).\n3. After some time the release will be available at [Maven Central](https://repo1.maven.org/maven2/org/itsallcode/holiday-calculator/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitsallcode%2Fholiday-calculator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitsallcode%2Fholiday-calculator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitsallcode%2Fholiday-calculator/lists"}