module Data.Time.Calendar.Japanese where
import Data.List
import qualified Data.Time.Calendar as C
data Gengo = Meiji | Taisho | Showa | Heisei | Reiwa
deriving (Eq, Show, Read, Bounded, Enum)
data Day = Day Gengo Integer Int Int
deriving (Eq, Show, Read)
fromDay :: C.Day -> Maybe Day
fromDay day =
let ms = find (\(g, s) -> day >= s) $ (\g -> (g, startDayOf g))
<$> reverse [minBound .. maxBound]
in uncurry fromBaseDay <$> ms
where
(y, m, d) = C.toGregorian day
fromBaseDay g s =
let (y', _, _) = C.toGregorian s
in Day g (y - y' + 1) m d
toDay :: Day -> C.Day
toDay (Day g y m d) = C.fromGregorian (y + y' - 1) m d
where (y', _, _) = C.toGregorian (startDayOf g)
startDayOf :: Gengo -> C.Day
startDayOf Heisei = C.fromGregorian 1989 1 8
startDayOf Showa = C.fromGregorian 1926 12 26
startDayOf Taisho = C.fromGregorian 1912 7 30
startDayOf Meiji = C.fromGregorian 1868 9 4
startDayOf Reiwa = C.fromGregorian 2019 5 1
format :: Gengo -> String
format Heisei = "平成"
format Showa = "昭和"
format Taisho = "大正"
format Meiji = "明治"
format Reiwa = "令和"