{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE OverloadedStrings #-}

-- Stolen from https://gist.github.com/nh2/16c84db9d10e8869d8ae

module Data.Time.ISO8601.Duration (
    Duration         (..)
  , DurDate          (..)
  , DurTime          (..)
  , DurYear          (..)
  , DurMonth         (..)
  , DurWeek          (..)
  , DurDay           (..)
  , DurHour          (..)
  , DurMinute        (..)
  , DurSecond        (..)
  , parseDuration
  , duration
  , formatDuration
  , formatDurationB
  , addDuration
) where

import           Control.Applicative
import           Data.Attoparsec.ByteString.Char8
import           Data.ByteString (ByteString)
import           Data.ByteString.Builder (Builder, toLazyByteString)
import qualified Data.ByteString.Lazy as LBS
import           Data.String (IsString, fromString)
import           Data.Time hiding (formatTime)



newtype DurSecond = DurSecond Integer                  deriving (DurSecond -> DurSecond -> Bool
(DurSecond -> DurSecond -> Bool)
-> (DurSecond -> DurSecond -> Bool) -> Eq DurSecond
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DurSecond -> DurSecond -> Bool
== :: DurSecond -> DurSecond -> Bool
$c/= :: DurSecond -> DurSecond -> Bool
/= :: DurSecond -> DurSecond -> Bool
Eq, Eq DurSecond
Eq DurSecond =>
(DurSecond -> DurSecond -> Ordering)
-> (DurSecond -> DurSecond -> Bool)
-> (DurSecond -> DurSecond -> Bool)
-> (DurSecond -> DurSecond -> Bool)
-> (DurSecond -> DurSecond -> Bool)
-> (DurSecond -> DurSecond -> DurSecond)
-> (DurSecond -> DurSecond -> DurSecond)
-> Ord DurSecond
DurSecond -> DurSecond -> Bool
DurSecond -> DurSecond -> Ordering
DurSecond -> DurSecond -> DurSecond
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 :: DurSecond -> DurSecond -> Ordering
compare :: DurSecond -> DurSecond -> Ordering
$c< :: DurSecond -> DurSecond -> Bool
< :: DurSecond -> DurSecond -> Bool
$c<= :: DurSecond -> DurSecond -> Bool
<= :: DurSecond -> DurSecond -> Bool
$c> :: DurSecond -> DurSecond -> Bool
> :: DurSecond -> DurSecond -> Bool
$c>= :: DurSecond -> DurSecond -> Bool
>= :: DurSecond -> DurSecond -> Bool
$cmax :: DurSecond -> DurSecond -> DurSecond
max :: DurSecond -> DurSecond -> DurSecond
$cmin :: DurSecond -> DurSecond -> DurSecond
min :: DurSecond -> DurSecond -> DurSecond
Ord, Int -> DurSecond -> ShowS
[DurSecond] -> ShowS
DurSecond -> String
(Int -> DurSecond -> ShowS)
-> (DurSecond -> String)
-> ([DurSecond] -> ShowS)
-> Show DurSecond
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DurSecond -> ShowS
showsPrec :: Int -> DurSecond -> ShowS
$cshow :: DurSecond -> String
show :: DurSecond -> String
$cshowList :: [DurSecond] -> ShowS
showList :: [DurSecond] -> ShowS
Show)
data DurMinute = DurMinute Integer (Maybe DurSecond)   deriving (DurMinute -> DurMinute -> Bool
(DurMinute -> DurMinute -> Bool)
-> (DurMinute -> DurMinute -> Bool) -> Eq DurMinute
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DurMinute -> DurMinute -> Bool
== :: DurMinute -> DurMinute -> Bool
$c/= :: DurMinute -> DurMinute -> Bool
/= :: DurMinute -> DurMinute -> Bool
Eq, Eq DurMinute
Eq DurMinute =>
(DurMinute -> DurMinute -> Ordering)
-> (DurMinute -> DurMinute -> Bool)
-> (DurMinute -> DurMinute -> Bool)
-> (DurMinute -> DurMinute -> Bool)
-> (DurMinute -> DurMinute -> Bool)
-> (DurMinute -> DurMinute -> DurMinute)
-> (DurMinute -> DurMinute -> DurMinute)
-> Ord DurMinute
DurMinute -> DurMinute -> Bool
DurMinute -> DurMinute -> Ordering
DurMinute -> DurMinute -> DurMinute
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 :: DurMinute -> DurMinute -> Ordering
compare :: DurMinute -> DurMinute -> Ordering
$c< :: DurMinute -> DurMinute -> Bool
< :: DurMinute -> DurMinute -> Bool
$c<= :: DurMinute -> DurMinute -> Bool
<= :: DurMinute -> DurMinute -> Bool
$c> :: DurMinute -> DurMinute -> Bool
> :: DurMinute -> DurMinute -> Bool
$c>= :: DurMinute -> DurMinute -> Bool
>= :: DurMinute -> DurMinute -> Bool
$cmax :: DurMinute -> DurMinute -> DurMinute
max :: DurMinute -> DurMinute -> DurMinute
$cmin :: DurMinute -> DurMinute -> DurMinute
min :: DurMinute -> DurMinute -> DurMinute
Ord, Int -> DurMinute -> ShowS
[DurMinute] -> ShowS
DurMinute -> String
(Int -> DurMinute -> ShowS)
-> (DurMinute -> String)
-> ([DurMinute] -> ShowS)
-> Show DurMinute
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DurMinute -> ShowS
showsPrec :: Int -> DurMinute -> ShowS
$cshow :: DurMinute -> String
show :: DurMinute -> String
$cshowList :: [DurMinute] -> ShowS
showList :: [DurMinute] -> ShowS
Show)
data DurHour   = DurHour   Integer (Maybe DurMinute)   deriving (DurHour -> DurHour -> Bool
(DurHour -> DurHour -> Bool)
-> (DurHour -> DurHour -> Bool) -> Eq DurHour
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DurHour -> DurHour -> Bool
== :: DurHour -> DurHour -> Bool
$c/= :: DurHour -> DurHour -> Bool
/= :: DurHour -> DurHour -> Bool
Eq, Eq DurHour
Eq DurHour =>
(DurHour -> DurHour -> Ordering)
-> (DurHour -> DurHour -> Bool)
-> (DurHour -> DurHour -> Bool)
-> (DurHour -> DurHour -> Bool)
-> (DurHour -> DurHour -> Bool)
-> (DurHour -> DurHour -> DurHour)
-> (DurHour -> DurHour -> DurHour)
-> Ord DurHour
DurHour -> DurHour -> Bool
DurHour -> DurHour -> Ordering
DurHour -> DurHour -> DurHour
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 :: DurHour -> DurHour -> Ordering
compare :: DurHour -> DurHour -> Ordering
$c< :: DurHour -> DurHour -> Bool
< :: DurHour -> DurHour -> Bool
$c<= :: DurHour -> DurHour -> Bool
<= :: DurHour -> DurHour -> Bool
$c> :: DurHour -> DurHour -> Bool
> :: DurHour -> DurHour -> Bool
$c>= :: DurHour -> DurHour -> Bool
>= :: DurHour -> DurHour -> Bool
$cmax :: DurHour -> DurHour -> DurHour
max :: DurHour -> DurHour -> DurHour
$cmin :: DurHour -> DurHour -> DurHour
min :: DurHour -> DurHour -> DurHour
Ord, Int -> DurHour -> ShowS
[DurHour] -> ShowS
DurHour -> String
(Int -> DurHour -> ShowS)
-> (DurHour -> String) -> ([DurHour] -> ShowS) -> Show DurHour
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DurHour -> ShowS
showsPrec :: Int -> DurHour -> ShowS
$cshow :: DurHour -> String
show :: DurHour -> String
$cshowList :: [DurHour] -> ShowS
showList :: [DurHour] -> ShowS
Show)
data DurTime   = DurTimeHour   DurHour
               | DurTimeMinute DurMinute
               | DurTimeSecond DurSecond               deriving (DurTime -> DurTime -> Bool
(DurTime -> DurTime -> Bool)
-> (DurTime -> DurTime -> Bool) -> Eq DurTime
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DurTime -> DurTime -> Bool
== :: DurTime -> DurTime -> Bool
$c/= :: DurTime -> DurTime -> Bool
/= :: DurTime -> DurTime -> Bool
Eq, Eq DurTime
Eq DurTime =>
(DurTime -> DurTime -> Ordering)
-> (DurTime -> DurTime -> Bool)
-> (DurTime -> DurTime -> Bool)
-> (DurTime -> DurTime -> Bool)
-> (DurTime -> DurTime -> Bool)
-> (DurTime -> DurTime -> DurTime)
-> (DurTime -> DurTime -> DurTime)
-> Ord DurTime
DurTime -> DurTime -> Bool
DurTime -> DurTime -> Ordering
DurTime -> DurTime -> DurTime
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 :: DurTime -> DurTime -> Ordering
compare :: DurTime -> DurTime -> Ordering
$c< :: DurTime -> DurTime -> Bool
< :: DurTime -> DurTime -> Bool
$c<= :: DurTime -> DurTime -> Bool
<= :: DurTime -> DurTime -> Bool
$c> :: DurTime -> DurTime -> Bool
> :: DurTime -> DurTime -> Bool
$c>= :: DurTime -> DurTime -> Bool
>= :: DurTime -> DurTime -> Bool
$cmax :: DurTime -> DurTime -> DurTime
max :: DurTime -> DurTime -> DurTime
$cmin :: DurTime -> DurTime -> DurTime
min :: DurTime -> DurTime -> DurTime
Ord, Int -> DurTime -> ShowS
[DurTime] -> ShowS
DurTime -> String
(Int -> DurTime -> ShowS)
-> (DurTime -> String) -> ([DurTime] -> ShowS) -> Show DurTime
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DurTime -> ShowS
showsPrec :: Int -> DurTime -> ShowS
$cshow :: DurTime -> String
show :: DurTime -> String
$cshowList :: [DurTime] -> ShowS
showList :: [DurTime] -> ShowS
Show)
newtype DurDay    = DurDay    Integer                  deriving (DurDay -> DurDay -> Bool
(DurDay -> DurDay -> Bool)
-> (DurDay -> DurDay -> Bool) -> Eq DurDay
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DurDay -> DurDay -> Bool
== :: DurDay -> DurDay -> Bool
$c/= :: DurDay -> DurDay -> Bool
/= :: DurDay -> DurDay -> Bool
Eq, Eq DurDay
Eq DurDay =>
(DurDay -> DurDay -> Ordering)
-> (DurDay -> DurDay -> Bool)
-> (DurDay -> DurDay -> Bool)
-> (DurDay -> DurDay -> Bool)
-> (DurDay -> DurDay -> Bool)
-> (DurDay -> DurDay -> DurDay)
-> (DurDay -> DurDay -> DurDay)
-> Ord DurDay
DurDay -> DurDay -> Bool
DurDay -> DurDay -> Ordering
DurDay -> DurDay -> DurDay
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 :: DurDay -> DurDay -> Ordering
compare :: DurDay -> DurDay -> Ordering
$c< :: DurDay -> DurDay -> Bool
< :: DurDay -> DurDay -> Bool
$c<= :: DurDay -> DurDay -> Bool
<= :: DurDay -> DurDay -> Bool
$c> :: DurDay -> DurDay -> Bool
> :: DurDay -> DurDay -> Bool
$c>= :: DurDay -> DurDay -> Bool
>= :: DurDay -> DurDay -> Bool
$cmax :: DurDay -> DurDay -> DurDay
max :: DurDay -> DurDay -> DurDay
$cmin :: DurDay -> DurDay -> DurDay
min :: DurDay -> DurDay -> DurDay
Ord, Int -> DurDay -> ShowS
[DurDay] -> ShowS
DurDay -> String
(Int -> DurDay -> ShowS)
-> (DurDay -> String) -> ([DurDay] -> ShowS) -> Show DurDay
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DurDay -> ShowS
showsPrec :: Int -> DurDay -> ShowS
$cshow :: DurDay -> String
show :: DurDay -> String
$cshowList :: [DurDay] -> ShowS
showList :: [DurDay] -> ShowS
Show)
newtype DurWeek   = DurWeek   Integer                  deriving (DurWeek -> DurWeek -> Bool
(DurWeek -> DurWeek -> Bool)
-> (DurWeek -> DurWeek -> Bool) -> Eq DurWeek
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DurWeek -> DurWeek -> Bool
== :: DurWeek -> DurWeek -> Bool
$c/= :: DurWeek -> DurWeek -> Bool
/= :: DurWeek -> DurWeek -> Bool
Eq, Eq DurWeek
Eq DurWeek =>
(DurWeek -> DurWeek -> Ordering)
-> (DurWeek -> DurWeek -> Bool)
-> (DurWeek -> DurWeek -> Bool)
-> (DurWeek -> DurWeek -> Bool)
-> (DurWeek -> DurWeek -> Bool)
-> (DurWeek -> DurWeek -> DurWeek)
-> (DurWeek -> DurWeek -> DurWeek)
-> Ord DurWeek
DurWeek -> DurWeek -> Bool
DurWeek -> DurWeek -> Ordering
DurWeek -> DurWeek -> DurWeek
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 :: DurWeek -> DurWeek -> Ordering
compare :: DurWeek -> DurWeek -> Ordering
$c< :: DurWeek -> DurWeek -> Bool
< :: DurWeek -> DurWeek -> Bool
$c<= :: DurWeek -> DurWeek -> Bool
<= :: DurWeek -> DurWeek -> Bool
$c> :: DurWeek -> DurWeek -> Bool
> :: DurWeek -> DurWeek -> Bool
$c>= :: DurWeek -> DurWeek -> Bool
>= :: DurWeek -> DurWeek -> Bool
$cmax :: DurWeek -> DurWeek -> DurWeek
max :: DurWeek -> DurWeek -> DurWeek
$cmin :: DurWeek -> DurWeek -> DurWeek
min :: DurWeek -> DurWeek -> DurWeek
Ord, Int -> DurWeek -> ShowS
[DurWeek] -> ShowS
DurWeek -> String
(Int -> DurWeek -> ShowS)
-> (DurWeek -> String) -> ([DurWeek] -> ShowS) -> Show DurWeek
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DurWeek -> ShowS
showsPrec :: Int -> DurWeek -> ShowS
$cshow :: DurWeek -> String
show :: DurWeek -> String
$cshowList :: [DurWeek] -> ShowS
showList :: [DurWeek] -> ShowS
Show)
data DurMonth  = DurMonth  Integer (Maybe DurDay)      deriving (DurMonth -> DurMonth -> Bool
(DurMonth -> DurMonth -> Bool)
-> (DurMonth -> DurMonth -> Bool) -> Eq DurMonth
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DurMonth -> DurMonth -> Bool
== :: DurMonth -> DurMonth -> Bool
$c/= :: DurMonth -> DurMonth -> Bool
/= :: DurMonth -> DurMonth -> Bool
Eq, Eq DurMonth
Eq DurMonth =>
(DurMonth -> DurMonth -> Ordering)
-> (DurMonth -> DurMonth -> Bool)
-> (DurMonth -> DurMonth -> Bool)
-> (DurMonth -> DurMonth -> Bool)
-> (DurMonth -> DurMonth -> Bool)
-> (DurMonth -> DurMonth -> DurMonth)
-> (DurMonth -> DurMonth -> DurMonth)
-> Ord DurMonth
DurMonth -> DurMonth -> Bool
DurMonth -> DurMonth -> Ordering
DurMonth -> DurMonth -> DurMonth
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 :: DurMonth -> DurMonth -> Ordering
compare :: DurMonth -> DurMonth -> Ordering
$c< :: DurMonth -> DurMonth -> Bool
< :: DurMonth -> DurMonth -> Bool
$c<= :: DurMonth -> DurMonth -> Bool
<= :: DurMonth -> DurMonth -> Bool
$c> :: DurMonth -> DurMonth -> Bool
> :: DurMonth -> DurMonth -> Bool
$c>= :: DurMonth -> DurMonth -> Bool
>= :: DurMonth -> DurMonth -> Bool
$cmax :: DurMonth -> DurMonth -> DurMonth
max :: DurMonth -> DurMonth -> DurMonth
$cmin :: DurMonth -> DurMonth -> DurMonth
min :: DurMonth -> DurMonth -> DurMonth
Ord, Int -> DurMonth -> ShowS
[DurMonth] -> ShowS
DurMonth -> String
(Int -> DurMonth -> ShowS)
-> (DurMonth -> String) -> ([DurMonth] -> ShowS) -> Show DurMonth
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DurMonth -> ShowS
showsPrec :: Int -> DurMonth -> ShowS
$cshow :: DurMonth -> String
show :: DurMonth -> String
$cshowList :: [DurMonth] -> ShowS
showList :: [DurMonth] -> ShowS
Show)
data DurYear   = DurYear   Integer (Maybe DurMonth)    deriving (DurYear -> DurYear -> Bool
(DurYear -> DurYear -> Bool)
-> (DurYear -> DurYear -> Bool) -> Eq DurYear
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DurYear -> DurYear -> Bool
== :: DurYear -> DurYear -> Bool
$c/= :: DurYear -> DurYear -> Bool
/= :: DurYear -> DurYear -> Bool
Eq, Eq DurYear
Eq DurYear =>
(DurYear -> DurYear -> Ordering)
-> (DurYear -> DurYear -> Bool)
-> (DurYear -> DurYear -> Bool)
-> (DurYear -> DurYear -> Bool)
-> (DurYear -> DurYear -> Bool)
-> (DurYear -> DurYear -> DurYear)
-> (DurYear -> DurYear -> DurYear)
-> Ord DurYear
DurYear -> DurYear -> Bool
DurYear -> DurYear -> Ordering
DurYear -> DurYear -> DurYear
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 :: DurYear -> DurYear -> Ordering
compare :: DurYear -> DurYear -> Ordering
$c< :: DurYear -> DurYear -> Bool
< :: DurYear -> DurYear -> Bool
$c<= :: DurYear -> DurYear -> Bool
<= :: DurYear -> DurYear -> Bool
$c> :: DurYear -> DurYear -> Bool
> :: DurYear -> DurYear -> Bool
$c>= :: DurYear -> DurYear -> Bool
>= :: DurYear -> DurYear -> Bool
$cmax :: DurYear -> DurYear -> DurYear
max :: DurYear -> DurYear -> DurYear
$cmin :: DurYear -> DurYear -> DurYear
min :: DurYear -> DurYear -> DurYear
Ord, Int -> DurYear -> ShowS
[DurYear] -> ShowS
DurYear -> String
(Int -> DurYear -> ShowS)
-> (DurYear -> String) -> ([DurYear] -> ShowS) -> Show DurYear
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DurYear -> ShowS
showsPrec :: Int -> DurYear -> ShowS
$cshow :: DurYear -> String
show :: DurYear -> String
$cshowList :: [DurYear] -> ShowS
showList :: [DurYear] -> ShowS
Show)
data DurDate   = DurDateDay   DurDay   (Maybe DurTime)
               | DurDateMonth DurMonth (Maybe DurTime)
               | DurDateYear  DurYear  (Maybe DurTime) deriving (DurDate -> DurDate -> Bool
(DurDate -> DurDate -> Bool)
-> (DurDate -> DurDate -> Bool) -> Eq DurDate
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DurDate -> DurDate -> Bool
== :: DurDate -> DurDate -> Bool
$c/= :: DurDate -> DurDate -> Bool
/= :: DurDate -> DurDate -> Bool
Eq, Eq DurDate
Eq DurDate =>
(DurDate -> DurDate -> Ordering)
-> (DurDate -> DurDate -> Bool)
-> (DurDate -> DurDate -> Bool)
-> (DurDate -> DurDate -> Bool)
-> (DurDate -> DurDate -> Bool)
-> (DurDate -> DurDate -> DurDate)
-> (DurDate -> DurDate -> DurDate)
-> Ord DurDate
DurDate -> DurDate -> Bool
DurDate -> DurDate -> Ordering
DurDate -> DurDate -> DurDate
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 :: DurDate -> DurDate -> Ordering
compare :: DurDate -> DurDate -> Ordering
$c< :: DurDate -> DurDate -> Bool
< :: DurDate -> DurDate -> Bool
$c<= :: DurDate -> DurDate -> Bool
<= :: DurDate -> DurDate -> Bool
$c> :: DurDate -> DurDate -> Bool
> :: DurDate -> DurDate -> Bool
$c>= :: DurDate -> DurDate -> Bool
>= :: DurDate -> DurDate -> Bool
$cmax :: DurDate -> DurDate -> DurDate
max :: DurDate -> DurDate -> DurDate
$cmin :: DurDate -> DurDate -> DurDate
min :: DurDate -> DurDate -> DurDate
Ord, Int -> DurDate -> ShowS
[DurDate] -> ShowS
DurDate -> String
(Int -> DurDate -> ShowS)
-> (DurDate -> String) -> ([DurDate] -> ShowS) -> Show DurDate
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DurDate -> ShowS
showsPrec :: Int -> DurDate -> ShowS
$cshow :: DurDate -> String
show :: DurDate -> String
$cshowList :: [DurDate] -> ShowS
showList :: [DurDate] -> ShowS
Show)

data Duration  = DurationDate DurDate
               | DurationTime DurTime
               | DurationWeek DurWeek                  deriving (Duration -> Duration -> Bool
(Duration -> Duration -> Bool)
-> (Duration -> Duration -> Bool) -> Eq Duration
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Duration -> Duration -> Bool
== :: Duration -> Duration -> Bool
$c/= :: Duration -> Duration -> Bool
/= :: Duration -> Duration -> Bool
Eq, Eq Duration
Eq Duration =>
(Duration -> Duration -> Ordering)
-> (Duration -> Duration -> Bool)
-> (Duration -> Duration -> Bool)
-> (Duration -> Duration -> Bool)
-> (Duration -> Duration -> Bool)
-> (Duration -> Duration -> Duration)
-> (Duration -> Duration -> Duration)
-> Ord Duration
Duration -> Duration -> Bool
Duration -> Duration -> Ordering
Duration -> Duration -> Duration
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 :: Duration -> Duration -> Ordering
compare :: Duration -> Duration -> Ordering
$c< :: Duration -> Duration -> Bool
< :: Duration -> Duration -> Bool
$c<= :: Duration -> Duration -> Bool
<= :: Duration -> Duration -> Bool
$c> :: Duration -> Duration -> Bool
> :: Duration -> Duration -> Bool
$c>= :: Duration -> Duration -> Bool
>= :: Duration -> Duration -> Bool
$cmax :: Duration -> Duration -> Duration
max :: Duration -> Duration -> Duration
$cmin :: Duration -> Duration -> Duration
min :: Duration -> Duration -> Duration
Ord, Int -> Duration -> ShowS
[Duration] -> ShowS
Duration -> String
(Int -> Duration -> ShowS)
-> (Duration -> String) -> ([Duration] -> ShowS) -> Show Duration
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Duration -> ShowS
showsPrec :: Int -> Duration -> ShowS
$cshow :: Duration -> String
show :: Duration -> String
$cshowList :: [Duration] -> ShowS
showList :: [Duration] -> ShowS
Show)


durSecond :: Parser DurSecond
durMinute :: Parser DurMinute
durHour   :: Parser DurHour
durTime   :: Parser DurTime
durDay    :: Parser DurDay
durWeek   :: Parser DurWeek
durMonth  :: Parser DurMonth
durYear   :: Parser DurYear
durDate   :: Parser DurDate
duration  :: Parser Duration

durSecond :: Parser DurSecond
durSecond = Integer -> DurSecond
DurSecond (Integer -> DurSecond)
-> Parser ByteString Integer -> Parser DurSecond
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser ByteString Integer
forall a. Integral a => Parser a
decimal Parser ByteString Integer
-> Parser ByteString Char -> Parser ByteString Integer
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser ByteString Char
char Char
'S')
durMinute :: Parser DurMinute
durMinute = Integer -> Maybe DurSecond -> DurMinute
DurMinute (Integer -> Maybe DurSecond -> DurMinute)
-> Parser ByteString Integer
-> Parser ByteString (Maybe DurSecond -> DurMinute)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser ByteString Integer
forall a. Integral a => Parser a
decimal Parser ByteString Integer
-> Parser ByteString Char -> Parser ByteString Integer
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser ByteString Char
char Char
'M') Parser ByteString (Maybe DurSecond -> DurMinute)
-> Parser ByteString (Maybe DurSecond) -> Parser DurMinute
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser DurSecond -> Parser ByteString (Maybe DurSecond)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser DurSecond
durSecond
durHour :: Parser DurHour
durHour   = Integer -> Maybe DurMinute -> DurHour
DurHour   (Integer -> Maybe DurMinute -> DurHour)
-> Parser ByteString Integer
-> Parser ByteString (Maybe DurMinute -> DurHour)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser ByteString Integer
forall a. Integral a => Parser a
decimal Parser ByteString Integer
-> Parser ByteString Char -> Parser ByteString Integer
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser ByteString Char
char Char
'H') Parser ByteString (Maybe DurMinute -> DurHour)
-> Parser ByteString (Maybe DurMinute) -> Parser DurHour
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser DurMinute -> Parser ByteString (Maybe DurMinute)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser DurMinute
durMinute
durTime :: Parser DurTime
durTime   = Char -> Parser ByteString Char
char Char
'T' Parser ByteString Char -> Parser DurTime -> Parser DurTime
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ((DurHour -> DurTime
DurTimeHour (DurHour -> DurTime) -> Parser DurHour -> Parser DurTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser DurHour
durHour) Parser DurTime -> Parser DurTime -> Parser DurTime
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                         (DurMinute -> DurTime
DurTimeMinute (DurMinute -> DurTime) -> Parser DurMinute -> Parser DurTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser DurMinute
durMinute) Parser DurTime -> Parser DurTime -> Parser DurTime
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                         (DurSecond -> DurTime
DurTimeSecond (DurSecond -> DurTime) -> Parser DurSecond -> Parser DurTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser DurSecond
durSecond))
durDay :: Parser DurDay
durDay    = Integer -> DurDay
DurDay    (Integer -> DurDay) -> Parser ByteString Integer -> Parser DurDay
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser ByteString Integer
forall a. Integral a => Parser a
decimal Parser ByteString Integer
-> Parser ByteString Char -> Parser ByteString Integer
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser ByteString Char
char Char
'D')
durWeek :: Parser DurWeek
durWeek   = Integer -> DurWeek
DurWeek   (Integer -> DurWeek) -> Parser ByteString Integer -> Parser DurWeek
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser ByteString Integer
forall a. Integral a => Parser a
decimal Parser ByteString Integer
-> Parser ByteString Char -> Parser ByteString Integer
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser ByteString Char
char Char
'W')
durMonth :: Parser DurMonth
durMonth  = Integer -> Maybe DurDay -> DurMonth
DurMonth  (Integer -> Maybe DurDay -> DurMonth)
-> Parser ByteString Integer
-> Parser ByteString (Maybe DurDay -> DurMonth)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser ByteString Integer
forall a. Integral a => Parser a
decimal Parser ByteString Integer
-> Parser ByteString Char -> Parser ByteString Integer
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser ByteString Char
char Char
'M') Parser ByteString (Maybe DurDay -> DurMonth)
-> Parser ByteString (Maybe DurDay) -> Parser DurMonth
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser DurDay -> Parser ByteString (Maybe DurDay)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser DurDay
durDay
durYear :: Parser DurYear
durYear   = Integer -> Maybe DurMonth -> DurYear
DurYear   (Integer -> Maybe DurMonth -> DurYear)
-> Parser ByteString Integer
-> Parser ByteString (Maybe DurMonth -> DurYear)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser ByteString Integer
forall a. Integral a => Parser a
decimal Parser ByteString Integer
-> Parser ByteString Char -> Parser ByteString Integer
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser ByteString Char
char Char
'Y') Parser ByteString (Maybe DurMonth -> DurYear)
-> Parser ByteString (Maybe DurMonth) -> Parser DurYear
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser DurMonth -> Parser ByteString (Maybe DurMonth)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser DurMonth
durMonth
durDate :: Parser DurDate
durDate   = (DurDay -> Maybe DurTime -> DurDate
DurDateDay   (DurDay -> Maybe DurTime -> DurDate)
-> Parser DurDay -> Parser ByteString (Maybe DurTime -> DurDate)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser DurDay
durDay   Parser ByteString (Maybe DurTime -> DurDate)
-> Parser ByteString (Maybe DurTime) -> Parser DurDate
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser DurTime -> Parser ByteString (Maybe DurTime)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser DurTime
durTime) Parser DurDate -> Parser DurDate -> Parser DurDate
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
            (DurMonth -> Maybe DurTime -> DurDate
DurDateMonth (DurMonth -> Maybe DurTime -> DurDate)
-> Parser DurMonth -> Parser ByteString (Maybe DurTime -> DurDate)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser DurMonth
durMonth Parser ByteString (Maybe DurTime -> DurDate)
-> Parser ByteString (Maybe DurTime) -> Parser DurDate
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser DurTime -> Parser ByteString (Maybe DurTime)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser DurTime
durTime) Parser DurDate -> Parser DurDate -> Parser DurDate
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
            (DurYear -> Maybe DurTime -> DurDate
DurDateYear  (DurYear -> Maybe DurTime -> DurDate)
-> Parser DurYear -> Parser ByteString (Maybe DurTime -> DurDate)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser DurYear
durYear  Parser ByteString (Maybe DurTime -> DurDate)
-> Parser ByteString (Maybe DurTime) -> Parser DurDate
forall a b.
Parser ByteString (a -> b)
-> Parser ByteString a -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser DurTime -> Parser ByteString (Maybe DurTime)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser DurTime
durTime)

