diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,24 @@
 # Changelog for `bank-holiday-germany`
 
-All notable changes to this project will be documented in this file.
-
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
 and this project adheres to the
 [Haskell Package Versioning Policy](https://pvp.haskell.org/).
 
-## Unreleased
+## [1.0.0.0] - 2024-03-14
 
-## 0.1.0.0 - YYYY-MM-DD
+Initial release
+
+## [1.0.0.1] - 2024-03-14
+
+### Added
+
+- Added version bounds of dependencies
+
+## [1.0.0.2] - 2024-03-18
+
+### Added
+
+- Add module `ExtraHolidays` for additional public holidays
+- Export `dayToYear` helper function since it is also used by the new module
+- Add tests
+- Enhance docs
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,15 +1,45 @@
 # bank-holiday-germany
 
-This module provides calculation of bank holidays in Germany.
+*See below for a German version.*
 
+This package provides calculation of bank holidays and public holidays
+in Germany.
+
 Most of these bank holidays are also public aka legal holidays
 throughout Germany. You can use `isPublicHoliday` to check if a
 holiday is also a legal holiday.
 
 Legal holidays are generally off for all employees. Bank holidays that
-are no legal holidays as well are generally only off for bank employees.
+are not legal holidays as well are generally only off for bank employees.
 
-Note: There are even more public holidays in each federal state which
-are not covered by this module.
+There are even more public holidays in each federal state which
+are (partly) covered by the `ExtraHolidays` module of this package.
 
-https://de.wikipedia.org/wiki/Bankfeiertag
+See the module documentation for more information.
+
+-----
+
+Dieses Modul behandelt deutsche Bankfeiertage und gesetzliche Feiertage.
+
+Bis auf Heilig Abend und Silvester sind alle Bankfeiertage
+gleichzeitig gesetzliche Feiertage in allen Bundesländern der
+Bundesrepublik Deutschland. Die Funktion `isPublicHoliday` prüft ob
+ein Bankfeiertag auch ein gesetzlicher Feiertag ist.
+
+Gesetzliche Feiertage sind Ländersache – abgesehen vom
+[Nationalfeiertag](https://www.bmi.bund.de/DE/themen/verfassung/staatliche-symbole/nationale-feiertage/nationale-feiertage-node.html)
+*Tag der deutschen Einheit*.
+
+Bankfeiertage sind in der Regel für Bankangestellte frei.
+Gesetzliche Feiertage sind in der Regel für alle Angestellten frei (im
+Bundesland für das sie gelten).
+
+Gesetzliche Feiertage der Bundesländer, die nicht gleichzeitig
+Bankfeiertage sind, sind im Modul `ExtraHolidays` definiert.
+
+Vorsicht: Manche gesetzliche Feiertage gelten nicht für das ganze
+Bundesland sondern nur für bestimmte Landkreise, z.B. das Friedensfest
+in Augsburg.
+
+Ein Code-Beispiel im Modul `ExtraHolidays` zeigt, wie alle Feiertage
+für ein bestimmtes Bundesland berechnet werden können.
diff --git a/bank-holiday-germany.cabal b/bank-holiday-germany.cabal
--- a/bank-holiday-germany.cabal
+++ b/bank-holiday-germany.cabal
@@ -1,7 +1,7 @@
 cabal-version:       3.6
 
 name:                bank-holiday-germany
-version:             1.0.0.1
+version:             1.0.0.2
 synopsis:            German bank holidays and public holidays
 description:         Calculation of bank holidays and most public holidays in Germany.
 homepage:            https://github.com/schoettl/bank-holiday-germany#readme
@@ -18,6 +18,7 @@
 library
   hs-source-dirs:      src
   exposed-modules:     Data.Time.Calendar.BankHoliday.Germany
+                     , Data.Time.Calendar.BankHoliday.Germany.ExtraHolidays
   build-depends:       base >= 4.7 && < 5
                      , time >= 1.12.2 && < 1.14
   default-language:    GHC2021
@@ -35,6 +36,7 @@
   type:                exitcode-stdio-1.0
   main-is:             Main.hs
   other-modules:       Data.Time.Calendar.BankHoliday.Germany
+                     , Data.Time.Calendar.BankHoliday.Germany.ExtraHolidays
   hs-source-dirs:      test
                      , src
   build-depends:       base
diff --git a/src/Data/Time/Calendar/BankHoliday/Germany.hs b/src/Data/Time/Calendar/BankHoliday/Germany.hs
--- a/src/Data/Time/Calendar/BankHoliday/Germany.hs
+++ b/src/Data/Time/Calendar/BankHoliday/Germany.hs
@@ -8,10 +8,13 @@
 holiday is also a legal holiday.
 
 Note: There are even more public holidays in each federal state which
-are not covered by this module.
+are covered by the [@ExtraHolidays@](Data.Time.Calendar.BankHoliday.Germany.ExtraHolidays)
+module of this package.
 
-https://de.wikipedia.org/wiki/Bankfeiertag
+Resources:
 
+ - https://de.wikipedia.org/wiki/Bankfeiertag
+
 -}
 
 module Data.Time.Calendar.BankHoliday.Germany (
@@ -22,28 +25,30 @@
     holidaysBetween,
     fromDay,
     toDay,
-    germanHolidayName
+    germanHolidayName,
+    yearFromDay
 ) where
 
+import Prelude
 import Data.Time.Calendar
 import Data.Maybe
 
--- | Data type specifying German bank holidays.
+-- | Data type specifying German bank holidays including Christmas Eve and New Year's Eve.
 --
 -- Note: This type cannot be an instance of class 'Ord' because due to
 -- Easter day calculation the order can change from year to year.
 data BankHoliday
-    = NewYearsDay
-    | GoodFriday   -- ^ Karfreitag
-    | EasterMonday
-    | LabourDay
-    | AscensionDay -- ^ Christi Himmelfahrt
-    | WhitMonday   -- ^ Pfingstmontag
-    | GermanUnityDay
-    | ChristmasEve
-    | ChristmasDay
-    | SecondChristmasDay
-    | NewYearsEve
+    = NewYearsDay        -- ^ Neujahrstag
+    | GoodFriday         -- ^ Karfreitag
+    | EasterMonday       -- ^ Ostermontag
+    | LabourDay          -- ^ Tag der Arbeit
+    | AscensionDay       -- ^ Christi Himmelfahrt
+    | WhitMonday         -- ^ Pfingstmontag
+    | GermanUnityDay     -- ^ Tag der Deutschen Einheit
+    | ChristmasEve       -- ^ Heilig Abend
+    | ChristmasDay       -- ^ 1​. Weihnachtsfeiertag
+    | SecondChristmasDay -- ^ 2​. Weihnachtsfeiertag
+    | NewYearsEve        -- ^ Silvestertag
     deriving (Enum, Eq, Bounded, Show, Read)
 
 
diff --git a/src/Data/Time/Calendar/BankHoliday/Germany/ExtraHolidays.hs b/src/Data/Time/Calendar/BankHoliday/Germany/ExtraHolidays.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Time/Calendar/BankHoliday/Germany/ExtraHolidays.hs
@@ -0,0 +1,145 @@
+
+{-|
+
+This module provides additional German public holidays that are not
+covered by the [bank holidays](Data.Time.Calendar.BankHoliday.Germany).
+
+Public holidays – except for
+'Data.Time.Calendar.BankHoliday.Germany.GermanUnityDay' – are under
+federal obligations in Germany („Ländersache“).
+
+Most bank holidays are also federal public holidays
+(see 'Data.Time.Calendar.BankHoliday.Germany.isPublicHoliday').
+But there are some additional extra holidays which may differ between
+federal states.
+
+For example Heilige Drei Könige is not a bank holiday but it is a
+public holiday in Bavaria.
+
+Note: The extra holidays are currently only implemented for Bavaria.
+
+Example for computing all public holidays in Bavaria (Landkreis
+Miesbach, Oberbayern) in the next couple years:
+
+@
+  import Data.List
+  import Data.Time
+  import qualified Data.Time.Calendar.BankHoliday.Germany as BH
+  import qualified Data.Time.Calendar.BankHoliday.Germany.ExtraHolidays as EH
+
+  start = fromGregorian 2024 1 1
+
+  end = fromGregorian 2026 12 31
+
+  holidays :: [[String]]
+  holidays = map (\(x,y) -> [show x, BH.germanHolidayName y]) (filter (BH.isPublicHoliday . snd) $ BH.holidaysBetween start end)
+          ++ map (\(x,y) -> [show x, EH.germanHolidayName y]) (filter ((/=EH.Friedensfest) . snd) $ EH.holidaysBetween EH.Bayern start end)
+
+  putStrLn $ unlines $ sort $ map unwords holidays
+@
+
+Resources:
+
+ - Bayern: https://www.stmi.bayern.de/suv/feiertage/
+
+-}
+
+module Data.Time.Calendar.BankHoliday.Germany.ExtraHolidays (
+    ExtraHoliday(..),
+    FederalState(..),
+    holidaysBetween,
+    fromDay,
+    toDay,
+    germanHolidayName,
+    isHolidayInState
+) where
+
+import Prelude
+import Data.Maybe
+import Data.Time.Calendar
+import Data.Time.Calendar.BankHoliday.Germany (calculateEasterSunday, yearFromDay)
+
+-- | Germany's federal states – Deutsche Bundesländer.
+data FederalState
+  = BadenWuerttemberg
+  | Bayern
+  | Berlin
+  | Brandenburg
+  | Bremen
+  | Hamburg
+  | Hessen
+  | MecklenburgVorpommern
+  | Niedersachsen
+  | NordrheinWestfalen
+  | RheinlandPfalz
+  | Saarland
+  | Sachsen
+  | SachsenAnhalt
+  | SchleswigHolstein
+  | Thueringen
+  deriving (Enum, Eq, Bounded, Show, Read)
+
+-- | Extra federal holidays, no overlap with
+-- 'Data.Time.Calendar.BankHoliday.Germany.BankHoliday'.
+-- Spezielle Feiertage der Bundesländer.
+--
+-- Note: Currently, only Bavaria's extra holidays are implemented.
+data ExtraHoliday
+  = HeiligeDreiKoenige     -- ^ Heilige Drei Könige (Bayern, …)
+  | Fronleichnam           -- ^ Fronleichnam (Bayern, …)
+  | Friedensfest           -- ^ Friedensfest (Bayern (Augsburg), …)
+  | MariaeHimmelfahrt      -- ^ Mariä Himmelfahrt (Bayern (regional), …)
+  | Allerheiligen          -- ^ Allerheiligen (Bayern, …)
+  deriving (Enum, Eq, Bounded, Show, Read)
+
+-- | Compute the date for a given year and extra holiday.
+--
+-- >>> toDay 2024 HeiligeDreiKoenige
+-- 2024-01-06
+toDay :: Year -> ExtraHoliday -> Day
+toDay year HeiligeDreiKoenige      = fromGregorian year 1 6
+toDay year Fronleichnam            = addDays 60 $ calculateEasterSunday year
+toDay year Friedensfest            = fromGregorian year 8 8
+toDay year MariaeHimmelfahrt       = fromGregorian year 8 15
+toDay year Allerheiligen           = fromGregorian year 11 1
+
+-- | Compute 'Maybe' the holiday for a given date.
+--
+-- >>> fromDay (fromGregorian 2024 11 1)
+-- Just Allerheiligen
+--
+-- >>> fromDay (fromGregorian 2024 5 5)
+-- Nothing
+fromDay :: Day -> Maybe ExtraHoliday
+fromDay day = listToMaybe $ filter (\d -> day == toDay (yearFromDay day) d) [minBound..maxBound]
+
+-- | Compute pairs of date and holiday from start to end for the given federal state.
+--
+-- >>> map snd $ holidaysBetween Bayern (fromGregorian 2024 8 8) (fromGregorian 2024 8 15)
+-- [Friedensfest,MariaeHimmelfahrt]
+holidaysBetween :: FederalState -> Day -> Day -> [(Day, ExtraHoliday)]
+holidaysBetween state start end = filter (isHolidayInState state . snd) $ catMaybes $ map (\d -> (d,) <$> fromDay d) [start..end]
+
+-- | Translate the holiday name to German.
+germanHolidayName :: ExtraHoliday -> String
+germanHolidayName d = case d of
+  HeiligeDreiKoenige     -> "Heilige Drei Könige"
+  Fronleichnam           -> "Fronleichnam"
+  Friedensfest           -> "Friedensfest"
+  MariaeHimmelfahrt      -> "Mariä Himmelfahrt"
+  Allerheiligen          -> "Allerheiligen"
+
+-- | Check if 'ExtraHoliday' is a holiday in the given federal state.
+--
+-- >>> isHolidayInState Bayern Allerheiligen
+-- True
+--
+-- >>> isHolidayInState Berlin Allerheiligen
+-- False
+isHolidayInState :: FederalState -> ExtraHoliday -> Bool
+isHolidayInState Bayern HeiligeDreiKoenige = True
+isHolidayInState Bayern Fronleichnam = True
+isHolidayInState Bayern Friedensfest = True
+isHolidayInState Bayern MariaeHimmelfahrt = True
+isHolidayInState Bayern Allerheiligen = True
+isHolidayInState _ _ = False
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -2,6 +2,7 @@
 module Main (main) where
 
 import Data.Time.Calendar.BankHoliday.Germany
+import Data.Time.Calendar.BankHoliday.Germany.ExtraHolidays qualified as EH
 import Data.Time.Calendar.WeekDate
 import Data.Time
 
@@ -21,6 +22,7 @@
 main = do
   doctest ["src/"]
   hspec $ do
+   describe "Data.Time.Calendar.BankHoliday.Germany" $ do
     describe "holidaysBetween" $ do
       it "works for Christmas" $
         holidaysBetween (day 2024 12 1) (day 2024 12 30)
@@ -59,3 +61,27 @@
       it "is False only for Chrismas Eve and New Year's Eve" $
         length (filter (not . isPublicHoliday) [minBound..maxBound])
           `shouldBe` 2
+    describe "yearFromDay" $ do
+      it "works for any year" $ hedgehog $ do
+        y <- forAll $ Gen.integral (Range.linear 0 5000)
+        m <- forAll $ Gen.integral (Range.linear 1 12)
+        d <- forAll $ Gen.integral (Range.linear 1 28)
+        yearFromDay (day y m d) === y
+
+   describe "Data.Time.Calendar.BankHoliday.Germany.ExtraHolidays" $ do
+     describe "FederalState" $
+       it "has right number of states" $
+         length [minBound .. maxBound :: EH.FederalState] `shouldBe` 16
+     describe "toDay" $
+       it "works for Fronleichnam (depending on Easter Sunday)" $ do
+         -- https://www.arbeitstage.org/feiertage/fronleichnam/
+         map (\y -> show $ EH.toDay y EH.Fronleichnam) [2024..2027]
+           `shouldBe` ["2024-05-30", "2025-06-19", "2026-06-04", "2027-05-27"]
+     describe "holidaysBetween" $ do
+       it "only has Bavaria's extra holidays" $
+         map snd (EH.holidaysBetween EH.Bayern (day 2024 11 1) (day 2024 12 31))
+           `shouldBe` [EH.Allerheiligen]
+       it "has no holidays for other states yet => otherwise, please add tests" $ do
+         let statesExceptBavaria = filter (/=EH.Bayern) [minBound..maxBound]
+         let holidays = concatMap (\x -> EH.holidaysBetween x (day 2024 1 1) (day 2024 12 31)) statesExceptBavaria
+         holidays `shouldBe` []
