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 +30/−0
- Data/UnixTime/Conv.hs +121/−0
- Data/UnixTime/Diff.hs +82/−0
- Data/UnixTime/Sys.hsc +31/−0
- Data/UnixTime/Types.hs +20/−0
- LICENSE +29/−0
- Setup.hs +2/−0
- cbits/conv.c +37/−0
- unix-time.cabal +28/−0
+ 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