module Database.RethinkDB.Time where
import qualified Data.Time as Time
import qualified Data.Time.Clock.POSIX as Time
import Data.Aeson as JSON
import Data.Aeson.Types (Parser)
import Control.Monad
import Control.Applicative
import Database.RethinkDB.ReQL
import Database.RethinkDB.Protobuf.Ql2.Term.TermType
now :: ReQL
now = op NOW () ()
time :: ReQL -> ReQL -> ReQL -> ReQL -> ReQL -> ReQL -> ReQL -> ReQL
time y m d hh mm ss tz = op TIME [y, m, d, hh, mm, ss, tz] ()
epochTime :: ReQL -> ReQL
epochTime t = op EPOCH_TIME [t] ()
iso8601 :: ReQL -> ReQL
iso8601 t = op ISO8601 [t] ()
inTimezone :: Expr time => ReQL -> time -> ReQL
inTimezone tz t = op IN_TIMEZONE (t, tz) ()
during :: (Expr left, Expr right, Expr time) => Bound left -> Bound right -> time -> ReQL
during l r t = op DURING (t, getBound l, getBound r) [
"left_bound" := closedOrOpen l, "right_bound" := closedOrOpen r]
timezone, date, timeOfDay, year, month, day, dayOfWeek, dayOfYear, hours, minutes, seconds ::
Expr time => time -> ReQL
timezone t = op TIMEZONE [t] ()
date t = op DATE [t] ()
timeOfDay t = op TIME_OF_DAY [t] ()
year t = op YEAR [t] ()
month t = op MONTH [t] ()
day t = op DAY [t] ()
dayOfWeek t = op DAY_OF_WEEK [t] ()
dayOfYear t = op DAY_OF_YEAR [t] ()
hours t = op HOURS [t] ()
minutes t = op MINUTES [t] ()
seconds t = op SECONDS [t] ()
toIso8601, toEpochTime :: Expr t => t -> ReQL
toIso8601 t = op TO_ISO8601 [t] ()
toEpochTime t = op TO_EPOCH_TIME [t] ()
newtype UTCTime = UTCTime Time.UTCTime
instance Show UTCTime where
show (UTCTime t) = show t
newtype ZonedTime = ZonedTime Time.ZonedTime
instance Show ZonedTime where
show (ZonedTime t) = show t
instance FromJSON UTCTime where
parseJSON (JSON.Object v) = UTCTime . Time.posixSecondsToUTCTime . fromRational <$> v .: "epoch_time"
parseJSON _ = mzero
instance FromJSON ZonedTime where
parseJSON (JSON.Object v) = do
tz <- v .: "timezone"
t <- v.: "epoch_time"
tz' <- parseTimeZone tz
return . ZonedTime $ Time.utcToZonedTime tz'
(Time.posixSecondsToUTCTime (fromRational t))
parseJSON _ = mzero
parseTimeZone :: String -> Parser Time.TimeZone
parseTimeZone "Z" = return Time.utc
parseTimeZone tz = Time.minutesToTimeZone <$> case tz of
('-':tz') -> negate <$> go tz'
('+':tz') -> go tz'
_ -> go tz
where
go tz' = do
(h, _:m) <- return $ break (==':') tz'
([(hh, "")], [(mm, "")]) <- return $ (reads h, reads m)
return $ hh * 60 + mm
instance Expr UTCTime where
expr (UTCTime t) = expr t
instance Expr ZonedTime where
expr (ZonedTime t) = expr t