duration :: Parser Duration
duration  = Char -> Parser ByteString Char
char Char
'P' Parser ByteString Char -> Parser Duration -> Parser Duration
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ((DurDate -> Duration
DurationDate (DurDate -> Duration) -> Parser DurDate -> Parser Duration
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser DurDate
durDate) Parser Duration -> Parser Duration -> Parser Duration
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                         (DurTime -> Duration
DurationTime (DurTime -> Duration) -> Parser DurTime -> Parser Duration
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser DurTime
durTime) Parser Duration -> Parser Duration -> Parser Duration
forall a.
Parser ByteString a -> Parser ByteString a -> Parser ByteString a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                         (DurWeek -> Duration
DurationWeek (DurWeek -> Duration) -> Parser DurWeek -> Parser Duration
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser DurWeek
durWeek))


parseDuration :: ByteString -> Either String Duration
parseDuration :: ByteString -> Either String Duration
parseDuration = Parser Duration -> ByteString -> Either String Duration
forall a. Parser a -> ByteString -> Either String a
parseOnly (Parser Duration
duration Parser Duration -> Parser ByteString () -> Parser Duration
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString ()
forall t. Chunk t => Parser t ()
endOfInput)


formatDuration :: Duration -> ByteString
formatDuration :: Duration -> ByteString
formatDuration = Builder -> ByteString
runBuilder (Builder -> ByteString)
-> (Duration -> Builder) -> Duration -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Duration -> Builder
formatDurationB

