{-# LANGUAGE UnicodeSyntax, DeriveDataTypeable #-}
{-# LANGUAGE CPP #-}

module Data.Dates.Types
  (DateTime (..),
   Time (..),
   months, capitalize
  ) where

import Prelude.Unicode
import Data.Semigroup
import Data.Monoid
import Data.Char
import Data.Generics

-- | Date / Time
data DateTime =
  DateTime {
    DateTime -> Int
year    Int,
    DateTime -> Int
month   Int,
    DateTime -> Int
day     Int,
    DateTime -> Int
hour    Int,
    DateTime -> Int
minute  Int,
    DateTime -> Int
second  Int }
  deriving (DateTime -> DateTime -> Bool
(DateTime -> DateTime -> Bool)
-> (DateTime -> DateTime -> Bool) -> Eq DateTime
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DateTime -> DateTime -> Bool
$c/= :: DateTime -> DateTime -> Bool
== :: DateTime -> DateTime -> Bool
$c== :: DateTime -> DateTime -> Bool
Eq,Eq DateTime
Eq DateTime
-> (DateTime -> DateTime -> Ordering)
-> (DateTime -> DateTime -> Bool)
-> (DateTime -> DateTime -> Bool)
-> (DateTime -> DateTime -> Bool)
-> (DateTime -> DateTime -> Bool)
-> (DateTime -> DateTime -> DateTime)
-> (DateTime -> DateTime -> DateTime)
-> Ord DateTime
DateTime -> DateTime -> Bool
DateTime -> DateTime -> Ordering
DateTime -> DateTime -> DateTime
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
min :: DateTime -> DateTime -> DateTime
$cmin :: DateTime -> DateTime -> DateTime
max :: DateTime -> DateTime -> DateTime
$cmax :: DateTime -> DateTime -> DateTime
>= :: DateTime -> DateTime -> Bool
$c>= :: DateTime -> DateTime -> Bool
> :: DateTime -> DateTime -> Bool
$c> :: DateTime -> DateTime -> Bool
<= :: DateTime -> DateTime -> Bool
$c<= :: DateTime -> DateTime -> Bool
< :: DateTime -> DateTime -> Bool
$c< :: DateTime -> DateTime -> Bool
compare :: DateTime -> DateTime -> Ordering
$ccompare :: DateTime -> DateTime -> Ordering
$cp1Ord :: Eq DateTime
Ord,Typeable DateTime
DataType
Constr
Typeable DateTime
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DateTime -> c DateTime)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DateTime)
-> (DateTime -> Constr)
-> (DateTime -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DateTime))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DateTime))
-> ((forall b. Data b => b -> b) -> DateTime -> DateTime)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DateTime -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DateTime -> r)
-> (forall u. (forall d. Data d => d -> u) -> DateTime -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> DateTime -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DateTime -> m DateTime)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DateTime -> m DateTime)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DateTime -> m DateTime)
-> Data DateTime
DateTime -> DataType
DateTime -> Constr
(forall b. Data b => b -> b) -> DateTime -> DateTime
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DateTime -> c DateTime
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DateTime
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> DateTime -> u
forall u. (forall d. Data d => d -> u) -> DateTime -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DateTime -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DateTime -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DateTime -> m DateTime
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DateTime -> m DateTime
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DateTime
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DateTime -> c DateTime
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DateTime)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DateTime)
$cDateTime :: Constr
$tDateTime :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> DateTime -> m DateTime
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DateTime -> m DateTime
gmapMp :: (forall d. Data d => d -> m d) -> DateTime -> m DateTime
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DateTime -> m DateTime
gmapM :: (forall d. Data d => d -> m d) -> DateTime -> m DateTime
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DateTime -> m DateTime
gmapQi :: Int -> (forall d. Data d => d -> u) -> DateTime -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DateTime -> u
gmapQ :: (forall d. Data d => d -> u) -> DateTime -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> DateTime -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DateTime -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DateTime -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DateTime -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DateTime -> r
gmapT :: (forall b. Data b => b -> b) -> DateTime -> DateTime
$cgmapT :: (forall b. Data b => b -> b) -> DateTime -> DateTime
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DateTime)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c DateTime)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c DateTime)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DateTime)
dataTypeOf :: DateTime -> DataType
$cdataTypeOf :: DateTime -> DataType
toConstr :: DateTime -> Constr
$ctoConstr :: DateTime -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DateTime
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DateTime
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DateTime -> c DateTime
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DateTime -> c DateTime
$cp1Data :: Typeable DateTime
Data,Typeable)

