{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances #-}
module Data.HodaTime.Calendar.Persian
(
calendarDate
,fromNthDay
,fromWeekDate
,Month(..)
,DayOfWeek(..)
,Persian
)
where
import Data.HodaTime.CalendarDateTime.Internal (IsCalendar(..), IsCalendarDateTime(..), CalendarDate, DayNth, DayOfMonth, Year, WeekNumber, CalendarDateTime(..), LocalTime(..), Date)
import Control.DeepSeq (NFData(..))
import Data.Hashable (Hashable(..))
import Data.HodaTime.Instant.Internal (Instant(..))
import Data.HodaTime.Calendar.Internal (mkCommonDaySetter, mkCommonMonthSetter, mkYearSetter, mkFromNthDay, mkFromWeekDate, moveByDow, dayOfWeekFromDays)
import Data.HodaTime.Calendar.Persian.Astronomical (newYearDay, minPersianYear, maxPersianYear)
import Data.Int (Int32)
import Data.Word (Word8)
import Control.Monad (guard)
monthsPerYear :: Int
monthsPerYear :: Int
monthsPerYear = Int
12
persianMonthDayOffsets :: [Int]
persianMonthDayOffsets :: [Int]
persianMonthDayOffsets = [Int
0, Int
31, Int
62, Int
93, Int
124, Int
155, Int
186, Int
216, Int
246, Int
276, Int
306, Int
336]
firstPerDayTuple :: (Integral a, Integral b, Integral c) => (a, b, c)
firstPerDayTuple :: forall a b c. (Integral a, Integral b, Integral c) => (a, b, c)
firstPerDayTuple = (a
1, b
0, c
1)
invalidDayThresh :: Integral a => a
invalidDayThresh :: forall a. Integral a => a
invalidDayThresh = Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> a) -> Int -> a
forall a b. (a -> b) -> a -> b
$ Int -> Int
forall a. Enum a => a -> a
pred Int
day0
where
(Int
y, Int
m, Int
d) = (Int, Int, Int)
forall a b c. (Integral a, Integral b, Integral c) => (a, b, c)
firstPerDayTuple :: (Year, Int, DayOfMonth)
day0 :: Int
day0 = Int -> Month Persian -> Int -> Int
yearMonthDayToDays Int
y (Int -> Month Persian
forall a. Enum a => Int -> a
toEnum Int
m) Int
d
epochDayOfWeek :: DayOfWeek Persian
epochDayOfWeek :: DayOfWeek Persian
epochDayOfWeek = DayOfWeek Persian
Wednesday
data Persian
instance IsCalendar Persian where
data Date Persian = PersianDate {-# UNPACK #-} !Int32 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Int32
deriving (Date Persian -> Date Persian -> Bool
(Date Persian -> Date Persian -> Bool)
-> (Date Persian -> Date Persian -> Bool) -> Eq (Date Persian)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Date Persian -> Date Persian -> Bool
== :: Date Persian -> Date Persian -> Bool
$c/= :: Date Persian -> Date Persian -> Bool
/= :: Date Persian -> Date Persian -> Bool
Eq, Eq (Date Persian)
Eq (Date Persian) =>
(Date Persian -> Date Persian -> Ordering)
-> (Date Persian -> Date Persian -> Bool)
-> (Date Persian -> Date Persian -> Bool)
-> (Date Persian -> Date Persian -> Bool)
-> (Date Persian -> Date Persian -> Bool)
-> (Date Persian -> Date Persian -> Date Persian)
-> (Date Persian -> Date Persian -> Date Persian)
-> Ord (Date Persian)
Date Persian -> Date Persian -> Bool
Date Persian -> Date Persian -> Ordering
Date Persian -> Date Persian -> Date Persian
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Date Persian -> Date Persian -> Ordering
compare :: Date Persian -> Date Persian -> Ordering
$c< :: Date Persian -> Date Persian -> Bool
< :: Date Persian -> Date Persian -> Bool
$c<= :: Date Persian -> Date Persian -> Bool
<= :: Date Persian -> Date Persian -> Bool
$c> :: Date Persian -> Date Persian -> Bool
> :: Date Persian -> Date Persian -> Bool
$c>= :: Date Persian -> Date Persian -> Bool
>= :: Date Persian -> Date Persian -> Bool
$cmax :: Date Persian -> Date Persian -> Date Persian
max :: Date Persian -> Date Persian -> Date Persian
$cmin :: Date Persian -> Date Persian -> Date Persian
min :: Date Persian -> Date Persian -> Date Persian
Ord)
data DayOfWeek Persian = Sunday | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday
deriving (Int -> DayOfWeek Persian -> ShowS
[DayOfWeek Persian] -> ShowS
DayOfWeek Persian -> String
(Int -> DayOfWeek Persian -> ShowS)
-> (DayOfWeek Persian -> String)
-> ([DayOfWeek Persian] -> ShowS)
-> Show (DayOfWeek Persian)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DayOfWeek Persian -> ShowS
showsPrec :: Int -> DayOfWeek Persian -> ShowS
$cshow :: DayOfWeek Persian -> String
show :: DayOfWeek Persian -> String
$cshowList :: [DayOfWeek Persian] -> ShowS
showList :: [DayOfWeek Persian] -> ShowS
Show, ReadPrec [DayOfWeek Persian]
ReadPrec (DayOfWeek Persian)
Int -> ReadS (DayOfWeek Persian)
ReadS [DayOfWeek Persian]
(Int -> ReadS (DayOfWeek Persian))
-> ReadS [DayOfWeek Persian]
-> ReadPrec (DayOfWeek Persian)
-> ReadPrec [DayOfWeek Persian]
-> Read (DayOfWeek Persian)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS (DayOfWeek Persian)
readsPrec :: Int -> ReadS (DayOfWeek Persian)
$creadList :: ReadS [DayOfWeek Persian]
readList :: ReadS [DayOfWeek Persian]
$creadPrec :: ReadPrec (DayOfWeek Persian)
readPrec :: ReadPrec (DayOfWeek Persian)
$creadListPrec :: ReadPrec [DayOfWeek Persian]
readListPrec :: ReadPrec [DayOfWeek Persian]
Read, DayOfWeek Persian -> DayOfWeek Persian -> Bool
(DayOfWeek Persian -> DayOfWeek Persian -> Bool)
-> (DayOfWeek Persian -> DayOfWeek Persian -> Bool)
-> Eq (DayOfWeek Persian)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DayOfWeek Persian -> DayOfWeek Persian -> Bool
== :: DayOfWeek Persian -> DayOfWeek Persian -> Bool
$c/= :: DayOfWeek Persian -> DayOfWeek Persian -> Bool
/= :: DayOfWeek Persian -> DayOfWeek Persian -> Bool
Eq, Eq (DayOfWeek Persian)
Eq (DayOfWeek Persian) =>
(DayOfWeek Persian -> DayOfWeek Persian -> Ordering)
-> (DayOfWeek Persian -> DayOfWeek Persian -> Bool)
-> (DayOfWeek Persian -> DayOfWeek Persian -> Bool)
-> (DayOfWeek Persian -> DayOfWeek Persian -> Bool)
-> (DayOfWeek Persian -> DayOfWeek Persian -> Bool)
-> (DayOfWeek Persian -> DayOfWeek Persian -> DayOfWeek Persian)
-> (DayOfWeek Persian -> DayOfWeek Persian -> DayOfWeek Persian)
-> Ord (DayOfWeek Persian)
DayOfWeek Persian -> DayOfWeek Persian -> Bool
DayOfWeek Persian -> DayOfWeek Persian -> Ordering
DayOfWeek Persian -> DayOfWeek Persian -> DayOfWeek Persian
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: DayOfWeek Persian -> DayOfWeek Persian -> Ordering
compare :: DayOfWeek Persian -> DayOfWeek Persian -> Ordering
$c< :: DayOfWeek Persian -> DayOfWeek Persian -> Bool
< :: DayOfWeek Persian -> DayOfWeek Persian -> Bool
$c<= :: DayOfWeek Persian -> DayOfWeek Persian -> Bool
<= :: DayOfWeek Persian -> DayOfWeek Persian -> Bool
$c> :: DayOfWeek Persian -> DayOfWeek Persian -> Bool
> :: DayOfWeek Persian -> DayOfWeek Persian -> Bool
$c>= :: DayOfWeek Persian -> DayOfWeek Persian -> Bool
>= :: DayOfWeek Persian -> DayOfWeek Persian -> Bool
$cmax :: DayOfWeek Persian -> DayOfWeek Persian -> DayOfWeek Persian
max :: DayOfWeek Persian -> DayOfWeek Persian -> DayOfWeek Persian
$cmin :: DayOfWeek Persian -> DayOfWeek Persian -> DayOfWeek Persian
min :: DayOfWeek Persian -> DayOfWeek Persian -> DayOfWeek Persian
Ord, Int -> DayOfWeek Persian
DayOfWeek Persian -> Int
DayOfWeek Persian -> [DayOfWeek Persian]
DayOfWeek Persian -> DayOfWeek Persian
DayOfWeek Persian -> DayOfWeek Persian -> [DayOfWeek Persian]
DayOfWeek Persian
-> DayOfWeek Persian -> DayOfWeek Persian -> [DayOfWeek Persian]
(DayOfWeek Persian -> DayOfWeek Persian)
-> (DayOfWeek Persian -> DayOfWeek Persian)
-> (Int -> DayOfWeek Persian)
-> (DayOfWeek Persian -> Int)
-> (DayOfWeek Persian -> [DayOfWeek Persian])
-> (DayOfWeek Persian -> DayOfWeek Persian -> [DayOfWeek Persian])
-> (DayOfWeek Persian -> DayOfWeek Persian -> [DayOfWeek Persian])
-> (DayOfWeek Persian
-> DayOfWeek Persian -> DayOfWeek Persian -> [DayOfWeek Persian])
-> Enum (DayOfWeek Persian)
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: DayOfWeek Persian -> DayOfWeek Persian
succ :: DayOfWeek Persian -> DayOfWeek Persian
$cpred :: DayOfWeek Persian -> DayOfWeek Persian
pred :: DayOfWeek Persian -> DayOfWeek Persian
$ctoEnum :: Int -> DayOfWeek Persian
toEnum :: Int -> DayOfWeek Persian
$cfromEnum :: DayOfWeek Persian -> Int
fromEnum :: DayOfWeek Persian -> Int
$cenumFrom :: DayOfWeek Persian -> [DayOfWeek Persian]
enumFrom :: DayOfWeek Persian -> [DayOfWeek Persian]
$cenumFromThen :: DayOfWeek Persian -> DayOfWeek Persian -> [DayOfWeek Persian]
enumFromThen :: DayOfWeek Persian -> DayOfWeek Persian -> [DayOfWeek Persian]
$cenumFromTo :: DayOfWeek Persian -> DayOfWeek Persian -> [DayOfWeek Persian]
enumFromTo :: DayOfWeek Persian -> DayOfWeek Persian -> [DayOfWeek Persian]
$cenumFromThenTo :: DayOfWeek Persian
-> DayOfWeek Persian -> DayOfWeek Persian -> [DayOfWeek Persian]
enumFromThenTo :: DayOfWeek Persian
-> DayOfWeek Persian -> DayOfWeek Persian -> [DayOfWeek Persian]
Enum, DayOfWeek Persian
DayOfWeek Persian
-> DayOfWeek Persian -> Bounded (DayOfWeek Persian)
forall a. a -> a -> Bounded a
$cminBound :: DayOfWeek Persian
minBound :: DayOfWeek Persian
$cmaxBound :: DayOfWeek Persian
maxBound :: DayOfWeek Persian
Bounded)
data Month Persian = Farvardin | Ordibehesht | Khordad | Tir | Mordad | Shahrivar | Mehr | Aban | Azar | Dey | Bahman | Esfand
deriving (Int -> Month Persian -> ShowS
[Month Persian] -> ShowS
Month Persian -> String
(Int -> Month Persian -> ShowS)
-> (Month Persian -> String)
-> ([Month Persian] -> ShowS)
-> Show (Month Persian)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Month Persian -> ShowS
showsPrec :: Int -> Month Persian -> ShowS
$cshow :: Month Persian -> String
show :: Month Persian -> String
$cshowList :: [Month Persian] -> ShowS
showList :: [Month Persian] -> ShowS
Show, ReadPrec [Month Persian]
ReadPrec (Month Persian)
Int -> ReadS (Month Persian)
ReadS [Month Persian]
(Int -> ReadS (Month Persian))
-> ReadS [Month Persian]
-> ReadPrec (Month Persian)
-> ReadPrec [Month Persian]
-> Read (Month Persian)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS (Month Persian)
readsPrec :: Int -> ReadS (Month Persian)
$creadList :: ReadS [Month Persian]
readList :: ReadS [Month Persian]
$creadPrec :: ReadPrec (Month Persian)
readPrec :: ReadPrec (Month Persian)
$creadListPrec :: ReadPrec [Month Persian]
readListPrec :: ReadPrec [Month Persian]
Read, Month Persian -> Month Persian -> Bool
(Month Persian -> Month Persian -> Bool)
-> (Month Persian -> Month Persian -> Bool) -> Eq (Month Persian)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Month Persian -> Month Persian -> Bool
== :: Month Persian -> Month Persian -> Bool
$c/= :: Month Persian -> Month Persian -> Bool
/= :: Month Persian -> Month Persian -> Bool
Eq, Eq (Month Persian)
Eq (Month Persian) =>
(Month Persian -> Month Persian -> Ordering)
-> (Month Persian -> Month Persian -> Bool)
-> (Month Persian -> Month Persian -> Bool)
-> (Month Persian -> Month Persian -> Bool)
-> (Month Persian -> Month Persian -> Bool)
-> (Month Persian -> Month Persian -> Month Persian)
-> (Month Persian -> Month Persian -> Month Persian)
-> Ord (Month Persian)
Month Persian -> Month Persian -> Bool
Month Persian -> Month Persian -> Ordering
Month Persian -> Month Persian -> Month Persian
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Month Persian -> Month Persian -> Ordering
compare :: Month Persian -> Month Persian -> Ordering
$c< :: Month Persian -> Month Persian -> Bool
< :: Month Persian -> Month Persian -> Bool
$c<= :: Month Persian -> Month Persian -> Bool
<= :: Month Persian -> Month Persian -> Bool
$c> :: Month Persian -> Month Persian -> Bool
> :: Month Persian -> Month Persian -> Bool
$c>= :: Month Persian -> Month Persian -> Bool
>= :: Month Persian -> Month Persian -> Bool
$cmax :: Month Persian -> Month Persian -> Month Persian
max :: Month Persian -> Month Persian -> Month Persian
$cmin :: Month Persian -> Month Persian -> Month Persian
min :: Month Persian -> Month Persian -> Month Persian
Ord, Int -> Month Persian
Month Persian -> Int
Month Persian -> [Month Persian]
Month Persian -> Month Persian
Month Persian -> Month Persian -> [Month Persian]
Month Persian -> Month Persian -> Month Persian -> [Month Persian]
(Month Persian -> Month Persian)
-> (Month Persian -> Month Persian)
-> (Int -> Month Persian)
-> (Month Persian -> Int)
-> (Month Persian -> [Month Persian])
-> (Month Persian -> Month Persian -> [Month Persian])
-> (Month Persian -> Month Persian -> [Month Persian])
-> (Month Persian
-> Month Persian -> Month Persian -> [Month Persian])
-> Enum (Month Persian)
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Month Persian -> Month Persian
succ :: Month Persian -> Month Persian
$cpred :: Month Persian -> Month Persian
pred :: Month Persian -> Month Persian
$ctoEnum :: Int -> Month Persian
toEnum :: Int -> Month Persian
$cfromEnum :: Month Persian -> Int
fromEnum :: Month Persian -> Int
$cenumFrom :: Month Persian -> [Month Persian]
enumFrom :: Month Persian -> [Month Persian]
$cenumFromThen :: Month Persian -> Month Persian -> [Month Persian]
enumFromThen :: Month Persian -> Month Persian -> [Month Persian]
$cenumFromTo :: Month Persian -> Month Persian -> [Month Persian]
enumFromTo :: Month Persian -> Month Persian -> [Month Persian]
$cenumFromThenTo :: Month Persian -> Month Persian -> Month Persian -> [Month Persian]
enumFromThenTo :: Month Persian -> Month Persian -> Month Persian -> [Month Persian]
Enum, Month Persian
Month Persian -> Month Persian -> Bounded (Month Persian)
forall a. a -> a -> Bounded a
$cminBound :: Month Persian
minBound :: Month Persian
$cmaxBound :: Month Persian
maxBound :: Month Persian
Bounded)
fromDays :: Int32 -> Date Persian
fromDays = Int32 -> Date Persian
persianFromDays
toDays :: Date Persian -> Int32
toDays = Date Persian -> Int32
persianToDays
toYmd :: Date Persian -> (Int32, Word8, Word8)
toYmd = Date Persian -> (Int32, Word8, Word8)
persianToYmd
calendarName :: Date Persian -> String
calendarName Date Persian
_ = String
"Persian"
day' :: Date Persian -> Int
day' (PersianDate Int32
_ Word8
d Word8
_ Int32
_) = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
d
setDay' :: Int -> Date Persian -> Date Persian
setDay' = Int
-> (Int -> Month Persian -> Int -> Int)
-> (Int32 -> Date Persian)
-> (Date Persian -> (Int32, Word8, Word8))
-> Int
-> Date Persian
-> Date Persian
forall mon d.
Enum mon =>
Int
-> (Int -> mon -> Int -> Int)
-> (Int32 -> d)
-> (d -> (Int32, Word8, Word8))
-> Int
-> d
-> d
mkCommonDaySetter Int
forall a. Integral a => a
invalidDayThresh Int -> Month Persian -> Int -> Int
yearMonthDayToDays Int32 -> Date Persian
persianFromDays Date Persian -> (Int32, Word8, Word8)
persianToYmd
{-# INLINE day' #-}
month' :: Date Persian -> Month Persian
month' (PersianDate Int32
_ Word8
_ Word8
m Int32
_) = Int -> Month Persian
forall a. Enum a => Int -> a
toEnum (Int -> Month Persian) -> (Word8 -> Int) -> Word8 -> Month Persian
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Month Persian) -> Word8 -> Month Persian
forall a b. (a -> b) -> a -> b
$ Word8
m
setMonthIndex' :: Int -> Date Persian -> Date Persian
setMonthIndex' = Int
-> (Int, Int, Word8)
-> (Month Persian -> Int -> Int)
-> (Int -> Month Persian -> Int -> Int)
-> (Date Persian -> (Int32, Word8, Word8))
-> (Int32 -> Date Persian)
-> Int
-> Date Persian
-> Date Persian
forall mon d.
Enum mon =>
Int
-> (Int, Int, Word8)
-> (mon -> Int -> Int)
-> (Int -> mon -> Int -> Int)
-> (d -> (Int32, Word8, Word8))
-> (Int32 -> d)
-> Int
-> d
-> d
mkCommonMonthSetter Int
monthsPerYear (Int, Int, Word8)
forall a b c. (Integral a, Integral b, Integral c) => (a, b, c)
firstPerDayTuple Month Persian -> Int -> Int
maxDaysInMonth Int -> Month Persian -> Int -> Int
yearMonthDayToDays Date Persian -> (Int32, Word8, Word8)
persianToYmd Int32 -> Date Persian
persianFromDays
{-# INLINE month' #-}
year' :: Date Persian -> Int
year' (PersianDate Int32
_ Word8
_ Word8
_ Int32
y) = Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
y
setYear' :: Int -> Date Persian -> Date Persian
setYear' = (Int, Word8, Word8)
-> (Month Persian -> Int -> Int)
-> (Int -> Month Persian -> Int -> Int)
-> (Date Persian -> (Int32, Word8, Word8))
-> (Int32 -> Date Persian)
-> Int
-> Date Persian
-> Date Persian
forall mon d.
Enum mon =>
(Int, Word8, Word8)
-> (mon -> Int -> Int)
-> (Int -> mon -> Int -> Int)
-> (d -> (Int32, Word8, Word8))
-> (Int32 -> d)
-> Int
-> d
-> d
mkYearSetter (Int, Word8, Word8)
forall a b c. (Integral a, Integral b, Integral c) => (a, b, c)
firstPerDayTuple Month Persian -> Int -> Int
maxDaysInMonth Int -> Month Persian -> Int -> Int
yearMonthDayToDays Date Persian -> (Int32, Word8, Word8)
persianToYmd Int32 -> Date Persian
persianFromDays
{-# INLINE year' #-}
dayOfWeek' :: Date Persian -> DayOfWeek Persian
dayOfWeek' (PersianDate Int32
days Word8
_ Word8
_ Int32
_) = Int -> DayOfWeek Persian
forall a. Enum a => Int -> a
toEnum (Int -> DayOfWeek Persian)
-> (Int32 -> Int) -> Int32 -> DayOfWeek Persian
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DayOfWeek Persian -> Int -> Int
forall dow. Enum dow => dow -> Int -> Int
dayOfWeekFromDays DayOfWeek Persian
epochDayOfWeek (Int -> Int) -> (Int32 -> Int) -> Int32 -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32 -> DayOfWeek Persian) -> Int32 -> DayOfWeek Persian
forall a b. (a -> b) -> a -> b
$ Int32
days
next' :: Int -> DayOfWeek Persian -> Date Persian -> Date Persian
next' Int
n DayOfWeek Persian
dow (PersianDate Int32
days Word8
_ Word8
_ Int32
_) = (Int32 -> Date Persian)
-> DayOfWeek Persian
-> Int
-> DayOfWeek Persian
-> (Int -> Int -> Int)
-> (Int -> Int -> Int)
-> (Int -> Int -> Bool)
-> Int
-> Date Persian
forall dow d.
Enum dow =>
(Int32 -> d)
-> dow
-> Int
-> dow
-> (Int -> Int -> Int)
-> (Int -> Int -> Int)
-> (Int -> Int -> Bool)
-> Int
-> d
moveByDow Int32 -> Date Persian
persianFromDays DayOfWeek Persian
epochDayOfWeek Int
n DayOfWeek Persian
dow (-) Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(>) (Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
days)
previous' :: Int -> DayOfWeek Persian -> Date Persian -> Date Persian
previous' Int
n DayOfWeek Persian
dow (PersianDate Int32
days Word8
_ Word8
_ Int32
_) = (Int32 -> Date Persian)
-> DayOfWeek Persian
-> Int
-> DayOfWeek Persian
-> (Int -> Int -> Int)
-> (Int -> Int -> Int)
-> (Int -> Int -> Bool)
-> Int
-> Date Persian
forall dow d.
Enum dow =>
(Int32 -> d)
-> dow
-> Int
-> dow
-> (Int -> Int -> Int)
-> (Int -> Int -> Int)
-> (Int -> Int -> Bool)
-> Int
-> d
moveByDow Int32 -> Date Persian
persianFromDays DayOfWeek Persian
epochDayOfWeek Int
n DayOfWeek Persian
dow Int -> Int -> Int
forall a. Num a => a -> a -> a
subtract (-) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(<) (Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
days)
instance NFData (Date Persian) where
rnf :: Date Persian -> ()
rnf (PersianDate Int32
days Word8
d Word8
m Int32
y) = Int32 -> ()
forall a. NFData a => a -> ()
rnf Int32
days () -> () -> ()
forall a b. a -> b -> b
`seq` Word8 -> ()
forall a. NFData a => a -> ()
rnf Word8
d () -> () -> ()
forall a b. a -> b -> b
`seq` Word8 -> ()
forall a. NFData a => a -> ()
rnf Word8
m () -> () -> ()
forall a b. a -> b -> b
`seq` Int32 -> ()
forall a. NFData a => a -> ()
rnf Int32
y
instance Hashable (Date Persian) where
hashWithSalt :: Int -> Date Persian -> Int
hashWithSalt Int
s (PersianDate Int32
days Word8
d Word8
m Int32
y) = Int
s Int -> Int32 -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int32
days Int -> Word8 -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Word8
d Int -> Word8 -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Word8
m Int -> Int32 -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int32
y
instance NFData (Month Persian) where
rnf :: Month Persian -> ()
rnf Month Persian
m = Month Persian
m Month Persian -> () -> ()
forall a b. a -> b -> b
`seq` ()
instance Hashable (Month Persian) where
hashWithSalt :: Int -> Month Persian -> Int
hashWithSalt Int
s = Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
s (Int -> Int) -> (Month Persian -> Int) -> Month Persian -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Month Persian -> Int
forall a. Enum a => a -> Int
fromEnum
instance NFData (DayOfWeek Persian) where
rnf :: DayOfWeek Persian -> ()
rnf DayOfWeek Persian
d = DayOfWeek Persian
d DayOfWeek Persian -> () -> ()
forall a b. a -> b -> b
`seq` ()
instance Hashable (DayOfWeek Persian) where
hashWithSalt :: Int -> DayOfWeek Persian -> Int
hashWithSalt Int
s = Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
s (Int -> Int)
-> (DayOfWeek Persian -> Int) -> DayOfWeek Persian -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DayOfWeek Persian -> Int
forall a. Enum a => a -> Int
fromEnum
instance IsCalendarDateTime Persian where
fromAdjustedInstant :: Instant -> CalendarDateTime Persian
fromAdjustedInstant (Instant Int32
days Word32
secs Word32
nsecs) = Date Persian -> LocalTime -> CalendarDateTime Persian
forall calendar.
Date calendar -> LocalTime -> CalendarDateTime calendar
CalendarDateTime (Int32 -> Date Persian
persianFromDays Int32
days) (Word32 -> Word32 -> LocalTime
LocalTime Word32
secs Word32
nsecs)
toUnadjustedInstant :: CalendarDateTime Persian -> Instant
toUnadjustedInstant (CalendarDateTime Date Persian
pd (LocalTime Word32
secs Word32
nsecs)) = Int32 -> Word32 -> Word32 -> Instant
Instant (Date Persian -> Int32
persianToDays Date Persian
pd) Word32
secs Word32
nsecs
persianFromDays :: Int32 -> Date Persian
persianFromDays :: Int32 -> Date Persian
persianFromDays Int32
days = Int32 -> Word8 -> Word8 -> Int32 -> Date Persian
PersianDate Int32
days Word8
d Word8
m Int32
y
where (Int32
y, Word8
m, Word8
d) = Int32 -> (Int32, Word8, Word8)
daysToYearMonthDay Int32
days
persianToDays :: Date Persian -> Int32
persianToDays :: Date Persian -> Int32
persianToDays (PersianDate Int32
days Word8
_ Word8
_ Int32
_) = Int32
days
persianToYmd :: Date Persian -> (Int32, Word8, Word8)
persianToYmd :: Date Persian -> (Int32, Word8, Word8)
persianToYmd (PersianDate Int32
_ Word8
d Word8
m Int32
y) = (Int32
y, Word8
m, Word8
d)
calendarDate :: DayOfMonth -> Month Persian -> Year -> Maybe (CalendarDate Persian)
calendarDate :: Int -> Month Persian -> Int -> Maybe (Date Persian)
calendarDate Int
d Month Persian
m Int
y = do
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
minPersianYear Bool -> Bool -> Bool
&& Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
maxPersianYear
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Month Persian -> Int -> Int
maxDaysInMonth Month Persian
m Int
y
Date Persian -> Maybe (Date Persian)
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (Date Persian -> Maybe (Date Persian))
-> Date Persian -> Maybe (Date Persian)
forall a b. (a -> b) -> a -> b
$ Int32 -> Date Persian
persianFromDays (Int -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int32) -> Int -> Int32
forall a b. (a -> b) -> a -> b
$ Int -> Month Persian -> Int -> Int
yearMonthDayToDays Int
y Month Persian
m Int
d)
fromNthDay :: DayNth -> DayOfWeek Persian -> Month Persian -> Year -> Maybe (CalendarDate Persian)
fromNthDay :: DayNth
-> DayOfWeek Persian
-> Month Persian
-> Int
-> Maybe (Date Persian)
fromNthDay = Int
-> DayOfWeek Persian
-> (Int -> Month Persian -> Int -> Int)
-> (Month Persian -> Int -> Int)
-> (Int32 -> Date Persian)
-> DayNth
-> DayOfWeek Persian
-> Month Persian
-> Int
-> Maybe (Date Persian)
forall mon dow d.
(Enum mon, Enum dow) =>
Int
-> dow
-> (Int -> mon -> Int -> Int)
-> (mon -> Int -> Int)
-> (Int32 -> d)
-> DayNth
-> dow
-> mon
-> Int
-> Maybe d
mkFromNthDay Int
forall a. Integral a => a
invalidDayThresh DayOfWeek Persian
epochDayOfWeek Int -> Month Persian -> Int -> Int
yearMonthDayToDays Month Persian -> Int -> Int
maxDaysInMonth Int32 -> Date Persian
persianFromDays
fromWeekDate :: WeekNumber -> DayOfWeek Persian -> Year -> Maybe (CalendarDate Persian)
fromWeekDate :: Int -> DayOfWeek Persian -> Int -> Maybe (Date Persian)
fromWeekDate = Int
-> DayOfWeek Persian
-> (Int -> Month Persian -> Int -> Int)
-> (Int32 -> Date Persian)
-> Int
-> DayOfWeek Persian
-> Int
-> DayOfWeek Persian
-> Int
-> Maybe (Date Persian)
forall mon dow d.
(Enum mon, Enum dow) =>
Int
-> dow
-> (Int -> mon -> Int -> Int)
-> (Int32 -> d)
-> Int
-> dow
-> Int
-> dow
-> Int
-> Maybe d
mkFromWeekDate Int
forall a. Integral a => a
invalidDayThresh DayOfWeek Persian
epochDayOfWeek Int -> Month Persian -> Int -> Int
yearMonthDayToDays Int32 -> Date Persian
persianFromDays Int
1 DayOfWeek Persian
Saturday
isLeapYear :: Year -> Bool
isLeapYear :: Int -> Bool
isLeapYear Int
y = Int -> Int
newYearDay (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int -> Int
newYearDay (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
y) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
366
maxDaysInMonth :: Month Persian -> Year -> Int
maxDaysInMonth :: Month Persian -> Int -> Int
maxDaysInMonth Month Persian
R:MonthPersian
Esfand Int
y
| Int -> Bool
isLeapYear Int
y = Int
30
| Bool
otherwise = Int
29
maxDaysInMonth Month Persian
m Int
_
| Month Persian -> Int
forall a. Enum a => a -> Int
fromEnum Month Persian
m Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
6 = Int
31
| Bool
otherwise = Int
30
yearMonthDayToDays :: Year -> Month Persian -> DayOfMonth -> Int
yearMonthDayToDays :: Int -> Month Persian -> Int -> Int
yearMonthDayToDays Int
y Month Persian
m Int
d = Int -> Int
newYearDay (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
y) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int]
persianMonthDayOffsets [Int] -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!! Month Persian -> Int
forall a. Enum a => a -> Int
fromEnum Month Persian
m Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
d Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
daysToYearMonthDay :: Int32 -> (Int32, Word8, Word8)
daysToYearMonthDay :: Int32 -> (Int32, Word8, Word8)
daysToYearMonthDay Int32
flatDays = (Int -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
y, Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
m, Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
d)
where
day :: Int
day = Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
flatDays :: Int
yEst :: Int
yEst = Int
minPersianYear Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
day Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int -> Int
newYearDay Int
minPersianYear) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
365
y :: Int
y = Int -> Int
adjust Int
yEst
adjust :: Int -> Int
adjust Int
yy
| Int -> Int
newYearDay Int
yy Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
day = Int -> Int
adjust (Int
yy Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
| Int -> Int
newYearDay (Int
yy Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
day = Int -> Int
adjust (Int
yy Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
| Bool
otherwise = Int
yy
dayOfYear :: Int
dayOfYear = Int
day Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int -> Int
newYearDay Int
y
(Int
m, Int
d)
| Int
dayOfYear Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
365 = (Int
11, Int
30)
| Int
dayOfYear Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
31 = let (Int
mm, Int
dd) = Int
dayOfYear Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
`divMod` Int
31 in (Int
mm, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
| Bool
otherwise = let (Int
mm, Int
dd) = (Int
dayOfYear Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
6 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
31) Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
`divMod` Int
30 in (Int
mm Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6, Int
dd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)