packages feed

tz 0.1.1.1 → 0.1.2.0

raw patch · 9 files changed

+159/−249 lines, 9 filesdep −bindings-posixdep −unixdep ~data-default

Dependencies removed: bindings-posix, unix

Dependency ranges changed: data-default

Files

Data/Time/Zones/Read.hs view
@@ -48,6 +48,9 @@ -- | Looks for the time zone file in the system timezone directory, which is -- @\/usr\/share\/zoneinfo@, or if the @TZDIR@ environment variable is -- set, then there.+--+-- Note, this is unlikely to work on non-posix systems (e.g.,+-- Windows), use `loadTZFromDB` or `loadTZFromFile` instead. loadSystemTZ :: String -> IO TZ loadSystemTZ tzName = pathForSystemTZ tzName >>= loadTZFromFile 
Data/Time/Zones/TH.hs view
@@ -52,6 +52,9 @@ -- -- See also: `loadSystemTZ` for details on how system time zone files -- are located.+--+-- Note, this is unlikely to work on non-posix systems (e.g.,+-- Windows), use `includeTZFromDB` or `includeTZFromFile` instead. includeSystemTZ :: String -> Q Exp includeSystemTZ tzName = do   desc <- runIO $ pathForSystemTZ tzName >>= BL.readFile
benchmarks/benchTZ.hs view
@@ -1,6 +1,5 @@ module Main (main) where -import Bindings.Posix.Time import Criterion.Main import Data.Fixed import Data.Int@@ -8,12 +7,14 @@ import Data.Time.LocalTime.TimeZone.Olson import Data.Time.LocalTime.TimeZone.Series import Data.Time.Zones-import System.Posix.Env+import System.Environment +foreign import ccall safe "time.h tzset" c_tzset :: IO ()+ setupTZ :: String -> IO TZ setupTZ zoneName = do-  setEnv "TZ" zoneName True-  c'tzset+  setEnv "TZ" zoneName+  c_tzset   loadSystemTZ zoneName  mkLocal :: Integer -> Int -> Int -> Int -> Int -> Pico -> LocalTime
− benchmarks/bench_c_localtime.hs
@@ -1,99 +0,0 @@-{-# LANGUAGE ViewPatterns #-}--module Main (main) where--import Bindings.Posix.Time-import Bindings.Posix.Sys.Types-import Criterion.Main-import Foreign.Safe-import Foreign.C-import System.Posix.Env--setupTZ :: String -> IO ()-setupTZ zoneName = do-  setEnv "TZ" zoneName True-  c'tzset--data C_tm = C_tm {-  _tm_sec    :: {-# UNPACK #-} !CInt,-  _tm_min    :: {-# UNPACK #-} !CInt,-  _tm_hour   :: {-# UNPACK #-} !CInt,-  _tm_mday   :: {-# UNPACK #-} !CInt,-  _tm_mon    :: {-# UNPACK #-} !CInt,-  _tm_year   :: {-# UNPACK #-} !CInt,-  _tm_wday   :: {-# UNPACK #-} !CInt,-  _tm_yday   :: {-# UNPACK #-} !CInt,-  _tm_isdst  :: {-# UNPACK #-} !CInt-  -- _tm_gmtoff :: {-# UNPACK #-} !CInt-  -- _tm_zone :: {-# UNPACK #-} !Ptr CString (??)-  } deriving (Show)--instance Storable C_tm where-  -- Overestimate; it's 10 or 11 based on architecture.-  sizeOf _ = 16 * sizeOf (undefined :: CInt)-  alignment _ = alignment (undefined :: CLong)-  peek (castPtr -> p) = do-    s <- peekElemOff p 0-    mi <- peekElemOff p 1-    h <- peekElemOff p 2-    d <- peekElemOff p 3-    m <- peekElemOff p 4-    y <- peekElemOff p 5-    wd <- peekElemOff p 6-    yd <- peekElemOff p 7-    idst <- peekElemOff p 8-    return $ C_tm s mi h d m y wd yd idst-  poke (castPtr -> p) (C_tm s mi h d m y wd yd idst) = do-    pokeElemOff p 0 s-    pokeElemOff p 1 mi-    pokeElemOff p 2 h-    pokeElemOff p 3 d-    pokeElemOff p 4 m-    pokeElemOff p 5 y-    pokeElemOff p 6 wd-    pokeElemOff p 7 yd-    pokeElemOff p 8 idst--foreign import ccall unsafe "time.h localtime_r" c_localtime_r-  :: Ptr C'time_t -> Ptr C_tm -> IO (Ptr C_tm)--localtime :: Int -> IO C_tm-localtime t = with (fromIntegral t) $ \ptime ->-  alloca $ \ptm -> do-    res <- c_localtime_r ptime ptm-    if res /= nullPtr-      then peek res-      else fail "c_localtime_r failed"---- This just wraps the binding from Bindings.Posix.Time.------ Because it's foreign import ccall _safe_, it's more than two times--- slower!-localtime' :: Int -> IO C'tm-localtime' t = with (fromIntegral t) $ \ptime ->-  alloca $ \ptm -> do-    res <- c'localtime_r ptime ptm-    if res /= nullPtr-      then peek res-      else fail "c'localtime_r failed"--benchmarks :: [Benchmark]-benchmarks = [-  bgroup "c'localtime_r" [-     bench "past" $ whnfIO $ localtime' (-2100000000),-     bench "epoch" $ whnfIO $ localtime' 0,-     bench "now" $ whnfIO $ localtime' 1395572400,-     bench "future" $ whnfIO $ localtime' 2100000000-     ],-  bgroup "our_localtime_r" [-     bench "past" $ whnfIO $ localtime (-2100000000),-     bench "epoch" $ whnfIO $ localtime 0,-     bench "now" $ whnfIO $ localtime 1395572400,-     bench "future" $ whnfIO $ localtime 2100000000-     ]-  ]--main :: IO ()-main = do-  setupTZ "Europe/Budapest"-  defaultMain benchmarks
stack.yaml view
@@ -1,15 +1,24 @@ # For more information, see: https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md  # Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2)-resolver: nightly-2016-05-29+resolver: nightly-2016-08-06  # Local packages, usually specified by relative directory name packages: - '.'+# timezone-series with time-1.6 support+- location:+    git: https://github.com/ryantrinkle/timezone-series.git+    commit: f8dece8c016db6476e2bb0d4f972769a76f6ff40+  extra-dep: true+# timezone-olson with time-1.6 support+- location:+    git: https://github.com/klao/timezone-olson.git+    commit: 04085c5adfa3a87155d560f7cbbf189a28e513e3+  extra-dep: true  # Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3)-extra-deps:-- bindings-posix-1.2.6+extra-deps: []  # Override default flag values for local packages and extra-deps flags: {}
tests/testTH.hs view
@@ -7,11 +7,11 @@ import Test.HUnit hiding (Test, assert)  tzBudapest :: TZ-tzBudapest = $(includeSystemTZ "Europe/Budapest")+tzBudapest = $(includeTZFromDB "Europe/Budapest")  case_Budapest_is_Budapest :: IO () case_Budapest_is_Budapest = do-  readBp <- loadSystemTZ "Europe/Budapest"+  readBp <- loadTZFromDB "Europe/Budapest"   tzBudapest @?= readBp  main :: IO ()
tests/testTZ.hs view
@@ -3,128 +3,16 @@  module Main (main) where -import Bindings.Posix.Time-import Data.Bits-import Data.Int-import Data.IORef import Data.Time-import Data.Time.Clock.POSIX import Data.Time.Zones-import Data.Time.Zones.Types-import qualified Data.Vector.Generic as V import Test.Framework.Providers.HUnit-import Test.Framework.Providers.QuickCheck2 import Test.Framework.TH import Test.HUnit hiding (Test, assert)-import Test.QuickCheck-import Test.QuickCheck.Monadic-import System.Posix.Env-import System.IO.Unsafe -setupTZ :: String -> IO TZ-setupTZ zoneName = do-  setEnv "TZ" zoneName True-  c'tzset-  loadSystemTZ zoneName--onceIO :: IO a -> IO a-{-# NOINLINE onceIO #-}-onceIO op = opWrap-  where-    {-# NOINLINE var #-}-    var = unsafePerformIO $ newIORef Nothing-    opWrap = do-      v <- readIORef var-      case v of-        Just x -> return x-        Nothing -> do-          x <- op-          atomicWriteIORef var $ Just x-          return x---- On the Int32 range of POSIX times we should replicate the behavior--- perfectly.------ * After year 2038 we normally run into a range where the--- envvar-like "rule" part of the TZif should be interpreted, which we--- don't do yet.------ * And below around -2^55 the localtime_r C function starts failing--- with "value too large".-checkTimeZone :: String -> Int32 -> Property-checkTimeZone zoneName = prop-  where-    setup = onceIO $ setupTZ zoneName-    prop ut = monadicIO $ do-      tz <- run $ setup-      run $ print ut-      timeZone <- run $ getTimeZone $ posixSecondsToUTCTime $ fromIntegral ut-      run $ timeZoneForPOSIX tz (fromIntegral ut) @?= timeZone---- See comment for the checkTimeZone.-checkTimeZone64 :: String -> Property-checkTimeZone64 zoneName = prop-  where-    setup = onceIO $ setupTZ zoneName-    two31 = 2147483647-    prop = monadicIO $ do-      tz <- run $ setup-      ut <- pick $ oneof [arbitrary, choose (-two31, two31)]-      pre $ ut < two31 && ut > -(1 `shiftL` 55)-      -- This is important. On 32 bit machines we want to limit-      -- testing to the Int range.-      pre $ ut > fromIntegral (minBound :: Int)-      timeZone <- run $ getTimeZone $ posixSecondsToUTCTime $ fromIntegral ut-      run $ timeZoneForPOSIX tz ut @?= timeZone---- On the Int32 range of POSIX times we should mostly replicate the--- behavior.------ * After year 2038 we normally run into a range where the--- envvar-like "rule" part of the TZif should be interpreted, which we--- don't do yet.------ * And the very first time diff in most of the TZif files is usually--- the "Local Mean Time", which is generally a fractional number of--- minutes, so we would get difference with getTimeZone too. Most of--- the locations switch to some more standard time zone before or--- around 1900, which happens to be less than -2^31 POSIX time.  But--- in some locations this transition falls within the Int32 range--- (eg. China), so we can supply another lower bound.-checkLocalTime :: String -> Maybe Int32 -> Int32 -> Property-checkLocalTime zoneName mLower = prop-  where-    setup = onceIO $ setupTZ zoneName-    prop ut = monadicIO $ do-      case mLower of-        Nothing -> return ()-        Just lower -> pre $ ut > lower-      tz <- run $ setup-      let utcTime = posixSecondsToUTCTime $ fromIntegral ut-      timeZone <- run $ getTimeZone utcTime-      run $ utcToLocalTimeTZ tz utcTime @?= utcToLocalTime timeZone utcTime-- case_utcTZ_is_utc = timeZoneForPOSIX utcTZ 0 @?= utc  case_utcTZ_zero_diff = diffForPOSIX utcTZ 0 @?= 0 -prop_Budapest_correct_TimeZone = checkTimeZone64 "Europe/Budapest"-prop_New_York_correct_TimeZone = checkTimeZone64 "America/New_York"-prop_Los_Angeles_correct_TimeZone = checkTimeZone64 "America/Los_Angeles"-prop_Shanghai_correct_TimeZone = checkTimeZone64 "Asia/Shanghai"-prop_Jerusalem_correct_TimeZone = checkTimeZone64 "Asia/Jerusalem"-prop_Antarctica_Palmer_correct_TimeZone = checkTimeZone64 "Antarctica/Palmer"-prop_Melbourne_correct_TimeZone = checkTimeZone64 "Australia/Melbourne"--prop_Budapest_correct_LocalTime = checkLocalTime "Europe/Budapest" Nothing-prop_New_York_correct_LocalTime = checkLocalTime "America/New_York" Nothing-prop_Los_Angeles_correct_LocalTime = checkLocalTime "America/Los_Angeles" Nothing-prop_Shanghai_correct_LocalTime = checkLocalTime "Asia/Shanghai" $ Just (-1325491558)-prop_Jerusalem_correct_LocalTime = checkLocalTime "Asia/Jerusalem" $ Just (-1641003641)-prop_Antarctica_Palmer_correct_LocalTime = checkLocalTime "Antarctica/Palmer" Nothing-prop_Melbourne_correct_LocalTime = checkLocalTime "Australia/Melbourne" Nothing- case_DB_utc_is_utc = do   tz <- loadTZFromDB "UTC"   tz @?= utcTZ@@ -183,9 +71,4 @@   diffForAbbr tz "XYZ" @?= Nothing  main :: IO ()-main = do-  -- When we are running 'cabal test' the package is not yet-  -- installed, so we want to use the data directory from within the-  -- sources.-  setEnv "tz_datadir" "./tzdata" True-  $defaultMainGenerator+main = $defaultMainGenerator
+ tests/testTZSys.hs view
@@ -0,0 +1,112 @@+{-# LANGUAGE TemplateHaskell #-}+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}++module Main (main) where++import Data.Bits+import Data.IORef+import Data.Int+import Data.Time+import Data.Time.Clock.POSIX+import Data.Time.Zones+import System.Environment+import System.IO.Unsafe+import Test.Framework.Providers.QuickCheck2+import Test.Framework.TH+import Test.HUnit hiding (Test, assert)+import Test.QuickCheck+import Test.QuickCheck.Monadic++foreign import ccall safe "time.h tzset" c_tzset :: IO ()++setupTZ :: String -> IO TZ+setupTZ zoneName = do+  setEnv "TZ" zoneName+  c_tzset+  loadSystemTZ zoneName++onceIO :: IO a -> IO a+{-# NOINLINE onceIO #-}+onceIO op = opWrap+  where+    {-# NOINLINE var #-}+    var = unsafePerformIO $ newIORef $ Left op+    opWrap = do+      v <- readIORef var+      case v of+        Right x -> return x+        Left _ -> do+          x <- op+          atomicWriteIORef var $ Right x+          return x++-- On the Int32 range of POSIX times we should replicate the behavior+-- perfectly.+--+-- * After year 2038 we normally run into a range where the+-- envvar-like "rule" part of the TZif should be interpreted, which we+-- don't do yet.+--+-- * And below around -2^55 the localtime_r C function starts failing+-- with "value too large".+checkTimeZone64 :: String -> Property+checkTimeZone64 zoneName = prop+  where+    setup = onceIO $ setupTZ zoneName+    two31 = 2147483647+    prop = monadicIO $ do+      tz <- run $ setup+      ut <- pick $ oneof [arbitrary, choose (-two31, two31)]+      pre $ ut < two31 && ut > -(1 `shiftL` 55)+      -- This is important. On 32 bit machines we want to limit+      -- testing to the Int range.+      pre $ ut > fromIntegral (minBound :: Int)+      timeZone <- run $ getTimeZone $ posixSecondsToUTCTime $ fromIntegral ut+      run $ timeZoneForPOSIX tz ut @?= timeZone++-- On the Int32 range of POSIX times we should mostly replicate the+-- behavior.+--+-- * After year 2038 we normally run into a range where the+-- envvar-like "rule" part of the TZif should be interpreted, which we+-- don't do yet.+--+-- * And the very first time diff in most of the TZif files is usually+-- the "Local Mean Time", which is generally a fractional number of+-- minutes, so we would get difference with getTimeZone too. Most of+-- the locations switch to some more standard time zone before or+-- around 1900, which happens to be less than -2^31 POSIX time.  But+-- in some locations this transition falls within the Int32 range+-- (eg. China), so we can supply another lower bound.+checkLocalTime :: String -> Maybe Int32 -> Int32 -> Property+checkLocalTime zoneName mLower = prop+  where+    setup = onceIO $ setupTZ zoneName+    prop ut = monadicIO $ do+      case mLower of+        Nothing -> return ()+        Just lower -> pre $ ut > lower+      tz <- run $ setup+      let utcTime = posixSecondsToUTCTime $ fromIntegral ut+      timeZone <- run $ getTimeZone utcTime+      run $ utcToLocalTimeTZ tz utcTime @?= utcToLocalTime timeZone utcTime+++prop_Budapest_correct_TimeZone = checkTimeZone64 "Europe/Budapest"+prop_New_York_correct_TimeZone = checkTimeZone64 "America/New_York"+prop_Los_Angeles_correct_TimeZone = checkTimeZone64 "America/Los_Angeles"+prop_Shanghai_correct_TimeZone = checkTimeZone64 "Asia/Shanghai"+prop_Jerusalem_correct_TimeZone = checkTimeZone64 "Asia/Jerusalem"+prop_Antarctica_Palmer_correct_TimeZone = checkTimeZone64 "Antarctica/Palmer"+prop_Melbourne_correct_TimeZone = checkTimeZone64 "Australia/Melbourne"++prop_Budapest_correct_LocalTime = checkLocalTime "Europe/Budapest" Nothing+prop_New_York_correct_LocalTime = checkLocalTime "America/New_York" Nothing+prop_Los_Angeles_correct_LocalTime = checkLocalTime "America/Los_Angeles" Nothing+prop_Shanghai_correct_LocalTime = checkLocalTime "Asia/Shanghai" $ Just (-1325491558)+prop_Jerusalem_correct_LocalTime = checkLocalTime "Asia/Jerusalem" $ Just (-1641003641)+prop_Antarctica_Palmer_correct_LocalTime = checkLocalTime "Antarctica/Palmer" Nothing+prop_Melbourne_correct_LocalTime = checkLocalTime "Australia/Melbourne" Nothing++main :: IO ()+main = $defaultMainGenerator
tz.cabal view
@@ -1,5 +1,5 @@ Name: tz-Version: 0.1.1.1+Version: 0.1.2.0 License: Apache-2.0 License-File: LICENSE Author: Mihaly Barasz, Gergely Risko@@ -53,7 +53,7 @@     binary             >= 0.5      && < 0.9,     bytestring         >= 0.9      && < 0.11,     containers         >= 0.5      && < 0.6,-    data-default       >= 0.5      && < 0.7,+    data-default       >= 0.5      && < 0.8,     deepseq            >= 1.1      && < 2,     time               >= 1.2      && < 1.7,     tzdata             >= 0.1      && < 0.2,@@ -76,16 +76,29 @@   Build-Depends:     tz,     base                       >= 4       && < 5,-    bindings-posix             >= 1.2     && < 2,     HUnit                      >= 1.2     && < 1.4,-    QuickCheck                 >= 2.4     && < 3,     test-framework             >= 0.4     && < 1,     test-framework-hunit       >= 0.2     && < 0.4,+    test-framework-th          >= 0.2     && < 0.4,+    time                       >= 1.2     && < 1.7++Test-Suite testsSys+  Default-Language: Haskell2010+  Type: exitcode-stdio-1.0+  HS-Source-Dirs: tests+  Main-Is: testTZSys.hs+  GHC-Options: -Wall+  If os(mingw32) || os(mingw64)+    Buildable: False+  Build-Depends:+    tz,+    base                       >= 4       && < 5,+    HUnit                      >= 1.2     && < 1.4,+    QuickCheck                 >= 2.4     && < 3,+    test-framework             >= 0.4     && < 1,     test-framework-quickcheck2 >= 0.2     && < 0.4,     test-framework-th          >= 0.2     && < 0.4,-    time                       >= 1.2     && < 1.7,-    unix                       >= 2.6     && < 3,-    vector                     >= 0.9     && < 0.12+    time                       >= 1.2     && < 1.7  Test-Suite th-test   Default-Language: Haskell2010@@ -127,25 +140,10 @@   Build-Depends:     tz,     base                       >= 4       && < 5,-    bindings-posix             >= 1.2     && < 2,     criterion                  >= 0.8     && < 1.2,     time                       >= 1.2     && < 1.7,     timezone-olson,-    timezone-series,-    unix                       >= 2.6     && < 3--Benchmark bench_c-  Default-Language: Haskell2010-  Type: exitcode-stdio-1.0-  HS-Source-Dirs: benchmarks-  Main-Is: bench_c_localtime.hs-  GHC-Options: -Wall -O2-  Build-Depends:-    tz,-    base                       >= 4       && < 5,-    bindings-posix             >= 1.2     && < 2,-    criterion                  >= 0.8     && < 1.2,-    unix                       >= 2.6     && < 3+    timezone-series  Benchmark bench_greg   Default-Language: Haskell2010