-- | 12 months names.
months  [String]
months :: [String]
months = [String
"january",
          String
"february",
          String
"march",
          String
"april",
          String
"may",
          String
"june",
          String
"july",
          String
"august",
          String
"september",
          String
"october",
          String
"november",
          String
"december"]

-- | capitalize first letter of the string
capitalize  String  String
capitalize :: String -> String
capitalize [] = []
capitalize (Char
x:String
xs) = (Char -> Char
toUpper Char
x)Char -> String -> String
forall a. a -> [a] -> [a]
:String
xs

-- | Show name of given month
showMonth   Int  String
showMonth :: Int -> String
showMonth Int
i = String -> String
capitalize (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ [String]
months [String] -> Int -> String
forall a. [a] -> Int -> a
!! (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)

instance Show DateTime where
  show :: DateTime -> String
show (DateTime Int
y Int
m Int
d Int
h Int
mins Int
s) = 
    Int -> String
forall a. Show a => a -> String
show Int
d String -> String -> String
forall α. [α] -> [α] -> [α]
 String
" " String -> String -> String
forall α. [α] -> [α] -> [α]
 Int -> String
showMonth Int
m String -> String -> String
forall α. [α] -> [α] -> [α]
 String
" " String -> String -> String
forall α. [α] -> [α] -> [α]
 Int -> String
forall a. Show a => a -> String
show Int
y String -> String -> String
forall α. [α] -> [α] -> [α]
 String
", " String -> String -> String
forall α. [α] -> [α] -> [α]

      Int -> String
forall a. Show a => a -> String
show Int
h String -> String -> String
forall α. [α] -> [α] -> [α]
 String
":" String -> String -> String
forall α. [α] -> [α] -> [α]
 Int -> String
forall a. Show a => a -> String
show Int
mins String -> String -> String
forall α. [α] -> [α] -> [α]
 String
":" String -> String -> String
forall α. [α] -> [α] -> [α]
 Int -> String
forall a. Show a => a -> String
show Int
s

-- | Only time, without date
data Time = 
  Time {
    Time -> Int
tHour    Int,
    Time -> Int
tMinute  Int,
    Time -> Int
tSecond  Int }
  deriving (Time -> Time -> Bool
(Time -> Time -> Bool) -> (Time -> Time -> Bool) -> Eq Time
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Time -> Time -> Bool
$c/= :: Time -> Time -> Bool
== :: Time -> Time -> Bool
$c== :: Time -> Time -> Bool
Eq,Eq Time
Eq Time
-> (Time -> Time -> Ordering)
-> (Time -> Time -> Bool)
-> (Time -> Time -> Bool)
-> (Time -> Time -> Bool)
-> (Time -> Time -> Bool)
-> (Time -> Time -> Time)
-> (Time -> Time -> Time)
-> Ord Time
Time -> Time -> Bool
Time -> Time -> Ordering
Time -> Time -> Time
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
min :: Time -> Time -> Time
$cmin :: Time -> Time -> Time
max :: Time -> Time -> Time
$cmax :: Time -> Time -> Time
>= :: Time -> Time -> Bool
$c>= :: Time -> Time -> Bool
> :: Time -> Time -> Bool
$c> :: Time -> Time -> Bool
<= :: Time -> Time -> Bool
$c<= :: Time -> Time -> Bool
< :: Time -> Time -> Bool
$c< :: Time -> Time -> Bool
compare :: Time -> Time -> Ordering
$ccompare :: Time -> Time -> Ordering
$cp1Ord :: Eq Time
Ord,Int -> Time -> String -> String
[Time] -> String -> String
Time -> String
(Int -> Time -> String -> String)
-> (Time -> String) -> ([Time] -> String -> String) -> Show Time
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [Time] -> String -> String
$cshowList :: [Time] -> String -> String
show :: Time -> String
$cshow :: Time -> String
showsPrec :: Int -> Time -> String -> String
$cshowsPrec :: Int -> Time -> String -> String
Show,Typeable Time
DataType
Constr
Typeable Time
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Time -> c Time)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Time)
-> (Time -> Constr)
-> (Time -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Time))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Time))
-> ((forall b. Data b => b -> b) -> Time -> Time)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Time -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Time -> r)
-> (forall u. (forall d. Data d => d -> u) -> Time -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Time -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Time -> m Time)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Time -> m Time)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Time -> m Time)
-> Data Time
Time -> DataType
Time -> Constr
(forall b. Data b => b -> b) -> Time -> Time
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Time -> c Time
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Time
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Time -> u
forall u. (forall d. Data d => d -> u) -> Time -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Time -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Time -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Time -> m Time
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Time -> m Time
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Time
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Time -> c Time
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Time)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Time)
$cTime :: Constr
$tTime :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Time -> m Time
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Time -> m Time
gmapMp :: (forall d. Data d => d -> m d) -> Time -> m Time
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Time -> m Time
gmapM :: (forall d. Data d => d -> m d) -> Time -> m Time
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Time -> m Time
gmapQi :: Int -> (forall d. Data d => d -> u) -> Time -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Time -> u
gmapQ :: (forall d. Data d => d -> u) -> Time -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Time -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Time -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Time -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Time -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Time -> r
gmapT :: (forall b. Data b => b -> b) -> Time -> Time
$cgmapT :: (forall b. Data b => b -> b) -> Time -> Time
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Time)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Time)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Time)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Time)
dataTypeOf :: Time -> DataType
$cdataTypeOf :: Time -> DataType
toConstr :: Time -> Constr
$ctoConstr :: Time -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Time
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Time
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Time -> c Time
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Time -> c Time
$cp1Data :: Typeable Time
Data,Typeable)