formatDurationB :: Duration -> Builder
formatDurationB :: Duration -> Builder
formatDurationB Duration
dur = Builder
"P" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> case Duration
dur of
  DurationDate DurDate
date -> DurDate -> Builder
forall {a}. (Semigroup a, IsString a) => DurDate -> a
formatDate DurDate
date
  DurationTime DurTime
time -> DurTime -> Builder
forall {a}. (Semigroup a, IsString a) => DurTime -> a
formatTime DurTime
time
  DurationWeek DurWeek
week -> DurWeek -> Builder
forall {a}. (Semigroup a, IsString a) => DurWeek -> a
formatWeek DurWeek
week
  where
    formatSecond :: DurSecond -> a
formatSecond (DurSecond Integer
second)          = Integer -> a
forall a b. (Show a, IsString b) => a -> b
show' Integer
second a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
"S"
    formatMinute :: DurMinute -> a
formatMinute (DurMinute Integer
minute Maybe DurSecond
mbSecond) =
      Integer -> a
forall a b. (Show a, IsString b) => a -> b
show' Integer
minute a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
"M" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a -> (DurSecond -> a) -> Maybe DurSecond -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
"" DurSecond -> a
forall {a}. (Semigroup a, IsString a) => DurSecond -> a
formatSecond Maybe DurSecond
mbSecond
    formatHour :: DurHour -> a
