Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions lib/Data/Format.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE Safe #-}

module Data.Format (
Expand Down Expand Up @@ -26,6 +27,9 @@ module Data.Format (

import Control.Monad.Fail
import Data.Char
#if MIN_VERSION_base(4,19,0)
import Data.List (unsnoc)
#endif
import Data.Void
import Text.ParserCombinators.ReadP
import Prelude hiding (fail)
Expand Down Expand Up @@ -227,11 +231,17 @@ zeroPad Nothing s = s
zeroPad (Just i) s = replicate (i - length s) '0' ++ s

trimTrailing :: String -> String
trimTrailing "" = ""
trimTrailing "." = ""
trimTrailing s
| last s == '0' = trimTrailing $ init s
trimTrailing s = s
trimTrailing s = case unsnoc s of
Nothing -> ""
Just (initial, '0') -> trimTrailing initial
_ -> s

#if !MIN_VERSION_base(4,19,0)
unsnoc :: [a] -> Maybe ([a], a)
unsnoc = foldr (\x -> Just . maybe ([], x) (\(~(a, b)) -> (x : a, b))) Nothing
{-# INLINABLE unsnoc #-}
#endif

showNumber :: Show t => SignOption -> Maybe Int -> t -> Maybe String
showNumber signOpt mdigitcount t =
Expand Down
33 changes: 23 additions & 10 deletions test/unix/Test/Format/Format.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# OPTIONS -fno-warn-orphans #-}

module Test.Format.Format (
Expand All @@ -6,6 +7,9 @@ module Test.Format.Format (

import Data.Char
import Data.Fixed as F
#if MIN_VERSION_base(4,19,0)
import Data.List (unsnoc)
#endif
import Data.Time
import Data.Time.Clock.POSIX
import Foreign
Expand Down Expand Up @@ -151,16 +155,25 @@ unixWorkarounds fmt s
unixWorkarounds _ s = s

compareFormat :: (String -> String) -> String -> TimeZone -> UTCTime -> Result
compareFormat _modUnix fmt zone _time
| last fmt == 'Z' && timeZoneName zone == "" = rejected
compareFormat modUnix fmt zone time =
let
ctime = utcToZonedTime zone time
haskellText = formatTime locale fmt ctime
unixText = unixFormatTime fmt zone time
expectedText = unixWorkarounds fmt (modUnix unixText)
in
assertEqualQC (show time ++ " with " ++ show zone) expectedText haskellText
compareFormat modUnix fmt zone time = case unsnoc fmt of
Nothing ->
error "compareFormat: The impossible happened! Format string is \"\"."
Just (_, lastChar)
| lastChar == 'Z' && timeZoneName zone == "" -> rejected
| otherwise ->
let
ctime = utcToZonedTime zone time
haskellText = formatTime locale fmt ctime
unixText = unixFormatTime fmt zone time
expectedText = unixWorkarounds fmt (modUnix unixText)
in
assertEqualQC (show time ++ " with " ++ show zone) expectedText haskellText

#if !MIN_VERSION_base(4,19,0)
unsnoc :: [a] -> Maybe ([a], a)
unsnoc = foldr (\x -> Just . maybe ([], x) (\(~(a, b)) -> (x : a, b))) Nothing
{-# INLINABLE unsnoc #-}
#endif

-- as found in http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html
-- plus FgGklz
Expand Down