instance Semigroup DateTime where
  DateTime
dt1 <> :: DateTime -> DateTime -> DateTime
<> DateTime
dt2 = 
      Int -> Int -> Int -> Int -> Int -> Int -> DateTime
DateTime (DateTime -> Int
year DateTime
dt1   Int -> Int -> Int
`plus` DateTime -> Int
year DateTime
dt2)
               (DateTime -> Int
month DateTime
dt1  Int -> Int -> Int
`plus` DateTime -> Int
month DateTime
dt2)
               (DateTime -> Int
day DateTime
dt1    Int -> Int -> Int
`plus` DateTime -> Int
day DateTime
dt2)
               (DateTime -> Int
hour DateTime
dt1   Int -> Int -> Int
`plus` DateTime -> Int
hour DateTime
dt2)
               (DateTime -> Int
minute DateTime
dt1 Int -> Int -> Int
`plus` DateTime -> Int
minute DateTime
dt2)
               (DateTime -> Int
second DateTime
dt1 Int -> Int -> Int
`plus` DateTime -> Int
second DateTime
dt2)
    where
      plus :: Int  Int  Int
      plus :: Int -> Int -> Int
plus Int
0 Int
x = Int
x
      plus Int
x Int
_ = Int
x

instance Monoid DateTime where
  mempty :: DateTime
mempty = Int -> Int -> Int -> Int -> Int -> Int -> DateTime
DateTime Int
0 Int
0 Int
0 Int
0 Int
0 Int
0
  mappend :: DateTime -> DateTime -> DateTime
mappend = DateTime -> DateTime -> DateTime
forall a. Semigroup a => a -> a -> a
(Data.Semigroup.<>)