formatHour   (DurHour   Integer
hour   Maybe DurMinute
mbMinute) =
      Integer -> a
forall a b. (Show a, IsString b) => a -> b
show' Integer
hour   a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
"H" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a -> (DurMinute -> a) -> Maybe DurMinute -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
"" DurMinute -> a
forall {a}. (Semigroup a, IsString a) => DurMinute -> a
formatMinute Maybe DurMinute
mbMinute
    formatTime :: DurTime -> a
formatTime DurTime
time = a
"T" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> case DurTime
time of
      DurTimeSecond DurSecond
second -> DurSecond -> a
forall {a}. (Semigroup a, IsString a) => DurSecond -> a
formatSecond DurSecond
second
      DurTimeMinute DurMinute
minute -> DurMinute -> a
forall {a}. (Semigroup a, IsString a) => DurMinute -> a
formatMinute DurMinute
minute
      DurTimeHour   DurHour
hour   -> DurHour -> a
forall {a}. (Semigroup a, IsString a) => DurHour -> a
formatHour   DurHour
hour
    formatDay :: DurDay -> a
formatDay   (DurDay   Integer
day)           = Integer -> a
forall a b. (Show a, IsString b) => a -> b
show' Integer
day   a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
"D"
    formatWeek :: DurWeek -> a
