{-# OPTIONS_GHC -fno-warn-orphans #-}

module Data.Time.Clock.Instances
  ( iso8601OutputFormat, iso8601ParseFormat
  ) where

import ClassyPrelude

import Database.Persist.Sql

import Data.Proxy

import Data.Binary (Binary)
import qualified Data.Binary as Binary

import Data.Time.Clock
import Data.Time.Calendar.Instances ()
import Web.PathPieces

import qualified Data.Csv as Csv


instance Hashable DiffTime where
  hashWithSalt s = hashWithSalt s . toRational

instance PersistField NominalDiffTime where
  toPersistValue   = toPersistValue . toRational
  fromPersistValue = fmap fromRational . fromPersistValue

instance PersistFieldSql NominalDiffTime where
  sqlType _ = sqlType (Proxy @Rational)


iso8601OutputFormat, iso8601ParseFormat :: String
iso8601OutputFormat = "%0Y-%m-%dT%H:%M:%S%Q%z"
iso8601ParseFormat = "%Y-%m-%dT%H:%M:%S%Q%z"


deriving instance Generic UTCTime
instance Hashable UTCTime

instance PathPiece UTCTime where
  toPathPiece = pack . formatTime defaultTimeLocale iso8601OutputFormat
  fromPathPiece = parseTimeM False defaultTimeLocale iso8601ParseFormat . unpack

instance Csv.ToField UTCTime where
  toField = Csv.toField . formatTime defaultTimeLocale iso8601OutputFormat

instance Csv.FromField UTCTime where
  parseField = parseTimeM False defaultTimeLocale iso8601ParseFormat <=< Csv.parseField


instance Binary DiffTime where
  get = fromRational <$> Binary.get
  put = Binary.put . toRational

instance Binary UTCTime
