{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
#if __GLASGOW_HASKELL__ >= 710
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
#endif
module Data.Time.Calendar.Quarter.Compat (
QuarterOfYear(..), addQuarters, diffQuarters,
Quarter(..),
#if __GLASGOW_HASKELL__ >= 710
pattern YearQuarter,
#endif
monthOfYearQuarter,
monthQuarter,
dayQuarter,
fromYearQuarter,
toYearQuarter,
) where
#if MIN_VERSION_time(1,11,0)
import Data.Time.Calendar (Year)
import Data.Time.Calendar.Quarter
fromYearQuarter :: Year -> QuarterOfYear -> Quarter
fromYearQuarter :: Year -> QuarterOfYear -> Quarter
fromYearQuarter = Year -> QuarterOfYear -> Quarter
YearQuarter
toYearQuarter :: Quarter -> (Year, QuarterOfYear)
toYearQuarter :: Quarter -> (Year, QuarterOfYear)
toYearQuarter (YearQuarter Year
y QuarterOfYear
m) = (Year
y, QuarterOfYear
m)
#else
import Data.Data (Data)
import Data.Typeable (Typeable)
import Text.Read (Read (..))
import Data.Fixed (mod', divMod')
import Text.ParserCombinators.ReadPrec (lift)
import Text.ParserCombinators.ReadP (char)
import Control.DeepSeq (NFData (..))
import Data.Ix (Ix (..))
import Data.Hashable (Hashable (..))
import Data.Time.Calendar
import Data.Time.Calendar.Types
import Data.Time.Calendar.Private
import Data.Time.Calendar.Month.Compat
data QuarterOfYear = Q1 | Q2 | Q3 | Q4 deriving (Eq, Ord, Data, Typeable, Read, Show)
instance NFData QuarterOfYear where
rnf Q1 = ()
rnf Q2 = ()
rnf Q3 = ()
rnf Q4 = ()
instance Hashable QuarterOfYear where
hashWithSalt salt = hashWithSalt salt . fromEnum
instance Enum QuarterOfYear where
toEnum i =
case mod' i 4 of
1 -> Q1
2 -> Q2
3 -> Q3
_ -> Q4
fromEnum Q1 = 1
fromEnum Q2 = 2
fromEnum Q3 = 3
fromEnum Q4 = 4
instance Bounded QuarterOfYear where
minBound = Q1
maxBound = Q4
newtype Quarter = MkQuarter Integer deriving (Eq, Ord, Data, Typeable)
instance NFData Quarter where
rnf (MkQuarter m) = rnf m
instance Hashable Quarter where
hashWithSalt salt (MkQuarter x) = hashWithSalt salt x
instance Enum Quarter where
succ (MkQuarter a) = MkQuarter (succ a)
pred (MkQuarter a) = MkQuarter (pred a)
toEnum = MkQuarter . toEnum
fromEnum (MkQuarter a) = fromEnum a
enumFrom (MkQuarter a) = fmap MkQuarter (enumFrom a)
enumFromThen (MkQuarter a) (MkQuarter b) = fmap MkQuarter (enumFromThen a b)
enumFromTo (MkQuarter a) (MkQuarter b) = fmap MkQuarter (enumFromTo a b)
enumFromThenTo (MkQuarter a) (MkQuarter b) (MkQuarter c) =
fmap MkQuarter (enumFromThenTo a b c)
instance Ix Quarter where
range (MkQuarter a, MkQuarter b) = fmap MkQuarter (range (a, b))
index (MkQuarter a, MkQuarter b) (MkQuarter c) = index (a, b) c
inRange (MkQuarter a, MkQuarter b) (MkQuarter c) = inRange (a, b) c
rangeSize (MkQuarter a, MkQuarter b) = rangeSize (a, b)
instance Show Quarter where
show q = case toYearQuarter q of
(y, qy) -> show4 y ++ "-" ++ show qy
instance Read Quarter where
readPrec = do
y <- readPrec
_ <- lift $ char '-'
m <- readPrec
return $ fromYearQuarter y m
addQuarters :: Integer -> Quarter -> Quarter
addQuarters n (MkQuarter a) = MkQuarter $ a + n
diffQuarters :: Quarter -> Quarter -> Integer
diffQuarters (MkQuarter a) (MkQuarter b) = a - b
#if __GLASGOW_HASKELL__ >= 710
pattern YearQuarter :: Year -> QuarterOfYear -> Quarter
pattern YearQuarter y qy <- (toYearQuarter -> (y, qy))
where YearQuarter y qy = fromYearQuarter y qy
#if __GLASGOW_HASKELL__ >= 802
{-# COMPLETE YearQuarter #-}
#endif
#endif
monthOfYearQuarter :: MonthOfYear -> QuarterOfYear
monthOfYearQuarter my | my <= 3 = Q1
monthOfYearQuarter my | my <= 6 = Q2
monthOfYearQuarter my | my <= 9 = Q3
monthOfYearQuarter _ = Q4
monthQuarter :: Month -> Quarter
monthQuarter m = case toYearMonth m of
(y, my) -> fromYearQuarter y $ monthOfYearQuarter my
dayQuarter :: Day -> Quarter
dayQuarter d = case toMonthDay d of
(m, _) -> monthQuarter m
fromYearQuarter :: Year -> QuarterOfYear -> Quarter
fromYearQuarter y qy = MkQuarter $ y * 4 + toInteger (pred $ fromEnum qy)
toYearQuarter :: Quarter -> (Year, QuarterOfYear)
toYearQuarter (MkQuarter y) = case divMod' y 4 of
(y, qy) -> (y, toEnum (succ (fromInteger qy)))
#endif