formatWeek  (DurWeek  Integer
week)          = Integer -> a
forall a b. (Show a, IsString b) => a -> b
show' Integer
week  a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
"W"
    formatMonth :: DurMonth -> a
formatMonth (DurMonth Integer
month Maybe DurDay
mbDay)   =
      Integer -> a
forall a b. (Show a, IsString b) => a -> b
show' Integer
month a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
"M" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a -> (DurDay -> a) -> Maybe DurDay -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
"" DurDay -> a
forall {a}. (Semigroup a, IsString a) => DurDay -> a
formatDay   Maybe DurDay
mbDay
    formatYear :: DurYear -> a
formatYear  (DurYear  Integer
year  Maybe DurMonth
mbMonth) =
      Integer -> a
forall a b. (Show a, IsString b) => a -> b
show' Integer
year  a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
"Y" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a -> (DurMonth -> a) -> Maybe DurMonth -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
"" DurMonth -> a
forall {a}. (Semigroup a, IsString a) => DurMonth -> a
formatMonth Maybe DurMonth
mbMonth
    formatDate :: DurDate -> a
formatDate DurDate
date = case DurDate
date of
      DurDateDay   DurDay
day   Maybe DurTime
mbTime -> DurDay -> a
forall {a}. (Semigroup a, IsString a) => DurDay -> a
formatDay   DurDay
day   a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a -> (DurTime -> a) -> Maybe DurTime -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
"" DurTime -> a
forall {a}. (Semigroup a, IsString a) => DurTime -> a
formatTime Maybe DurTime
mbTime
      DurDateMonth DurMonth
