diff options
author | Joey Hess <joeyh@joeyh.name> | 2020-05-04 15:38:39 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2020-05-04 15:38:39 -0400 |
commit | 8c4352a0a544b2e5a4ed717999fc7c6ecb0a328f (patch) | |
tree | d57aca56117598b06bf30e5a1ed96f4b77e51f09 /Utility/TimeStamp.hs | |
parent | 6ea7eac330f73699d965cef7b8ee23d7218415a8 (diff) | |
download | git-repair-8c4352a0a544b2e5a4ed717999fc7c6ecb0a328f.tar.gz |
merge from git-annex
* Improve fetching from a remote with an url in host:path format.
* Merge from git-annex.
Diffstat (limited to 'Utility/TimeStamp.hs')
-rw-r--r-- | Utility/TimeStamp.hs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/Utility/TimeStamp.hs b/Utility/TimeStamp.hs new file mode 100644 index 0000000..b740d7b --- /dev/null +++ b/Utility/TimeStamp.hs @@ -0,0 +1,58 @@ +{- timestamp parsing and formatting + - + - Copyright 2015-2019 Joey Hess <id@joeyh.name> + - + - License: BSD-2-clause + -} + +module Utility.TimeStamp ( + parserPOSIXTime, + parsePOSIXTime, + formatPOSIXTime, +) where + +import Utility.Data + +import Data.Time.Clock.POSIX +import Data.Time +import Data.Ratio +import Control.Applicative +import qualified Data.ByteString as B +import qualified Data.ByteString.Char8 as B8 +import qualified Data.Attoparsec.ByteString as A +import Data.Attoparsec.ByteString.Char8 (char, decimal, signed, isDigit_w8) + +{- Parses how POSIXTime shows itself: "1431286201.113452s" + - (The "s" is included for historical reasons and is optional.) + - Also handles the format with no decimal seconds. -} +parserPOSIXTime :: A.Parser POSIXTime +parserPOSIXTime = mkPOSIXTime + <$> signed decimal + <*> (declen <|> pure (0, 0)) + <* optional (char 's') + where + declen :: A.Parser (Integer, Int) + declen = do + _ <- char '.' + b <- A.takeWhile isDigit_w8 + let len = B.length b + d <- either fail pure $ + A.parseOnly (decimal <* A.endOfInput) b + return (d, len) + +parsePOSIXTime :: String -> Maybe POSIXTime +parsePOSIXTime s = eitherToMaybe $ + A.parseOnly (parserPOSIXTime <* A.endOfInput) (B8.pack s) + +{- This implementation allows for higher precision in a POSIXTime than + - supported by the system's Double, and avoids the complications of + - floating point. -} +mkPOSIXTime :: Integer -> (Integer, Int) -> POSIXTime +mkPOSIXTime n (d, dlen) + | n < 0 = fromIntegral n - fromRational r + | otherwise = fromIntegral n + fromRational r + where + r = d % (10 ^ dlen) + +formatPOSIXTime :: String -> POSIXTime -> String +formatPOSIXTime fmt t = formatTime defaultTimeLocale fmt (posixSecondsToUTCTime t) |