module Text.Show.Text.Data.Time (
showbDay
, showbDiffTime
, showbUTCTime
, showbNominalDiffTime
, showbAbsoluteTime
, showbTimeZone
, showbTimeOfDay
, showbLocalTime
, showbZonedTime
) where
import Data.Text.Lazy.Builder (Builder)
import Data.Time.Calendar (Day)
import Data.Time.Clock (DiffTime, UTCTime, NominalDiffTime)
import Data.Time.Clock.TAI (AbsoluteTime, taiToUTCTime)
import Data.Time.LocalTime (TimeZone(..), TimeOfDay(..), LocalTime(..),
ZonedTime(..), utc, utcToLocalTime)
import Prelude hiding (Show)
import Text.Show.Text.Class (Show(showb))
import Text.Show.Text.Utils ((<>))
#if defined(TEXT_FORMAT)
import Data.Text.Buildable (build)
#else
import Data.Fixed (Pico)
import Data.Text.Lazy.Builder (fromString)
import Data.Time.Calendar (toGregorian)
import Data.Time.Format (NumericPadOption)
import Data.Time.LocalTime (utcToZonedTime)
import qualified Prelude as P
import Text.Show.Text.Data.Fixed (showbFixed)
import Text.Show.Text.Data.Integral ()
import Text.Show.Text.Utils (lengthB, replicateB, s)
#endif
showbDay :: Day -> Builder
#if defined(TEXT_FORMAT)
showbDay = build
#else
showbDay = showbGregorian
#endif
showbDiffTime :: DiffTime -> Builder
#if defined(TEXT_FORMAT)
showbDiffTime = build
#else
showbDiffTime = fromString . P.show
#endif
showbUTCTime :: UTCTime -> Builder
#if defined(TEXT_FORMAT)
showbUTCTime = build
#else
showbUTCTime = showb . utcToZonedTime utc
#endif
showbNominalDiffTime :: NominalDiffTime -> Builder
#if defined(TEXT_FORMAT)
showbNominalDiffTime = build
#else
showbNominalDiffTime = fromString . P.show
#endif
showbAbsoluteTime :: AbsoluteTime -> Builder
showbAbsoluteTime t = showbLocalTime (utcToLocalTime utc $ taiToUTCTime (const 0) t)
<> " TAI"
showbTimeZone :: TimeZone -> Builder
#if defined(TEXT_FORMAT)
showbTimeZone = build
#else
showbTimeZone zone@(TimeZone _ _ "") = timeZoneOffsetBuilder zone
showbTimeZone (TimeZone _ _ name) = fromString name
#endif
showbTimeOfDay :: TimeOfDay -> Builder
#if defined(TEXT_FORMAT)
showbTimeOfDay = build
#else
showbTimeOfDay (TimeOfDay h m sec) = showb2 zeroOpt h
<> s ':'
<> showb2 zeroOpt m
<> s ':'
<> showb2Fixed zeroOpt sec
#endif
showbLocalTime :: LocalTime -> Builder
#if defined(TEXT_FORMAT)
showbLocalTime = build
#else
showbLocalTime (LocalTime d t) = showbGregorian d <> s ' ' <> showb t
#endif
showbZonedTime :: ZonedTime -> Builder
#if defined(TEXT_FORMAT)
showbZonedTime = build
#else
showbZonedTime (ZonedTime t zone) = showb t <> s ' ' <> showb zone
#endif
#if !defined(TEXT_FORMAT)
pad1 :: NumericPadOption -> Builder -> Builder
pad1 (Just c) b = s c <> b
pad1 _ b = b
padN :: Int -> Char -> Builder -> Builder
padN i _ b | i <= 0 = b
padN i c b = replicateB (fromIntegral i) (s c) <> b
showb2 :: (Num t, Ord t, Show t) => NumericPadOption -> t -> Builder
showb2 = showbPaddedMin 2
showb2Fixed :: NumericPadOption -> Pico -> Builder
showb2Fixed opt x | x < 10 = pad1 opt $ showbFixed True x
showb2Fixed _ x = showbFixed True x
showb4 :: (Num t, Ord t, Show t) => NumericPadOption -> t -> Builder
showb4 = showbPaddedMin 4
showbGregorian :: Day -> Builder
showbGregorian date = showb4 zeroOpt y
<> s '-'
<> showb2 zeroOpt m
<> s '-'
<> showb2 zeroOpt d
where
(y,m,d) = toGregorian date
showbPaddedMin :: (Num t, Ord t, Show t) => Int -> NumericPadOption -> t -> Builder
showbPaddedMin _ Nothing i = showb i
showbPaddedMin pl opt i | i < 0 = s '-' <> showbPaddedMin pl opt (negate i)
showbPaddedMin pl (Just c) i =
let b = showb i
in padN (pl fromIntegral (lengthB b)) c b
showbT :: NumericPadOption -> Int -> Builder
showbT opt t = showb4 opt ((div t 60) * 100 + (mod t 60))
timeZoneOffsetBuilder' :: NumericPadOption -> TimeZone -> Builder
timeZoneOffsetBuilder' opt (TimeZone t _ _) | t < 0 = s '-' <> showbT opt (negate t)
timeZoneOffsetBuilder' opt (TimeZone t _ _) = s '+' <> showbT opt t
timeZoneOffsetBuilder :: TimeZone -> Builder
timeZoneOffsetBuilder = timeZoneOffsetBuilder' $ Just '0'
zeroOpt :: NumericPadOption
zeroOpt = Just '0'
#endif
instance Show Day where
showb = showbDay
instance Show DiffTime where
showb = showbDiffTime
instance Show UTCTime where
showb = showbUTCTime
instance Show NominalDiffTime where
showb = showbNominalDiffTime
instance Show AbsoluteTime where
showb = showbAbsoluteTime
instance Show TimeZone where
showb = showbTimeZone
instance Show TimeOfDay where
showb = showbTimeOfDay
instance Show LocalTime where
showb = showbLocalTime
instance Show ZonedTime where
showb = showbZonedTime