month Maybe DurTime
mbTime -> DurMonth -> a
forall {a}. (Semigroup a, IsString a) => DurMonth -> a
formatMonth DurMonth
month a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a -> (DurTime -> a) -> Maybe DurTime -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
"" DurTime -> a
forall {a}. (Semigroup a, IsString a) => DurTime -> a
formatTime Maybe DurTime
mbTime
      DurDateYear  DurYear
year  Maybe DurTime
mbTime -> DurYear -> a
forall {a}. (Semigroup a, IsString a) => DurYear -> a
formatYear  DurYear
year  a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a -> (DurTime -> a) -> Maybe DurTime -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
"" DurTime -> a
forall {a}. (Semigroup a, IsString a) => DurTime -> a
formatTime Maybe DurTime
mbTime

runBuilder :: Builder -> ByteString
runBuilder :: Builder -> ByteString
runBuilder = ByteString -> ByteString
LBS.toStrict (ByteString -> ByteString)
-> (Builder -> ByteString) -> Builder -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> ByteString
toLazyByteString

show' :: (Show a, IsString b) => a -> b
show' :: forall a b. (Show a, IsString b) => a -> b
show' = String -> b
forall a. IsString a => String -> a
fromString (String -> b) -> (a -> String) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show



addDuration :: Duration -> UTCTime -> UTCTime
addDuration :: Duration -> UTCTime -> UTCTime
addDuration (DurationDate DurDate
s) = DurDate -> UTCTime -> UTCTime
addDurationDate DurDate
s
addDuration (DurationTime DurTime
s) = DurTime -> UTCTime -> UTCTime
addDurationTime DurTime
s
addDuration (DurationWeek DurWeek
s) = DurWeek -> UTCTime -> UTCTime
addDurationWeek DurWeek
s

