packages feed

text-time (empty) → 0.1.0

raw patch · 10 files changed

+297/−0 lines, 10 filesdep +Cabaldep +QuickCheckdep +attoparsecsetup-changed

Dependencies added: Cabal, QuickCheck, attoparsec, base, hspec, text, time

Files

+ CHANGES.md view
@@ -0,0 +1,3 @@+# Version 0.1 (2016-12-???)++  *
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2014 Krzysztof Langner+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.++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.+
+ README.md view
@@ -0,0 +1,34 @@+[![Build Status](https://travis-ci.org/klangner/text-time.svg?branch=master)](https://travis-ci.org/klangner/text-time)+[![Hackage](https://img.shields.io/hackage/v/text-time.svg)](https://hackage.haskell.org/package/text-time)++# Welcome to Text Time library++This library contains fast parser for ISO date from Text into UTCTime data++++## Installation++```sh+stack setup+stack build+stack test+```+++# Join in!++We are happy to receive bug reports, fixes, documentation enhancements,+and other improvements.++Please report bugs via the+[github issue tracker](http://github.com/klangner/text-time/issues).++Master [git repository](http://github.com/klangner/text-time):++* `git clone https://github.com/klangner/text-time.git`+++# Redistributing++bytestring-time source code is distributed under the BSD3 License.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ benchmark/Benchmarks.hs view
@@ -0,0 +1,22 @@++import Criterion.Main+import Data.Text+import Data.Time+import Data.ByteString.Time+++parseString :: String -> UTCTime+parseString str = parseTimeOrError True defaultTimeLocale "%Y-%m-%dT%H:%M:%S" str+++parseByteString :: Text -> UTCTime+parseByteString str = parseTimeOrError True defaultTimeLocale "%Y-%m-%dT%H:%M:%S" (unpack str)+++main :: IO ()+main = defaultMain+    [ bgroup "Time parsers"+        [ bench "String"  $ nf parseString "2016-12-12T20:56:34"+        , bench "ByteString"  $ nf parseISODateTime (pack "2016-12-12T20:56:34")+        ]+    ]
+ src/Data/Text/Time.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE OverloadedStrings #-}++-- | Parser for ISO date from ByteString+module Data.Text.Time+    ( module Data.Text.Time.Parsers+    ) where+++import Data.Text.Time.Parsers++
+ src/Data/Text/Time/Parsers.hs view
@@ -0,0 +1,107 @@++module Data.Text.Time.Parsers+    ( parseISODateTime+    , parseUTCTimeOrError+    ) where++-- import Prelude+import           Control.Applicative+import           Control.Monad (when)+import qualified Data.Attoparsec.Text as A+import           Data.Bits ((.&.))+import           Data.Char (isDigit, ord)+import qualified Data.Text as T+import           Data.Time ( Day+                           , TimeOfDay+                           , UTCTime(..)+                           , fromGregorian+                           , fromGregorianValid+                           , makeTimeOfDayValid+                           , midnight+                           , timeOfDayToTime+                           )+++-- | Parse ISO date. If date can't be parsed then this function will return default value instead of error+-- Adapted from sqlite-simple package+parseISODateTime :: T.Text -> UTCTime+parseISODateTime str =+    case parseUTCTimeOrError str of+        Left _ -> defaultUTCTime+        Right dt -> dt+++-- | Default time if date can't be parsed+defaultUTCTime :: UTCTime+defaultUTCTime = UTCTime (fromGregorian 1 1 1) 0+++parseUTCTimeOrError :: T.Text -> Either String UTCTime+parseUTCTimeOrError = A.parseOnly getUTCTime++-- | Create UTCTime parser for ISO date time+-- This code is based on code from sqlite-simple package+--+getUTCTime :: A.Parser UTCTime+getUTCTime = do+    day  <- getDay+    time <- ((A.char ' ' <|> A.char 'T') *> getTimeOfDay) <|> pure midnight+    let time' = timeOfDayToTime time+    return (UTCTime day time')+++-- | Date parser+getDay :: A.Parser Day+getDay = do+    yearStr <- A.takeWhile isDigit+    when (T.length yearStr < 4) (fail "year must consist of at least 4 digits")++    let year = toNum yearStr+    month <- (A.char '-' *> digits "month") <|> pure 1+    day   <- (A.char '-' *> digits "day") <|> pure 1+    case fromGregorianValid year month day of+      Nothing -> fail "invalid date"+      Just x  -> return $! x+++getTimeOfDay :: A.Parser TimeOfDay+getTimeOfDay = do+    hour   <- digits "hours"+    _      <- A.char ':'+    minute <- digits "minutes"+    -- Allow omission of seconds.  If seconds is omitted, don't try to+    -- parse the sub-second part.+    (sec,subsec)+           <- ((,) <$> (A.char ':' *> digits "seconds") <*> fract) <|> pure (0,0)++    let picos' = sec + subsec++    case makeTimeOfDayValid hour minute picos' of+      Nothing -> fail "invalid time of day"+      Just x  -> return $! x++    where+      fract =+        (A.char '.' *> (decimal <$> A.takeWhile1 isDigit)) <|> pure 0+++toNum :: Num n => T.Text -> n+toNum = T.foldl' (\a c -> 10*a + digit c) 0+{-# INLINE toNum #-}++digit :: Num n => Char -> n+digit c = fromIntegral (ord c .&. 0x0f)+{-# INLINE digit #-}++digits :: Num n => String -> A.Parser n+digits msg = do+  x <- A.anyChar+  y <- A.anyChar+  if isDigit x && isDigit y+  then return $! (10 * digit x + digit y)+  else fail (msg ++ " is not 2 digits")+{-# INLINE digits #-}++decimal :: Fractional a => T.Text -> a+decimal str = toNum str / 10^(T.length str)+{-# INLINE decimal #-}
+ test-src/Data/Text/TimeSpec.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE OverloadedStrings #-}+module Data.Text.TimeSpec (spec) where++import Data.Text.Time+import Test.Hspec+import Data.Time+++spec :: Spec+spec = do++  describe "Parsers" $ do++    it "iso format: YYYY" $ do+        parseISODateTime "2014" `shouldBe` UTCTime (fromGregorian 2014 1 1) 0++    it "iso format: YYYY-MM" $ do+        parseISODateTime "2014-04" `shouldBe` UTCTime (fromGregorian 2014 4 1) 0++    it "iso format: YYYY-MM-DD" $ do+        parseISODateTime "2014-04-23" `shouldBe` UTCTime (fromGregorian 2014 4 23) 0++    it "iso format: YYYY-MM-DDTHH:MM:SS" $ do+        let t = timeOfDayToTime (TimeOfDay 12 34 56)+        parseISODateTime "2014-04-23T12:34:56" `shouldBe` UTCTime (fromGregorian 2014 4 23) t++    it "iso format: YYYY-MM-DD HH:MM:SS" $ do+        let t = timeOfDayToTime (TimeOfDay 12 34 56)+        parseISODateTime "2014-04-23 12:34:56" `shouldBe` UTCTime (fromGregorian 2014 4 23) t
+ test-src/Spec.hs view
@@ -0,0 +1,7 @@+import Test.Hspec+import qualified Data.Text.TimeSpec+++main :: IO ()+main = hspec $ do+  describe "Time" Data.Text.TimeSpec.spec
+ text-time.cabal view
@@ -0,0 +1,55 @@+name:           text-time+version:        0.1.0+synopsis:       Library for Time parsing from Text into UTCTime+License:        BSD3+License-file:   LICENSE+Extra-Source-Files:+                README.md,+                CHANGES.md,+                LICENSE,+                benchmark/*.hs+description:+    Fast parser for ISO date from Text to UTCTime+homepage:       https://github.com/klangner/text-time+author:         Krzysztof Langner+maintainer:     klangner@gmail.com+category:       Data+build-type:     Simple+cabal-version:  >=1.10++source-repository head+  type:     git+  location: https://github.com/klangner/text-time++library+  hs-source-dirs:   src+  default-language: Haskell2010+  ghc-options:      -Wall+  build-depends:+                    base >= 4.7 && < 5,+                    attoparsec < 0.14,+                    text < 2,+                    time < 2+  exposed-modules:+                    Data.Text.Time+  other-modules:+                    Data.Text.Time.Parsers++test-suite unit-tests+  type:             exitcode-stdio-1.0+  main-is:          Spec.hs+  default-language: Haskell2010+  build-depends:+                    base >= 4 && <5,+                    hspec >=2 && <3,+                    QuickCheck >=2.6 && <3,+                    Cabal >=1.16.0 && <2,+                    attoparsec < 0.14,+                    text < 2,+                    time < 2+  other-modules:+                    Data.Text.Time,+                    Data.Text.TimeSpec+  hs-source-dirs:+                    src,+                    test-src