module Text.Show.Text.Data.Time (
showbDay
, showbDiffTime
, showbUTCTime
, showbNominalDiffTime
, showbAbsoluteTime
, showbTimeZone
, showbTimeOfDay
, showbLocalTime
, showbZonedTime
) where
import Data.Fixed (Pico)
import Data.Time.Calendar (Day, toGregorian)
import Data.Time.Clock (DiffTime, UTCTime, NominalDiffTime)
import Data.Time.Clock.TAI (AbsoluteTime, taiToUTCTime)
import Data.Time.Format (NumericPadOption)
import Data.Time.LocalTime (TimeZone(..), TimeOfDay(..), LocalTime(..), ZonedTime(..),
utc, utcToLocalTime, utcToZonedTime)
import Prelude hiding (Show)
import Text.Show.Text (Builder, Show(showb), fromString,
lengthB, replicateB, showbSpace,
FromStringShow(..))
import Text.Show.Text.Data.Fixed (showbFixed)
import Text.Show.Text.Data.Integral ()
import Text.Show.Text.Utils ((<>), s)
#include "inline.h"
showbDay :: Day -> Builder
showbDay = showbGregorian
showbDiffTime :: DiffTime -> Builder
showbDiffTime = showb . FromStringShow
showbUTCTime :: UTCTime -> Builder
showbUTCTime = showb . utcToZonedTime utc
showbNominalDiffTime :: NominalDiffTime -> Builder
showbNominalDiffTime = showb . FromStringShow
showbAbsoluteTime :: AbsoluteTime -> Builder
showbAbsoluteTime t = showbLocalTime (utcToLocalTime utc $ taiToUTCTime (const 0) t)
<> " TAI"
showbTimeZone :: TimeZone -> Builder
showbTimeZone zone@(TimeZone _ _ "") = timeZoneOffsetBuilder zone
showbTimeZone (TimeZone _ _ name) = fromString name
showbTimeOfDay :: TimeOfDay -> Builder
showbTimeOfDay (TimeOfDay h m sec) = showb2 zeroOpt h
<> s ':'
<> showb2 zeroOpt m
<> s ':'
<> showb2Fixed zeroOpt sec
showbLocalTime :: LocalTime -> Builder
showbLocalTime (LocalTime d t) = showbGregorian d <> showbSpace <> showb t
showbZonedTime :: ZonedTime -> Builder
showbZonedTime (ZonedTime t zone) = showb t <> showbSpace <> showb zone
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'
instance Show Day where
showb = showbDay
INLINE_INST_FUN(showb)
instance Show DiffTime where
showb = showbDiffTime
INLINE_INST_FUN(showb)
instance Show UTCTime where
showb = showbUTCTime
INLINE_INST_FUN(showb)
instance Show NominalDiffTime where
showb = showbNominalDiffTime
INLINE_INST_FUN(showb)
instance Show AbsoluteTime where
showb = showbAbsoluteTime
INLINE_INST_FUN(showb)
instance Show TimeZone where
showb = showbTimeZone
INLINE_INST_FUN(showb)
instance Show TimeOfDay where
showb = showbTimeOfDay
INLINE_INST_FUN(showb)
instance Show LocalTime where
showb = showbLocalTime
INLINE_INST_FUN(showb)
instance Show ZonedTime where
showb = showbZonedTime
INLINE_INST_FUN(showb)