addDurationDate :: DurDate -> UTCTime -> UTCTime
addDurationDate :: DurDate -> UTCTime -> UTCTime
addDurationDate (DurDateDay DurDay
d Maybe DurTime
dt) =
  (UTCTime -> UTCTime)
-> (DurTime -> UTCTime -> UTCTime)
-> Maybe DurTime
-> UTCTime
-> UTCTime
forall b a. b -> (a -> b) -> Maybe a -> b
maybe UTCTime -> UTCTime
forall a. a -> a
id DurTime -> UTCTime -> UTCTime
addDurationTime Maybe DurTime
dt (UTCTime -> UTCTime) -> (UTCTime -> UTCTime) -> UTCTime -> UTCTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DurDay -> UTCTime -> UTCTime
addDurDay DurDay
d

addDurationDate (DurDateMonth DurMonth
m Maybe DurTime
dt) =
  (UTCTime -> UTCTime)
-> (DurTime -> UTCTime -> UTCTime)
-> Maybe DurTime
-> UTCTime
-> UTCTime
forall b a. b -> (a -> b) -> Maybe a -> b
maybe UTCTime -> UTCTime
forall a. a -> a
id DurTime -> UTCTime -> UTCTime
addDurationTime Maybe DurTime
dt (UTCTime -> UTCTime) -> (UTCTime -> UTCTime) -> UTCTime -> UTCTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DurMonth -> UTCTime -> UTCTime
addDurMonth DurMonth
m

