0 | module Data.Time.Date
3 | import Data.Refined.Integer
4 | import Derive.Prelude
5 | import Derive.Refined
8 | %language ElabReflection
18 | {auto 0 valid : FromTo 0 9999 year}
20 | %runElab derive "Year" [Show, Eq, Ord, RefinedInteger]
23 | Interpolation Year where
24 | interpolate (Y y) = padLeft 4 '0' $
show y
27 | isLeap : Year -> Bool
28 | isLeap (Y y) = mod y 4 == 0 && (mod y 100 /= 0 || mod y 400 == 0)
35 | data Month : Type where
49 | %runElab derive "Month" [Show, Eq, Ord]
52 | Interpolation Month where
53 | interpolate m = padLeft 2 '0' $
show (conIndexMonth m + 1)
56 | DaysInMonth : Month -> Integer
57 | DaysInMonth JAN = 31
58 | DaysInMonth FEB = 29
59 | DaysInMonth MAR = 31
60 | DaysInMonth APR = 30
61 | DaysInMonth MAY = 31
62 | DaysInMonth JUN = 30
63 | DaysInMonth JUL = 31
64 | DaysInMonth AUG = 31
65 | DaysInMonth SEP = 30
66 | DaysInMonth OCT = 31
67 | DaysInMonth NOV = 30
68 | DaysInMonth DEC = 31
71 | intToMonth : Integer -> Maybe Month
72 | intToMonth 1 = Just JAN
73 | intToMonth 2 = Just FEB
74 | intToMonth 3 = Just MAR
75 | intToMonth 4 = Just APR
76 | intToMonth 5 = Just MAY
77 | intToMonth 6 = Just JUN
78 | intToMonth 7 = Just JUL
79 | intToMonth 8 = Just AUG
80 | intToMonth 9 = Just SEP
81 | intToMonth 10 = Just OCT
82 | intToMonth 11 = Just NOV
83 | intToMonth 12 = Just DEC
84 | intToMonth _ = Nothing
91 | record Day (m : Month) where
94 | {auto 0 valid : FromTo 1 (DaysInMonth m) day}
96 | %runElab deriveIndexed "Day" [Show, Eq, Ord]
99 | refineDay : {m : _} -> Integer -> Maybe (Day m)
100 | refineDay n = case hdec0 {p = FromTo 1 (DaysInMonth m)} n of
101 | Nothing0 => Nothing
102 | Just0 v => Just $
D n
109 | -> {auto 0 p : IsJust (refineDay {m} $
cast n)}
111 | fromInteger n = fromJust $
refineDay (cast n)
114 | Interpolation (Day m) where
115 | interpolate (D d) = padLeft 2 '0' $
show d
122 | record LocalDate where
130 | MkDate y1 m1 d1 == MkDate y2 m2 d2 =
131 | y1 == y2 && m1 == m2 && d1.day == d2.day
134 | Ord LocalDate where
135 | compare (MkDate y1 m1 d1) (MkDate y2 m2 d2) =
136 | if y1 /= y2 then compare y1 y2
137 | else if m1 /= m2 then compare m1 m2
138 | else compare d1.day d2.day
140 | %runElab derive "LocalDate" [Show]
143 | Interpolation LocalDate where
144 | interpolate (MkDate y m d) = "\{y}-\{m}-\{d}"