packages feed

unix-time (empty) → 0.0.0

raw patch · 9 files changed

+380/−0 lines, 9 filesdep +basedep +bytestringdep +old-timesetup-changed

Dependencies added: base, bytestring, old-time

Files

+ Data/UnixTime.hs view
@@ -0,0 +1,30 @@+module Data.UnixTime (+  -- * Data structure+    UnixTime(..)+  -- * Getting time+  , getUnixTime+  -- * Parsing and formatting time+  , parseUnixTime+  , parseUnixTimeGMT+  , formatUnixTime+  , formatUnixTimeGMT+  , Format+  , webDateFormat+  , mailDateFormat+  -- * Difference time+  , UnixDiffTime+  , diffUnixTime+  , addUnixDiffTime+  , secondsToUnixDiffTime+  , microSecondsToUnixDiffTime+  -- * Translating time+  , fromEpochTime+  , toEpochTime+  , fromClockTime+  , toClockTime+  ) where++import Data.UnixTime.Conv+import Data.UnixTime.Sys+import Data.UnixTime.Types+import Data.UnixTime.Diff
+ Data/UnixTime/Conv.hs view
@@ -0,0 +1,121 @@+{-# LANGUAGE OverloadedStrings, ForeignFunctionInterface #-}++module Data.UnixTime.Conv (+    formatUnixTime, formatUnixTimeGMT+  , parseUnixTime, parseUnixTimeGMT+  , webDateFormat, mailDateFormat+  , fromEpochTime, toEpochTime+  , fromClockTime, toClockTime+  ) where++import Data.ByteString+import Data.ByteString.Unsafe+import Data.UnixTime.Types+import Foreign.C.String+import Foreign.C.Types+import Foreign.Marshal.Alloc+import System.IO.Unsafe (unsafePerformIO)+import System.Posix.Types (EpochTime)+import System.Time (ClockTime(..))++foreign import ccall unsafe "c_parse_unix_time"+        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++foreign import ccall unsafe "c_format_unix_time"+        c_format_unix_time :: CString -> CTime -> CString -> CInt -> IO ()++foreign import ccall unsafe "c_format_unix_time_gmt"+        c_format_unix_time_gmt :: CString -> CTime -> CString -> CInt -> IO ()++----------------------------------------------------------------++{-| Parsing 'ByteString' to 'UnixTime' interpreting as localtime.+    Zone in 'Format' (%Z or %z) would be ignored.+    This is a wrapper for strptime_l().+-}+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.+    Zone in 'Format' (%Z or %z) would be ignored.+    This is a wrapper for strptime_l().+-}+parseUnixTimeGMT :: Format -> ByteString -> UnixTime+parseUnixTimeGMT fmt str = unsafePerformIO $+    useAsCString fmt $ \cfmt ->+        useAsCString str $ \cstr -> do+            sec <- c_parse_unix_time_gmt cfmt cstr+            return $ UnixTime sec 0++----------------------------------------------------------------++{-| Formatting 'UnixTime' to 'ByteString' in local time.+    This is a wrapper for strftime_l().+-}+formatUnixTime :: Format -> UnixTime -> ByteString+formatUnixTime fmt (UnixTime sec _) = unsafePerformIO $+    useAsCString fmt $ \cfmt -> do+        let siz = 256 -- FIXME+        ptr <- mallocBytes siz+        c_format_unix_time cfmt sec ptr (fromIntegral siz)+        unsafePackMallocCString ptr++{-| Formatting 'UnixTime' to 'ByteString' in GMT.+    This is a wrapper for strftime_l().+-}+formatUnixTimeGMT :: Format -> UnixTime -> ByteString+formatUnixTimeGMT fmt (UnixTime sec _) = unsafePerformIO $+    useAsCString fmt $ \cfmt -> do+        let siz = 256 -- FIXME+        ptr <- mallocBytes siz+        c_format_unix_time_gmt cfmt sec ptr (fromIntegral siz)+        unsafePackMallocCString ptr++----------------------------------------------------------------++{-| Format for web (RFC 2616).+    This should be used with 'formatUnixTimeGMT'.+-}+webDateFormat :: Format+webDateFormat = "%a, %d %b %Y %H:%M:%S GMT"++{-| Format for e-mail (RFC 5322).+    This should be used with 'formatUnixTime'.+-}+mailDateFormat :: Format+mailDateFormat = "%a, %d %b %Y %H:%M:%S %z"++----------------------------------------------------------------++{-| 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+    sec' = fromIntegral sec+    usec' = fromIntegral $ psec `div` 1000000++{-| From 'UnixTime' to 'ClockTime'.+-}+toClockTime :: UnixTime -> ClockTime+toClockTime (UnixTime sec usec) = TOD sec' psec'+  where+    sec' = truncate (toRational sec)+    psec' = fromIntegral $ usec * 1000000
+ Data/UnixTime/Diff.hs view
@@ -0,0 +1,82 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Data.UnixTime.Diff (+    diffUnixTime+  , addUnixDiffTime+  , secondsToUnixDiffTime+  , microSecondsToUnixDiffTime+  ) where++import Data.UnixTime.Types+import Data.Int+import Foreign.C.Types++----------------------------------------------------------------++calc :: CTime -> Int32 -> UnixDiffTime+calc sec usec = uncurry UnixDiffTime . ajust sec $ usec++calc' :: CTime -> Int32 -> UnixDiffTime+calc' sec usec = uncurry UnixDiffTime . slowAjust sec $ usec++calcU :: CTime -> Int32 -> UnixTime+calcU sec usec = uncurry UnixTime . ajust sec $ usec++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)+	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+	fromInteger i = UnixDiffTime (fromInteger s) (fromInteger u)+         where (s,u) = secondMicro i++----------------------------------------------------------------++-- | Calculating difference between two 'UnixTime'.+diffUnixTime :: UnixTime -> UnixTime -> UnixDiffTime+diffUnixTime (UnixTime s1 u1) (UnixTime s2 u2) = calc (s1-s2) (u1-u2)++-- | Adding difference to 'UnixTime'.+addUnixDiffTime :: UnixTime -> UnixDiffTime -> UnixTime+addUnixDiffTime (UnixTime s1 u1) (UnixDiffTime s2 u2) = calcU (s1+s2) (u1+u2)++-- | Creating difference from seconds.+secondsToUnixDiffTime :: Int -> UnixDiffTime+secondsToUnixDiffTime sec = UnixDiffTime (fromIntegral sec) 0++-- | Creating difference from micro seconds.+microSecondsToUnixDiffTime :: Int -> UnixDiffTime+microSecondsToUnixDiffTime usec = calc (fromIntegral s) (fromIntegral u)+  where+    (s,u) = secondMicro usec++----------------------------------------------------------------++ajust :: CTime -> Int32 -> (CTime, Int32)+ajust sec usec+  | sec >= 0  = ajp+  | otherwise = ajm+  where+    micro  = 1000000+    mmicro = - micro+    ajp+     | 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)++slowAjust :: CTime -> Int32 -> (CTime, Int32)+slowAjust sec usec = (sec + fromIntegral s, usec - u)+  where+    (s,u) = secondMicro u++secondMicro :: Integral a => a -> (a,a)+secondMicro usec = usec `quotRem` 1000000
+ Data/UnixTime/Sys.hsc view
@@ -0,0 +1,31 @@+{-# LANGUAGE ForeignFunctionInterface #-}++module Data.UnixTime.Sys (getUnixTime) where++import Data.UnixTime.Types+import Foreign.C.Error+import Foreign.C.Types+import Foreign.Marshal.Alloc+import Foreign.Ptr+import Foreign.Storable++-- from System.Time++#include <time.h>+#include <sys/time.h>++type CTimeVal = ()+type CTimeZone = ()++foreign import ccall unsafe "gettimeofday"+    gettimeofday :: Ptr CTimeVal -> Ptr CTimeZone -> IO CInt++{-| Getting 'UnixTime' from OS.+-}+getUnixTime :: IO UnixTime+getUnixTime =+  allocaBytes (#const sizeof(struct timeval)) $ \ p_timeval -> do+    throwErrnoIfMinus1_ "getClockTime" $ gettimeofday p_timeval nullPtr+    sec <- (#peek struct timeval,tv_sec) p_timeval+    usec <- (#peek struct timeval,tv_usec) p_timeval+    return $ UnixTime sec usec
+ Data/UnixTime/Types.hs view
@@ -0,0 +1,20 @@+module Data.UnixTime.Types where++import Data.ByteString+import Data.ByteString.Char8 ()+import Data.Int+import Foreign.C.Types++-- | Data structure for Unix time.+data UnixTime = UnixTime {+  -- | Seconds from 1st Jan 1970+    utSeconds :: !CTime+  -- | Micro seconds (i.e. 10^(-6))+  , utMicroSeconds :: !Int32+  } deriving (Eq,Ord,Show)++-- | Format of the strptime()/strftime() style.+type Format = ByteString++-- | Data structure for UnixTime diff.+data UnixDiffTime = UnixDiffTime !CTime !Int32 deriving (Eq,Ord,Show)
+ LICENSE view
@@ -0,0 +1,29 @@+Copyright (c) 2009, IIJ Innovation Institute Inc.+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++  * Redistributions of source code must retain the above copyright+    notice, this list of conditions and the following disclaimer.+  * Redistributions in binary form must reproduce the above copyright+    notice, this list of conditions and the following disclaimer in+    the documentation and/or other materials provided with the+    distribution.+  * Neither the name of the copyright holders nor the names of its+    contributors may be used to endorse or promote products derived+    from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ cbits/conv.c view
@@ -0,0 +1,37 @@+#include <time.h>+#include <locale.h>+#include <xlocale.h>++locale_t c_locale = NULL;++locale_t init_locale() {+    if (c_locale == NULL) c_locale = newlocale(LC_ALL_MASK, NULL, NULL);+}++time_t c_parse_unix_time(char *fmt, char *src) {+    struct tm dst;+    init_locale();+    strptime_l(src, fmt, &dst, c_locale);+    return mktime(&dst);+}++time_t c_parse_unix_time_gmt(char *fmt, char *src) {+    struct tm dst;+    init_locale();+    strptime_l(src, fmt, &dst, c_locale);+    return timegm(&dst);+}++void c_format_unix_time(char *fmt, time_t src, char* dst, int siz) {+    struct tm tim;+    init_locale();+    localtime_r(&src, &tim);+    strftime_l(dst, siz, fmt, &tim, c_locale);+}++void c_format_unix_time_gmt(char *fmt, time_t src, char* dst, int siz) {+    struct tm tim;+    init_locale();+    gmtime_r(&src, &tim);+    strftime_l(dst, siz, fmt, &tim, c_locale);+}
+ unix-time.cabal view
@@ -0,0 +1,28 @@+Name:                   unix-time+Version:                0.0.0+Author:                 Kazu Yamamoto <kazu@iij.ad.jp>+Maintainer:             Kazu Yamamoto <kazu@iij.ad.jp>+License:                BSD3+License-File:           LICENSE+Synopsis:               Unix time parser\/formatter and utilities+Description:            Fast parser\/formatter\/utilities for Unix time+Category:               Data+Cabal-Version:          >= 1.6+Build-Type:             Simple+Extra-Source-Files:     cbits/conv.c+library+  if impl(ghc >= 6.12)+    GHC-Options:        -Wall -fno-warn-unused-do-bind+  else+    GHC-Options:        -Wall+  Exposed-Modules:      Data.UnixTime+  Other-Modules:        Data.UnixTime.Conv+                        Data.UnixTime.Diff+                        Data.UnixTime.Types+                        Data.UnixTime.Sys+  Build-Depends:        base >= 4 && < 5,bytestring, old-time+  C-Sources:            cbits/conv.c++Source-Repository head+  Type:                 git+  Location:             git://github.com/kazu-yamamoto/http-date