addDurationDate (DurDateYear DurYear
y Maybe DurTime
dt) =
  (UTCTime -> UTCTime)
-> (DurTime -> UTCTime -> UTCTime)
-> Maybe DurTime
-> UTCTime
-> UTCTime
forall b a. b -> (a -> b) -> Maybe a -> b
maybe UTCTime -> UTCTime
forall a. a -> a
id DurTime -> UTCTime -> UTCTime
addDurationTime Maybe DurTime
dt (UTCTime -> UTCTime) -> (UTCTime -> UTCTime) -> UTCTime -> UTCTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DurYear -> UTCTime -> UTCTime
addDurYear DurYear
y

addDurDay :: DurDay -> UTCTime -> UTCTime
addDurDay :: DurDay -> UTCTime -> UTCTime
addDurDay (DurDay Integer
s) (UTCTime Day
d DiffTime
dt) = Day -> DiffTime -> UTCTime
UTCTime (Integer -> Day -> Day
addDays Integer
s Day
d) DiffTime
dt

addDurMonth :: DurMonth -> UTCTime -> UTCTime
addDurMonth :: DurMonth -> UTCTime -> UTCTime
addDurMonth (DurMonth Integer
s Maybe DurDay
m) (UTCTime Day
d DiffTime
dt) =
  (UTCTime -> UTCTime)
-> (DurDay -> UTCTime -> UTCTime)
-> Maybe DurDay
-> UTCTime
-> UTCTime
forall b a. b -> (a -> b) -> Maybe a -> b
maybe UTCTime -> UTCTime
forall a. a -> a
id DurDay -> UTCTime -> UTCTime
addDurDay Maybe DurDay
m (UTCTime -> UTCTime) -> UTCTime -> UTCTime
forall a b. (a -> b) -> a -> b
$
  Day -> DiffTime -> UTCTime
UTCTime (Integer -> Day -> Day
addGregorianMonthsRollOver Integer
s Day
d) DiffTime
dt

addDurYear :: DurYear -> UTCTime -> UTCTime
addDurYear :: DurYear -> UTCTime -> UTCTime
addDurYear (DurYear Integer
s Maybe DurMonth
m) (UTCTime Day
d DiffTime
dt) =
  (UTCTime -> UTCTime)
-> (DurMonth -> UTCTime -> UTCTime)
-> Maybe DurMonth
-> UTCTime
-> UTCTime
forall b a. b -> (a -> b) -> Maybe a -> b
maybe UTCTime -> UTCTime
forall a. a -> a
id DurMonth -> UTCTime -> UTCTime
addDurMonth Maybe DurMonth
m (UTCTime -> UTCTime) -> UTCTime -> UTCTime
forall a b. (a -> b) -> a -> b
$
  Day -> DiffTime -> UTCTime
UTCTime (Integer -> Day -> Day
addGregorianYearsRollOver Integer
s Day
d) DiffTime
dt


addDurationTime :: DurTime -> UTCTime -> UTCTime
addDurationTime :: DurTime -> UTCTime -> UTCTime
addDurationTime = NominalDiffTime -> UTCTime -> UTCTime
addUTCTime (NominalDiffTime -> UTCTime -> UTCTime)
-> (DurTime -> NominalDiffTime) -> DurTime -> UTCTime -> UTCTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DurTime -> NominalDiffTime
forall {a}. Num a => DurTime -> a
durTimeToNDT
  where
    durTimeToNDT :: DurTime -> a
durTimeToNDT (DurTimeHour   DurHour
s) = DurHour -> a
forall {a}. Num a => DurHour -> a
durHourToNDT   DurHour
s
    durTimeToNDT (DurTimeMinute DurMinute
s) = DurMinute -> a
forall {a}. Num a => DurMinute -> a
durMinuteToNDT DurMinute
s
    durTimeToNDT (DurTimeSecond DurSecond
s) = DurSecond -> a
forall {b}. Num b => DurSecond -> b
durSecondToNDT DurSecond
s

    durHourToNDT :: DurHour -> a
durHourToNDT (DurHour Integer
s Maybe DurMinute
m) =
      Integer -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
s Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
60 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
60) a -> a -> a
forall a. Num a => a -> a -> a
+ a -> (DurMinute -> a) -> Maybe DurMinute -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
0 DurMinute -> a
forall {a}. Num a => DurMinute -> a
durMinuteToNDT Maybe DurMinute
m

    durMinuteToNDT :: DurMinute -> a
durMinuteToNDT (DurMinute Integer
s Maybe DurSecond
m) =
      Integer -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
s Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
60) a -> a -> a
forall a. Num a => a -> a -> a
+ a -> (DurSecond -> a) -> Maybe DurSecond -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
0 DurSecond -> a
forall {b}. Num b => DurSecond -> b
durSecondToNDT Maybe DurSecond
m

    durSecondToNDT :: DurSecond -> b
durSecondToNDT (DurSecond Integer
s) = Integer -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
s

addDurationWeek :: DurWeek -> UTCTime -> UTCTime
addDurationWeek :: DurWeek -> UTCTime -> UTCTime
addDurationWeek (DurWeek Integer
w) = DurDay -> UTCTime -> UTCTime
addDurDay (Integer -> DurDay
DurDay (Integer
wInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
7))