diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ae5b23d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,31 @@ +name: CI + +on: + pull_request: + merge_group: + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v5 + + - name: init rust-toolchain + # somehow rustup show will take care to initialize the version based on the toolchain file + run: rustup show + + - name: Create iCal file for comparison + run: | + cargo run --release > ./output/feiertage_cmp.ical + + - name: Check that generated iCal file is up to date + run: > + diff + <(grep -vE "DTSTAMP|CREATED|LAST-MODIFIED" ./output/feiertage.ical) + <(grep -vE "DTSTAMP|CREATED|LAST-MODIFIED" ./output/feiertage_cmp.ical) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 2bcbdfc..fffd6d3 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -11,22 +11,13 @@ env: jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v2 - - - name: init rust-toolchain - # somehow rustup show will take care to initialize the version based on the toolchain file - run: rustup show - - - name: Create iCal file - run: | - cargo run --release > ./output/feiertage.ical - rm ./output/.gitignore + - uses: actions/checkout@v5 - name: Deploy - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 if: ${{ github.ref == 'refs/heads/main' }} with: github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/Cargo.lock b/Cargo.lock index 8a2a141..e47c084 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,50 +1,46 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "anyhow" -version = "1.0.65" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" - -[[package]] -name = "bstr" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" -dependencies = [ - "lazy_static", - "memchr", - "regex-automata", - "serde", -] +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "csv" -version = "1.1.6" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" +checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" dependencies = [ - "bstr", "csv-core", - "itoa 0.4.8", + "itoa", "ryu", - "serde", + "serde_core", ] [[package]] name = "csv-core" -version = "0.1.10" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" dependencies = [ "memchr", ] +[[package]] +name = "deranged" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +dependencies = [ + "powerfmt", +] + [[package]] name = "feiertage" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "csv", @@ -54,87 +50,76 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.8" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] -name = "itoa" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.135" +name = "memchr" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] -name = "memchr" -version = "2.5.0" +name = "num-conv" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] -name = "num_threads" -version = "0.1.6" +name = "powerfmt" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" -dependencies = [ - "libc", -] +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "proc-macro2" -version = "1.0.46" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" +checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] [[package]] -name = "regex-automata" -version = "0.1.10" +name = "ryu" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" [[package]] -name = "ryu" -version = "1.0.11" +name = "serde" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] [[package]] -name = "serde" -version = "1.0.145" +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.145" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -143,9 +128,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.102" +version = "2.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" +checksum = "678faa00651c9eb72dd2020cbdf275d92eccb2400d568e419efdd64838145cb4" dependencies = [ "proc-macro2", "quote", @@ -154,24 +139,37 @@ dependencies = [ [[package]] name = "time" -version = "0.3.15" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ - "itoa 1.0.4", - "libc", - "num_threads", + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", "time-macros", ] +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + [[package]] name = "time-macros" -version = "0.2.4" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" diff --git a/Cargo.toml b/Cargo.toml index 3acd141..a03cf01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "feiertage" -version = "0.1.0" -edition = "2021" +version = "0.2.0" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] anyhow = "1.0" -csv = "1.1" +csv = "1.4" serde = { version = "1.0", features = ["derive"] } time = { version = "0.3", features = ["formatting", "macros", "parsing"] } diff --git a/input/NRW.csv b/input/NRW.csv index 191e00d..22beab4 100644 --- a/input/NRW.csv +++ b/input/NRW.csv @@ -65,7 +65,6 @@ Tag der Deutschen Einheit So, 03.10.2027 Allerheiligen Mo, 01.11.2027 Weihnachten Sa, 25.12.2027 2. Weihnachtstag So, 26.12.2027 -Feiertag Datum Neujahr Sa, 01.01.2028 Karfreitag Fr, 14.04.2028 Ostermontag Mo, 17.04.2028 diff --git a/output/.gitignore b/output/.gitignore deleted file mode 100644 index 3ffccc1..0000000 --- a/output/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory… -* -# …except this file -!.gitignore \ No newline at end of file diff --git a/output/feiertage.ical b/output/feiertage.ical new file mode 100644 index 0000000..be9661d --- /dev/null +++ b/output/feiertage.ical @@ -0,0 +1,1087 @@ +BEGIN:VCALENDAR +PRODID:-//Geo Engine GmbH//Geo Engine Feiertage//DE +VERSION:2.0 +CALSCALE:GREGORIAN +METHOD:PUBLISH +X-WR-CALNAME:Feiertage in Deutschland für die Geo Engine GmbH +X-WR-TIMEZONE:UTC +X-WR-CALDESC:Feiertage in Deutschland für die Geo Engine GmbH +BEGIN:VEVENT +DTSTART;VALUE=DATE:20220101 +DTEND;VALUE=DATE:20220102 +DTSTAMP:20260105T074756Z +UID:20220101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Neujahr +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20220415 +DTEND;VALUE=DATE:20220416 +DTSTAMP:20260105T074756Z +UID:20220415#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Karfreitag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20220418 +DTEND;VALUE=DATE:20220419 +DTSTAMP:20260105T074756Z +UID:20220418#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Ostermontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20220501 +DTEND;VALUE=DATE:20220502 +DTSTAMP:20260105T074756Z +UID:20220501#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Arbeit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20220526 +DTEND;VALUE=DATE:20220527 +DTSTAMP:20260105T074756Z +UID:20220526#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Christi Himmelfahrt +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20220606 +DTEND;VALUE=DATE:20220607 +DTSTAMP:20260105T074756Z +UID:20220606#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Pfingstmontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20220616 +DTEND;VALUE=DATE:20220617 +DTSTAMP:20260105T074756Z +UID:20220616#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Fronleichnam +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20221003 +DTEND;VALUE=DATE:20221004 +DTSTAMP:20260105T074756Z +UID:20221003#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Deutschen Einheit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20221101 +DTEND;VALUE=DATE:20221102 +DTSTAMP:20260105T074756Z +UID:20221101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Allerheiligen +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20221225 +DTEND;VALUE=DATE:20221226 +DTSTAMP:20260105T074756Z +UID:20221225#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Weihnachten +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20221226 +DTEND;VALUE=DATE:20221227 +DTSTAMP:20260105T074756Z +UID:20221226#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:2. Weihnachtstag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20230101 +DTEND;VALUE=DATE:20230102 +DTSTAMP:20260105T074756Z +UID:20230101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Neujahr +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20230407 +DTEND;VALUE=DATE:20230408 +DTSTAMP:20260105T074756Z +UID:20230407#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Karfreitag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20230410 +DTEND;VALUE=DATE:20230411 +DTSTAMP:20260105T074756Z +UID:20230410#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Ostermontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20230501 +DTEND;VALUE=DATE:20230502 +DTSTAMP:20260105T074756Z +UID:20230501#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Arbeit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20230518 +DTEND;VALUE=DATE:20230519 +DTSTAMP:20260105T074756Z +UID:20230518#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Christi Himmelfahrt +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20230529 +DTEND;VALUE=DATE:20230530 +DTSTAMP:20260105T074756Z +UID:20230529#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Pfingstmontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20230608 +DTEND;VALUE=DATE:20230609 +DTSTAMP:20260105T074756Z +UID:20230608#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Fronleichnam +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20231003 +DTEND;VALUE=DATE:20231004 +DTSTAMP:20260105T074756Z +UID:20231003#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Deutschen Einheit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20231101 +DTEND;VALUE=DATE:20231102 +DTSTAMP:20260105T074756Z +UID:20231101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Allerheiligen +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20231225 +DTEND;VALUE=DATE:20231226 +DTSTAMP:20260105T074756Z +UID:20231225#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Weihnachten +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20231226 +DTEND;VALUE=DATE:20231227 +DTSTAMP:20260105T074756Z +UID:20231226#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:2. Weihnachtstag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240101 +DTEND;VALUE=DATE:20240102 +DTSTAMP:20260105T074756Z +UID:20240101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Neujahr +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240329 +DTEND;VALUE=DATE:20240330 +DTSTAMP:20260105T074756Z +UID:20240329#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Karfreitag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240401 +DTEND;VALUE=DATE:20240402 +DTSTAMP:20260105T074756Z +UID:20240401#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Ostermontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240501 +DTEND;VALUE=DATE:20240502 +DTSTAMP:20260105T074756Z +UID:20240501#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Arbeit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240509 +DTEND;VALUE=DATE:20240510 +DTSTAMP:20260105T074756Z +UID:20240509#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Christi Himmelfahrt +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240520 +DTEND;VALUE=DATE:20240521 +DTSTAMP:20260105T074756Z +UID:20240520#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Pfingstmontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240530 +DTEND;VALUE=DATE:20240531 +DTSTAMP:20260105T074756Z +UID:20240530#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Fronleichnam +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20241003 +DTEND;VALUE=DATE:20241004 +DTSTAMP:20260105T074756Z +UID:20241003#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Deutschen Einheit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20241101 +DTEND;VALUE=DATE:20241102 +DTSTAMP:20260105T074756Z +UID:20241101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Allerheiligen +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20241225 +DTEND;VALUE=DATE:20241226 +DTSTAMP:20260105T074756Z +UID:20241225#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Weihnachten +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20241226 +DTEND;VALUE=DATE:20241227 +DTSTAMP:20260105T074756Z +UID:20241226#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:2. Weihnachtstag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20250101 +DTEND;VALUE=DATE:20250102 +DTSTAMP:20260105T074756Z +UID:20250101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Neujahr +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20250418 +DTEND;VALUE=DATE:20250419 +DTSTAMP:20260105T074756Z +UID:20250418#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Karfreitag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20250421 +DTEND;VALUE=DATE:20250422 +DTSTAMP:20260105T074756Z +UID:20250421#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Ostermontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20250501 +DTEND;VALUE=DATE:20250502 +DTSTAMP:20260105T074756Z +UID:20250501#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Arbeit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20250529 +DTEND;VALUE=DATE:20250530 +DTSTAMP:20260105T074756Z +UID:20250529#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Christi Himmelfahrt +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20250609 +DTEND;VALUE=DATE:20250610 +DTSTAMP:20260105T074756Z +UID:20250609#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Pfingstmontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20250619 +DTEND;VALUE=DATE:20250620 +DTSTAMP:20260105T074756Z +UID:20250619#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Fronleichnam +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20251003 +DTEND;VALUE=DATE:20251004 +DTSTAMP:20260105T074756Z +UID:20251003#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Deutschen Einheit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20251101 +DTEND;VALUE=DATE:20251102 +DTSTAMP:20260105T074756Z +UID:20251101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Allerheiligen +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20251225 +DTEND;VALUE=DATE:20251226 +DTSTAMP:20260105T074756Z +UID:20251225#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Weihnachten +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20251226 +DTEND;VALUE=DATE:20251227 +DTSTAMP:20260105T074756Z +UID:20251226#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:2. Weihnachtstag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20260101 +DTEND;VALUE=DATE:20260102 +DTSTAMP:20260105T074756Z +UID:20260101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Neujahr +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20260403 +DTEND;VALUE=DATE:20260404 +DTSTAMP:20260105T074756Z +UID:20260403#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Karfreitag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20260406 +DTEND;VALUE=DATE:20260407 +DTSTAMP:20260105T074756Z +UID:20260406#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Ostermontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20260501 +DTEND;VALUE=DATE:20260502 +DTSTAMP:20260105T074756Z +UID:20260501#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Arbeit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20260514 +DTEND;VALUE=DATE:20260515 +DTSTAMP:20260105T074756Z +UID:20260514#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Christi Himmelfahrt +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20260525 +DTEND;VALUE=DATE:20260526 +DTSTAMP:20260105T074756Z +UID:20260525#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Pfingstmontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20260604 +DTEND;VALUE=DATE:20260605 +DTSTAMP:20260105T074756Z +UID:20260604#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Fronleichnam +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20261003 +DTEND;VALUE=DATE:20261004 +DTSTAMP:20260105T074756Z +UID:20261003#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Deutschen Einheit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20261101 +DTEND;VALUE=DATE:20261102 +DTSTAMP:20260105T074756Z +UID:20261101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Allerheiligen +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20261225 +DTEND;VALUE=DATE:20261226 +DTSTAMP:20260105T074756Z +UID:20261225#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Weihnachten +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20261226 +DTEND;VALUE=DATE:20261227 +DTSTAMP:20260105T074756Z +UID:20261226#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:2. Weihnachtstag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20270101 +DTEND;VALUE=DATE:20270102 +DTSTAMP:20260105T074756Z +UID:20270101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Neujahr +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20270326 +DTEND;VALUE=DATE:20270327 +DTSTAMP:20260105T074756Z +UID:20270326#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Karfreitag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20270329 +DTEND;VALUE=DATE:20270330 +DTSTAMP:20260105T074756Z +UID:20270329#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Ostermontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20270501 +DTEND;VALUE=DATE:20270502 +DTSTAMP:20260105T074756Z +UID:20270501#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Arbeit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20270506 +DTEND;VALUE=DATE:20270507 +DTSTAMP:20260105T074756Z +UID:20270506#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Christi Himmelfahrt +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20270517 +DTEND;VALUE=DATE:20270518 +DTSTAMP:20260105T074756Z +UID:20270517#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Pfingstmontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20270527 +DTEND;VALUE=DATE:20270528 +DTSTAMP:20260105T074756Z +UID:20270527#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Fronleichnam +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20271003 +DTEND;VALUE=DATE:20271004 +DTSTAMP:20260105T074756Z +UID:20271003#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Deutschen Einheit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20271101 +DTEND;VALUE=DATE:20271102 +DTSTAMP:20260105T074756Z +UID:20271101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Allerheiligen +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20271225 +DTEND;VALUE=DATE:20271226 +DTSTAMP:20260105T074756Z +UID:20271225#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Weihnachten +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20271226 +DTEND;VALUE=DATE:20271227 +DTSTAMP:20260105T074756Z +UID:20271226#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:2. Weihnachtstag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20280101 +DTEND;VALUE=DATE:20280102 +DTSTAMP:20260105T074756Z +UID:20280101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Neujahr +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20280414 +DTEND;VALUE=DATE:20280415 +DTSTAMP:20260105T074756Z +UID:20280414#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Karfreitag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20280417 +DTEND;VALUE=DATE:20280418 +DTSTAMP:20260105T074756Z +UID:20280417#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Ostermontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20280501 +DTEND;VALUE=DATE:20280502 +DTSTAMP:20260105T074756Z +UID:20280501#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Arbeit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20280525 +DTEND;VALUE=DATE:20280526 +DTSTAMP:20260105T074756Z +UID:20280525#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Christi Himmelfahrt +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20280605 +DTEND;VALUE=DATE:20280606 +DTSTAMP:20260105T074756Z +UID:20280605#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Pfingstmontag +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20280615 +DTEND;VALUE=DATE:20280616 +DTSTAMP:20260105T074756Z +UID:20280615#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Fronleichnam +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20281003 +DTEND;VALUE=DATE:20281004 +DTSTAMP:20260105T074756Z +UID:20281003#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Tag der Deutschen Einheit +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20281101 +DTEND;VALUE=DATE:20281102 +DTSTAMP:20260105T074756Z +UID:20281101#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Allerheiligen +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20281225 +DTEND;VALUE=DATE:20281226 +DTSTAMP:20260105T074756Z +UID:20281225#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Weihnachten +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20281226 +DTEND;VALUE=DATE:20281227 +DTSTAMP:20260105T074756Z +UID:20281226#feiertage +CLASS:PUBLIC +CREATED:20260105T074756Z +DESCRIPTION:(HE, NRW) +LAST-MODIFIED:20260105T074756Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:2. Weihnachtstag +TRANSP:TRANSPARENT +END:VEVENT +END:VCALENDAR diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 8b4a123..e6753c5 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "stable" +channel = "1.92" components = ["cargo", "rustfmt", "rust-src", "clippy"] diff --git a/src/main.rs b/src/main.rs index b9a6d50..d23c7d4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ -use serde::{de, Deserialize, Deserializer}; +use anyhow::Context; +use serde::{Deserialize, Deserializer, de}; use std::collections::BTreeSet; use std::ffi::OsStr; use std::fmt::Debug; @@ -6,7 +7,7 @@ use std::fs::{self}; use std::io::Write; use std::path::PathBuf; use std::{io::LineWriter, path::Path}; -use time::{macros::format_description, Date}; +use time::{Date, macros::format_description}; use time::{Duration, OffsetDateTime}; fn main() { @@ -18,7 +19,11 @@ fn main() { let parsed_csvs = csv_paths .iter() - .map(|path| parse_csv(path, extract_file_name(path)).unwrap()) + .map(|path| { + parse_csv(path, extract_file_name(path)) + .context(format!("Failed to parse CSV `{}`", path.display())) + .unwrap() + }) .collect::>(); let merged_days = merge(&parsed_csvs); @@ -39,10 +44,7 @@ fn csv_paths(directory: &Path) -> Vec { .into_iter() .filter_map(Result::ok) .map(|e| e.path()) - .filter(|path| { - path.extension() - .map_or(false, |extension| extension == "csv") - }) + .filter(|path| path.extension().is_some_and(|extension| extension == "csv")) .collect() } @@ -141,12 +143,12 @@ fn merge(inputs: &[Vec]) -> Vec { { // advance all iterators with that date for it in &mut iterators { - if let Some(feiertag) = it.peek() { - if feiertag.date == next_feiertag.date { - next_feiertag.lands.append(&mut feiertag.lands.clone()); + if let Some(feiertag) = it.peek() + && feiertag.date == next_feiertag.date + { + next_feiertag.lands.append(&mut feiertag.lands.clone()); - it.next(); - } + it.next(); } }