summaryrefslogtreecommitdiff
path: root/Utility/TimeStamp.hs
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2020-05-04 15:38:39 -0400
committerJoey Hess <joeyh@joeyh.name>2020-05-04 15:38:39 -0400
commit8c4352a0a544b2e5a4ed717999fc7c6ecb0a328f (patch)
treed57aca56117598b06bf30e5a1ed96f4b77e51f09 /Utility/TimeStamp.hs
parent6ea7eac330f73699d965cef7b8ee23d7218415a8 (diff)
downloadgit-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.hs58
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)