hourglass 0.2.6 → 0.2.7
raw patch · 5 files changed
+187/−15 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.Hourglass.Compat: dateFromPOSIXEpoch :: Integer -> Date
+ Data.Hourglass.Compat: dateFromTAIEpoch :: Integer -> Date
+ Data.Hourglass.Compat: diffTimeToTimeOfDay :: Real t => t -> TimeOfDay
Files
- CHANGELOG.md +33/−6
- Data/Hourglass/Compat.hs +104/−0
- Data/Hourglass/Format.hs +34/−4
- hourglass.cabal +2/−1
- tests/Tests.hs +14/−4
CHANGELOG.md view
@@ -1,14 +1,41 @@-## Version 0.2.2 (11 Jun 2014)+## Version 0.2.7 (2015-01-07) +- Add compatibility module for easy convertion with time and other standards.+- Format parsing improvements++## Version 0.2.6 (2014-10-19)++- fix compilation of benchs.+- add utc time.+- print the error in the test+- remove all the read instances in favor of explicit parsing in time parsing.++## Version 0.2.5 (2014-10-04)++- Fixed Windows build+- Added type signature to fromIntegral++## Version 0.2.4 (2014-09-30)++- Fix ElapsedP Num instance (addition and substraction)+- add travis machinery++## Version 0.2.3 (2014-09-25)++- Fix build on GNU/Hurd.+- Add milliseconds, microseconds and nanoseconds format time++## Version 0.2.2 (2014-06-11)+ - wrap system time in local time correctly -## Version 0.2.1 (10 Jun 2014)+## Version 0.2.1 (2014-06-10) - unwrap local time structure when doing a localTimePrint - properly show hours, minutes and seconds in format print. - add some description of new calls. -## Version 0.2.0 (3 Jun 2014)+## Version 0.2.0 (2014-06-03) - use tasty to replace test-framework - add some inlining pragma to tentatively deal with rules properly.@@ -22,17 +49,17 @@ - add some new derived classes (Enum,Real,Integral) for time unit types. - split TimeDiff into a Period and Duration structure. -## Version 0.1.2 (5 May 2014)+## Version 0.1.2 (2014-05-05) - fix compilation on OSX - add some system benchmarks - comment and markup reformating -## Version 0.1.1 (4 May 2014)+## Version 0.1.1 (2014-05-04) - add all the cabal tests file to the source dist - https-ize some urls -## Version 0.1.0 (4 May 2014)+## Version 0.1.0 (2014-05-04) - Initial version
+ Data/Hourglass/Compat.hs view
@@ -0,0 +1,104 @@+-- |+-- Module : Data.Hourglass.Compat+-- License : BSD-style+-- Maintainer : Nicolas DI PRIMA <nicolas@di-prima.fr>+--+-- Basic Time conversion compatibility.+--+-- This module aims to help conversion between the types from the package+-- time to the package hourglass.+--+-- Example of use (extracted from file Example/Time/Compat.hs):+--+-- > import Data.Hourglass as H+-- > import Data.Hourglass.Compat as C+-- > import Data.Time as T+-- >+-- > transpose :: T.ZonedTime+-- > -> H.LocalTime H.DateTime+-- > transpose oldTime =+-- > H.localTime+-- > offsetTime+-- > (H.DateTime newDate timeofday)+-- > where+-- > newDate :: H.Date+-- > newDate = C.dateFromTAIEpoch $ T.toModifiedJulianDay $ T.localDay $ T.zonedTimeToLocalTime oldTime+-- >+-- > timeofday :: H.TimeOfDay+-- > timeofday = C.diffTimeToTimeOfDay $ T.timeOfDayToTime $ T.localTimeOfDay $ T.zonedTimeToLocalTime oldTime+-- >+-- > offsetTime = H.TimezoneOffset $ fromIntegral $ T.timeZoneMinutes $ T.zonedTimeZone oldTime+--+module Data.Hourglass.Compat+ ( dateFromPOSIXEpoch+ , dateFromTAIEpoch+ , diffTimeToTimeOfDay+ ) where++import Data.Hourglass++-- | Convert an integer which represent the Number of days (To/From) POSIX Epoch+-- to a Date (POSIX Epoch is 1970-01-01).+dateFromPOSIXEpoch :: Integer -- ^ number of days since POSIX Epoch+ -> Date+dateFromPOSIXEpoch day = do+ let sec = Elapsed $ fromIntegral $ day * 86400+ timeConvert sec++-- | Number of days between POSIX Epoch and TAI Epoch+-- (between 1858-11-17 and 1970-01-01)+daysTAItoPOSIX :: Integer+daysTAItoPOSIX = 40587++-- | Convert an integer which represents the Number of days (To/From) TAI Epoch+-- This function allows use of the package time to easily convert the Day into+-- the Hourglass Date representation (TAI Epoch is 1858-11-17).+-- +-- This function allows user to easily convert a Data.Time.Calendar.Day into Date+--+-- > import qualified Data.Time.Calendar as T+-- >+-- > timeDay :: T.Day+-- >+-- > dateFromTAIEpoch $ T.toModifiedJulianDay timeDay+dateFromTAIEpoch :: Integer -- ^ number of days since TAI Epoch+ -> Date+dateFromTAIEpoch dtai =+ dateFromPOSIXEpoch (dtai - daysTAItoPOSIX)++-- | Convert of differential of time of a day.+-- (it convers a Data.Time.Clock.DiffTime into a TimeOfDay)+--+-- Example with DiffTime type from time:+--+-- > import qualified Data.Time.Clock as T+-- >+-- > difftime :: T.DiffTime+-- >+-- > diffTimeToTimeOfDay difftime+--+-- Example with the TimeOfDay type from time:+--+-- > import qualified Data.Time.Clock as T+-- >+-- > timeofday :: T.TimeOfDay+-- >+-- > diffTimeToTimeOfDay $ T.timeOfDayToTime timeofday+diffTimeToTimeOfDay :: Real t+ => t -- ^ number of seconds of the time of the day+ -> TimeOfDay+diffTimeToTimeOfDay dt = do+ TimeOfDay+ { todHour = fromIntegral hours+ , todMin = fromIntegral minutes+ , todSec = fromIntegral seconds+ , todNSec = fromIntegral nsecs+ }+ where+ r :: Rational+ r = toRational dt+ (secs, nR) = properFraction r :: (Integer, Rational)+ nsecs :: Integer+ nsecs = round (nR * 1000000000)+ (minsofday, seconds) = secs `divMod` 60 :: (Integer, Integer)+ (hours, minutes) = minsofday `divMod` 60 :: (Integer, Integer)
Data/Hourglass/Format.hs view
@@ -157,6 +157,23 @@ where dash = Format_Text '-' colon = Format_Text ':' +monthFromShort :: String -> Either String Month+monthFromShort str =+ case str of+ "Jan" -> Right January+ "Feb" -> Right February+ "Mar" -> Right March+ "Apr" -> Right April+ "May" -> Right May+ "Jun" -> Right June+ "Jul" -> Right July+ "Aug" -> Right August+ "Sep" -> Right September+ "Oct" -> Right October+ "Nov" -> Right November+ "Dec" -> Right December+ _ -> Left $ "unknown month: " ++ str+ printWith :: (TimeFormat format, Timeable t) => format -> TimezoneOffset@@ -250,6 +267,8 @@ $ getNDigitNum 2 s processOne acc Format_Month2 s = onSuccess (\m -> modDate (setMonth $ toEnum ((fromIntegral m - 1) `mod` 12)) acc) $ getNDigitNum 2 s+ processOne acc Format_MonthName_Short s =+ onSuccess (\m -> modDate (setMonth m) acc) $ getMonth s processOne acc Format_Day2 s = onSuccess (\d -> modDate (setDay d) acc) $ getNDigitNum 2 s processOne acc Format_Hour s =@@ -275,6 +294,7 @@ processOne acc Format_TzHM (c:s) = parseHMSign False acc c s + processOne acc Format_Spaces (' ':s) = Right (acc, s) -- catch all for unimplemented format. processOne _ f _ = error ("unimplemened parsing format: " ++ show f) @@ -307,10 +327,20 @@ (s1,s2) -> Right (toInt s1, s2) getNDigitNum :: Int -> String -> Either String (Int64, String)- getNDigitNum n s- | length s1 < n = Left ("not enough chars: expecting " ++ show n ++ " got " ++ show s1)- | not (allDigits s1) = Left ("not a digit chars in " ++ show s1)- | otherwise = Right (toInt s1, s2)+ getNDigitNum n s =+ case getNChar n s of+ Left err -> Left err+ Right (s1, s2) | not (allDigits s1) -> Left ("not a digit chars in " ++ show s1)+ | otherwise -> Right (toInt s1, s2)++ getMonth :: String -> Either String (Month, String)+ getMonth s =+ getNChar 3 s >>= \(s1, s2) -> monthFromShort s1 >>= \m -> Right (m, s2)++ getNChar :: Int -> String -> Either String (String, String)+ getNChar n s+ | length s1 < n = Left ("not enough chars: expecting " ++ show n ++ " got " ++ show s1)+ | otherwise = Right (s1, s2) where (s1, s2) = splitAt n s
hourglass.cabal view
@@ -1,5 +1,5 @@ Name: hourglass-Version: 0.2.6+Version: 0.2.7 Synopsis: simple performant time related library Description: Simple time library focusing on simple but powerful and performant API@@ -26,6 +26,7 @@ Exposed-modules: Data.Hourglass , Data.Hourglass.Types , Data.Hourglass.Epoch+ , Data.Hourglass.Compat , System.Hourglass Other-modules: Data.Hourglass.Time , Data.Hourglass.Format
tests/Tests.hs view
@@ -129,11 +129,12 @@ arithmeticTestSubRef :: [(ElapsedP, ElapsedP, ElapsedP)] arithmeticTestSubRef = map testRefToElapsedP- [ ((1, 100000000), (1, 100000000), (0, 000000000))- , ((1, 900000000), (1, 100000000), (0, 800000000))- , ((1, 100000000), (0, 200000000), (0, 900000000))- , ((1, 100000000), (2, 400000000), (-2, 700000000))+ [ ((1, ms 100), (1, ms 100), (0, ms 000))+ , ((1, ms 900), (1, ms 100), (0, ms 800))+ , ((1, ms 100), (0, ms 200), (0, ms 900))+ , ((1, ms 100), (2, ms 400), (-2, ms 700)) ]+ where ms v = v * 1000000 testRefToElapsedP :: ((Int64, Int64), (Int64, Int64), (Int64, Int64)) -> (ElapsedP, ElapsedP, ElapsedP) testRefToElapsedP (a, b, c) = (tupleToElapsedP a, tupleToElapsedP b, tupleToElapsedP c) @@ -206,6 +207,8 @@ case r of Right (localtime, "") -> tz `eq` localTimeGetTimezone localtime _ -> error "Cannot parse timezone"+ , testProperty "custom-1" $ test_property_format ("YYYY-MM-DDTH:MI:S.msusns" :: String)+ , testProperty "custom-2" $ test_property_format ("Mon DD\\t\\h YYYY at HH\\hMI\\mS\\s.p9\\n\\s" :: String) ] ] where toCalendarTest (i, (us, dt)) =@@ -223,6 +226,13 @@ calTimeFormatTimeISO8601 timePosix = T.formatTime T.defaultTimeLocale "%F" (T.posixSecondsToUTCTime timePosix)++ test_property_format :: (TimeFormat format, Show format) => format -> DateTime -> Bool+ test_property_format fmt dt =+ let p1 = timePrint fmt dt in+ case timeParseE fmt p1 of+ Left (fmtEl, err) -> error ("cannot decode printed DateTime: " ++ show p1 ++ " with format " ++ show fmt ++ " error with(" ++ show fmtEl ++ "): " ++ err)+ Right (dt2, _) -> dt `eq` dt2 main = do knowns <- E.catch (map parseTimeConv . lines <$> readFile "test-time-db")