packages feed

unix-time 0.4.9 → 0.4.10

raw patch · 5 files changed

+128/−104 lines, 5 filesdep +template-haskellPVP ok

version bump matches the API change (PVP)

Dependencies added: template-haskell

API changes (from Hackage documentation)

Files

Data/UnixTime.hs view
@@ -1,31 +1,36 @@ module Data.UnixTime (-  -- * Data structure-    UnixTime(..)-  -- * Getting time-  , getUnixTime-  -- * Parsing and formatting time-  , parseUnixTime-  , parseUnixTimeGMT-  , formatUnixTime-  , formatUnixTimeGMT-  -- * Format-  , Format-  , webDateFormat-  , mailDateFormat-  -- * Difference time-  , UnixDiffTime(..)-  , diffUnixTime-  , addUnixDiffTime-  , secondsToUnixDiffTime-  , microSecondsToUnixDiffTime-  -- * Translating time-  , fromEpochTime-  , toEpochTime-  , fromClockTime-  , toClockTime-  ) where+    -- * Data structure+    UnixTime (..), +    -- * Getting time+    getUnixTime,++    -- * Parsing and formatting time+    parseUnixTime,+    parseUnixTimeGMT,+    formatUnixTime,+    formatUnixTimeGMT,++    -- * Format+    Format,+    webDateFormat,+    mailDateFormat,++    -- * Difference time+    UnixDiffTime (..),+    diffUnixTime,+    addUnixDiffTime,+    secondsToUnixDiffTime,+    microSecondsToUnixDiffTime,++    -- * Translating time+    fromEpochTime,+    toEpochTime,+    fromClockTime,+    toClockTime,+) where+ import Data.UnixTime.Conv+import Data.UnixTime.Diff import Data.UnixTime.Sys import Data.UnixTime.Types-import Data.UnixTime.Diff
Data/UnixTime/Conv.hs view
@@ -2,12 +2,17 @@ {-# LANGUAGE OverloadedStrings #-}  module Data.UnixTime.Conv (-    formatUnixTime, formatUnixTimeGMT-  , parseUnixTime, parseUnixTimeGMT-  , webDateFormat, mailDateFormat-  , fromEpochTime, toEpochTime-  , fromClockTime, toClockTime-  ) where+    formatUnixTime,+    formatUnixTimeGMT,+    parseUnixTime,+    parseUnixTimeGMT,+    webDateFormat,+    mailDateFormat,+    fromEpochTime,+    toEpochTime,+    fromClockTime,+    toClockTime,+) where  import Control.Applicative import Data.ByteString.Char8@@ -18,23 +23,23 @@ import Foreign.Marshal.Alloc import System.IO.Unsafe (unsafePerformIO) import System.Posix.Types (EpochTime)-import System.Time (ClockTime(..))+import System.Time (ClockTime (..))  -- $setup -- >>> import Data.Function (on) -- >>> :set -XOverloadedStrings  foreign import ccall unsafe "c_parse_unix_time"-        c_parse_unix_time :: CString -> CString -> IO CTime+    c_parse_unix_time :: CString -> CString -> IO CTime  foreign import ccall unsafe "c_parse_unix_time_gmt"-        c_parse_unix_time_gmt :: CString -> CString -> IO CTime+    c_parse_unix_time_gmt :: CString -> CString -> IO CTime  foreign import ccall unsafe "c_format_unix_time"-        c_format_unix_time :: CString -> CTime -> CString -> CInt -> IO CSize+    c_format_unix_time :: CString -> CTime -> CString -> CInt -> IO CSize  foreign import ccall unsafe "c_format_unix_time_gmt"-        c_format_unix_time_gmt :: CString -> CTime -> CString -> CInt -> IO CSize+    c_format_unix_time_gmt :: CString -> CTime -> CString -> CInt -> IO CSize  ---------------------------------------------------------------- @@ -44,13 +49,13 @@ -- Many implementations of strptime_l() do not support %Z and -- some implementations of strptime_l() do not support %z, either. -- 'utMicroSeconds' is always set to 0.- parseUnixTime :: Format -> ByteString -> UnixTime parseUnixTime fmt str = unsafePerformIO $     useAsCString fmt $ \cfmt ->         useAsCString str $ \cstr -> do             sec <- c_parse_unix_time cfmt cstr             return $ UnixTime sec 0+ -- | -- Parsing 'ByteString' to 'UnixTime' interpreting as GMT. -- This is a wrapper for strptime_l().@@ -58,7 +63,6 @@ -- -- >>> parseUnixTimeGMT webDateFormat "Thu, 01 Jan 1970 00:00:00 GMT" -- UnixTime {utSeconds = 0, utMicroSeconds = 0}- parseUnixTimeGMT :: Format -> ByteString -> UnixTime parseUnixTimeGMT fmt str = unsafePerformIO $     useAsCString fmt $ \cfmt ->@@ -73,8 +77,6 @@ -- This is a wrapper for strftime_l(). -- 'utMicroSeconds' is ignored. -- The result depends on the TZ environment variable.---- formatUnixTime :: Format -> UnixTime -> IO ByteString formatUnixTime fmt t =     formatUnixTimeHelper c_format_unix_time fmt t@@ -94,7 +96,6 @@ -- True -- >>> ((==) `on` utMicroSeconds) ut ut' -- False- formatUnixTimeGMT :: Format -> UnixTime -> ByteString formatUnixTimeGMT fmt t =     unsafePerformIO $ formatUnixTimeHelper c_format_unix_time_gmt fmt t@@ -102,7 +103,6 @@  -- | -- Helper handling memory allocation for formatUnixTime and formatUnixTimeGMT.- formatUnixTimeHelper     :: (CString -> CTime -> CString -> CInt -> IO CSize)     -> Format@@ -111,8 +111,8 @@ formatUnixTimeHelper formatFun fmt (UnixTime sec _) =     useAsCString fmt $ \cfmt -> do         let siz = 80-        ptr  <- mallocBytes siz-        len  <- fromIntegral <$> formatFun cfmt sec ptr (fromIntegral siz)+        ptr <- mallocBytes siz+        len <- fromIntegral <$> formatFun cfmt sec ptr (fromIntegral siz)         ptr' <- reallocBytes ptr (len + 1)         unsafePackMallocCString ptr' -- FIXME: Use unsafePackMallocCStringLen from bytestring-0.10.2.0 @@ -122,7 +122,6 @@ -- Format for web (RFC 2616). -- The value is \"%a, %d %b %Y %H:%M:%S GMT\". -- This should be used with 'formatUnixTimeGMT' and 'parseUnixTimeGMT'.- webDateFormat :: Format webDateFormat = "%a, %d %b %Y %H:%M:%S GMT" @@ -130,7 +129,6 @@ -- Format for e-mail (RFC 5322). -- The value is \"%a, %d %b %Y %H:%M:%S %z\". -- This should be used with 'formatUnixTime' and 'parseUnixTime'.- mailDateFormat :: Format mailDateFormat = "%a, %d %b %Y %H:%M:%S %z" @@ -138,19 +136,16 @@  -- | -- From 'EpochTime' to 'UnixTime' setting 'utMicroSeconds' to 0.- fromEpochTime :: EpochTime -> UnixTime fromEpochTime sec = UnixTime sec 0  -- | -- From 'UnixTime' to 'EpochTime' ignoring 'utMicroSeconds'.- toEpochTime :: UnixTime -> EpochTime toEpochTime (UnixTime sec _) = sec  -- | -- From 'ClockTime' to 'UnixTime'.- fromClockTime :: ClockTime -> UnixTime fromClockTime (TOD sec psec) = UnixTime sec' usec'   where@@ -159,7 +154,6 @@  -- | -- From 'UnixTime' to 'ClockTime'.- toClockTime :: UnixTime -> ClockTime toClockTime (UnixTime sec usec) = TOD sec' psec'   where
Data/UnixTime/Diff.hs view
@@ -1,14 +1,14 @@ {-# OPTIONS_GHC -fno-warn-orphans #-}  module Data.UnixTime.Diff (-    diffUnixTime-  , addUnixDiffTime-  , secondsToUnixDiffTime-  , microSecondsToUnixDiffTime-  ) where+    diffUnixTime,+    addUnixDiffTime,+    secondsToUnixDiffTime,+    microSecondsToUnixDiffTime,+) where -import Data.UnixTime.Types import Data.Int+import Data.UnixTime.Types import Foreign.C.Types  -- $setup@@ -33,23 +33,22 @@ -- UnixDiffTime {udtSeconds = -3, udtMicroSeconds = 0} -- >>> (3 :: UnixDiffTime) * 2 -- UnixDiffTime {udtSeconds = 6, udtMicroSeconds = 0}- instance Num UnixDiffTime where-    UnixDiffTime s1 u1 + UnixDiffTime s2 u2 = calc (s1+s2) (u1+u2)-    UnixDiffTime s1 u1 - UnixDiffTime s2 u2 = calc (s1-s2) (u1-u2)-    UnixDiffTime s1 u1 * UnixDiffTime s2 u2 = calc' (s1*s2) (u1*u2)+    UnixDiffTime s1 u1 + UnixDiffTime s2 u2 = calc (s1 + s2) (u1 + u2)+    UnixDiffTime s1 u1 - UnixDiffTime s2 u2 = calc (s1 - s2) (u1 - u2)+    UnixDiffTime s1 u1 * UnixDiffTime s2 u2 = calc' (s1 * s2) (u1 * u2)     negate (UnixDiffTime s u) = UnixDiffTime (-s) (-u)     abs (UnixDiffTime s u) = UnixDiffTime (abs s) (abs u)     signum (UnixDiffTime s u)-         | s == 0 && u == 0 = 0-         | s > 0            = 1-         | otherwise        = -1+        | s == 0 && u == 0 = 0+        | s > 0 = 1+        | otherwise = -1     fromInteger i = UnixDiffTime (fromInteger i) 0  {-# RULES "Integral->UnixDiffTime" fromIntegral = secondsToUnixDiffTime #-}  instance Real UnixDiffTime where-        toRational = toFractional+    toRational = toFractional  {-# RULES "UnixDiffTime->Fractional" realToFrac = toFractional #-} @@ -59,25 +58,21 @@ -- -- >>> UnixTime 100 2000 `diffUnixTime` UnixTime 98 2100 -- UnixDiffTime {udtSeconds = 1, udtMicroSeconds = 999900}---- diffUnixTime :: UnixTime -> UnixTime -> UnixDiffTime-diffUnixTime (UnixTime s1 u1) (UnixTime s2 u2) = calc (s1-s2) (u1-u2)+diffUnixTime (UnixTime s1 u1) (UnixTime s2 u2) = calc (s1 - s2) (u1 - u2)  -- | Adding difference to 'UnixTime'. -- -- >>> UnixTime 100 2000 `addUnixDiffTime` microSecondsToUnixDiffTime ((-1003000) :: Int) -- UnixTime {utSeconds = 98, utMicroSeconds = 999000}- addUnixDiffTime :: UnixTime -> UnixDiffTime -> UnixTime-addUnixDiffTime (UnixTime s1 u1) (UnixDiffTime s2 u2) = calcU (s1+s2) (u1+u2)+addUnixDiffTime (UnixTime s1 u1) (UnixDiffTime s2 u2) = calcU (s1 + s2) (u1 + u2)  -- | Creating difference from seconds. -- -- >>> secondsToUnixDiffTime (100 :: Int) -- UnixDiffTime {udtSeconds = 100, udtMicroSeconds = 0}--secondsToUnixDiffTime :: (Integral a) => a -> UnixDiffTime+secondsToUnixDiffTime :: Integral a => a -> UnixDiffTime secondsToUnixDiffTime sec = UnixDiffTime (fromIntegral sec) 0 {-# INLINE secondsToUnixDiffTime #-} @@ -88,37 +83,36 @@ -- -- >>> microSecondsToUnixDiffTime ((-12345678) :: Int) -- UnixDiffTime {udtSeconds = -12, udtMicroSeconds = -345678}--microSecondsToUnixDiffTime :: (Integral a) => a -> UnixDiffTime+microSecondsToUnixDiffTime :: Integral a => a -> UnixDiffTime microSecondsToUnixDiffTime usec = calc (fromIntegral s) (fromIntegral u)   where-    (s,u) = secondMicro usec+    (s, u) = secondMicro usec {-# INLINE microSecondsToUnixDiffTime #-}  ----------------------------------------------------------------  adjust :: CTime -> Int32 -> (CTime, Int32) adjust sec usec-  | sec >= 0  = ajp-  | otherwise = ajm+    | sec >= 0 = ajp+    | otherwise = ajm   where-    micro  = 1000000-    mmicro = - micro+    micro = 1000000+    mmicro = -micro     ajp-     | usec >= micro  = (sec + 1, usec - micro)-     | usec >= 0      = (sec, usec)-     | otherwise      = (sec - 1, usec + micro)+        | usec >= micro = (sec + 1, usec - micro)+        | usec >= 0 = (sec, usec)+        | otherwise = (sec - 1, usec + micro)     ajm-     | usec <= mmicro = (sec - 1, usec + micro)-     | usec <= 0      = (sec, usec)-     | otherwise      = (sec + 1, usec - micro)+        | usec <= mmicro = (sec - 1, usec + micro)+        | usec <= 0 = (sec, usec)+        | otherwise = (sec + 1, usec - micro)  slowAdjust :: CTime -> Int32 -> (CTime, Int32) slowAdjust sec usec = (sec + fromIntegral s, usec - u)   where-    (s,u) = secondMicro usec+    (s, u) = secondMicro usec -secondMicro :: Integral a => a -> (a,a)+secondMicro :: Integral a => a -> (a, a) secondMicro usec = usec `quotRem` 1000000  toFractional :: Fractional a => UnixDiffTime -> a
test/UnixTimeSpec.hs view
@@ -1,4 +1,7 @@-{-# LANGUAGE OverloadedStrings, FlexibleInstances, CPP #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell #-} {-# OPTIONS_GHC -fno-warn-orphans #-}  module UnixTimeSpec (main, spec) where@@ -9,9 +12,10 @@ import Data.Time import Data.Time.Clock.POSIX (posixSecondsToUTCTime) import Data.UnixTime-import Foreign.Ptr (Ptr) import Foreign.Marshal.Alloc (alloca)+import Foreign.Ptr (Ptr) import Foreign.Storable (peek, poke)+import qualified Language.Haskell.TH as TH (runIO) import Test.Hspec import Test.Hspec.QuickCheck (prop) import Test.QuickCheck hiding ((===))@@ -25,12 +29,13 @@  instance Arbitrary UnixTime where     arbitrary = do-        a <- choose (0,4294967295) :: Gen Int-        b <- choose (0,999999) :: Gen Int-        let ut = UnixTime {-                utSeconds = abs (fromIntegral a)-              , utMicroSeconds = fromIntegral b-              }+        a <- choose (0, 4294967295) :: Gen Int+        b <- choose (0, 999999) :: Gen Int+        let ut =+                UnixTime+                    { utSeconds = abs (fromIntegral a)+                    , utMicroSeconds = fromIntegral b+                    }         return ut  spec :: Spec@@ -46,32 +51,44 @@     describe "parseUnixTimeGMT & formatUnixTimeGMT" $ do         let (===) = (==) `on` utSeconds         prop "inverses the result" $ \ut ->-            let dt  = formatUnixTimeGMT webDateFormat ut-                ut' = parseUnixTimeGMT  webDateFormat dt+            let dt = formatUnixTimeGMT webDateFormat ut+                ut' = parseUnixTimeGMT webDateFormat dt                 dt' = formatUnixTimeGMT webDateFormat ut'-            in ut === ut' && dt == dt'+             in ut === ut' && dt == dt'         prop "inverses the result (2)" $ \ut ->             let str = formatUnixTimeGMT "%s" ut                 ut' = parseUnixTimeGMT "%s" str-            in ut === ut'+             in ut === ut'      describe "addUnixDiffTime & diffUnixTime" $         prop "invrses the result" $ \(ut0, ut1) ->             let ut0' = addUnixDiffTime ut1 $ diffUnixTime ut0 ut1                 ut1' = addUnixDiffTime ut0 $ diffUnixTime ut1 ut0-            in ut0' == ut0 && ut1' == ut1+             in ut0' == ut0 && ut1' == ut1      describe "UnixTime Storable instance" $         prop "peek . poke = id" $ \ut ->             let pokePeek :: Ptr UnixTime -> IO UnixTime                 pokePeek ptr = poke ptr ut >> peek ptr-            in shouldReturn (alloca pokePeek) ut+             in shouldReturn (alloca pokePeek) ut +    describe "getUnixTime" $ do+        it "works well" $ do+            x <- getUnixTime+            x `shouldBe` x+        it "should work in Template Haskell" $+            $( do+                time <- TH.runIO getUnixTime+                let b = time == time+                [|b|]+             )+                `shouldBe` True+ formatMailModel :: UTCTime -> TimeZone -> ByteString formatMailModel ut zone = BS.pack $ formatTime defaultTimeLocale fmt zt   where-   zt = utcToZonedTime zone ut-   fmt = BS.unpack mailDateFormat+    zt = utcToZonedTime zone ut+    fmt = BS.unpack mailDateFormat  toUTCTime :: UnixTime -> UTCTime toUTCTime = posixSecondsToUTCTime . realToFrac . toEpochTime
unix-time.cabal view
@@ -1,6 +1,6 @@ cabal-version:      1.18 name:               unix-time-version:            0.4.9+version:            0.4.10 license:            BSD3 license-file:       LICENSE maintainer:         Kazu Yamamoto <kazu@iij.ad.jp>@@ -51,7 +51,20 @@     if impl(ghc >=7.8)         cc-options: -fPIC +    -- GHC 9.4.5, 9.6.1, and 9.6.2 on Windows do not link against mingwex, but+    -- unix-time implicitly depends on this library due to the use of the+    -- gettimeofday() function, which comes from mingwex on Windows. To avoid+    -- linker errors in the absence of a mingwex dependency (see+    -- https://gitlab.haskell.org/ghc/ghc/-/issues/23533 for an example of+    -- this), we depend on mingwex explicitly here.+    --+    -- Other versions of GHC on Windows already depend on mingwex, so we guard+    -- this behind appropriate conditionals.     if os(windows)+        if (impl(ghc >= 9.4.5) && !impl(ghc >= 9.4.6)) || (impl(ghc >= 9.6.1) && !impl(ghc >= 9.6.3))+            extra-libraries: mingwex++    if os(windows)         c-sources:             cbits/strftime.c             cbits/strptime.c@@ -71,6 +84,7 @@         old-locale,         old-time,         QuickCheck,+        template-haskell,         time,         unix-time,         hspec >=2.6