summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikitaVolkov <>2017-02-01 15:24:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2017-02-01 15:24:00 (GMT)
commit877b511d84f7c2307affe3bd927b5c438d2f1c36 (patch)
treebb3ba1e90eaaba4ebd8047735ac5d559ccb784b1
parent050e7080887d955d805dec53eff9e0adb3d5d50c (diff)
version 0.1.10.1.1
-rw-r--r--attoparsec-time.cabal2
-rw-r--r--library/Attoparsec/Time.hs55
2 files changed, 51 insertions, 6 deletions
diff --git a/attoparsec-time.cabal b/attoparsec-time.cabal
index b40ca89..c704c3f 100644
--- a/attoparsec-time.cabal
+++ b/attoparsec-time.cabal
@@ -1,7 +1,7 @@
name:
attoparsec-time
version:
- 0.1
+ 0.1.1
synopsis:
Attoparsec parsers of time
description:
diff --git a/library/Attoparsec/Time.hs b/library/Attoparsec/Time.hs
index f199cac..71e1b80 100644
--- a/library/Attoparsec/Time.hs
+++ b/library/Attoparsec/Time.hs
@@ -31,8 +31,9 @@ decimalChar =
decimalOfLength :: Num a => Int -> Parser a
decimalOfLength length =
- fmap (foldl' (\a b -> a * 10 + b) 0) $
- replicateM length (fmap fromIntegral decimalChar)
+ foldl' (\a b -> a * 10 + b) 0 <$>
+ replicateM length (fmap fromIntegral decimalChar) <|>
+ fail "Invalid decimal length"
shortMonth :: Parser Int
shortMonth =
@@ -69,6 +70,21 @@ picoWithBasisOfLength basisLength =
head : tail -> padListFromRight padding (head : accumulator) (pred length) tail
_ -> reverse accumulator ++ replicate length padding
+{-# INLINE hour #-}
+hour :: Parser Int
+hour =
+ validated B.hour (decimalOfLength 2) <?> "hour"
+
+{-# INLINE minute #-}
+minute :: Parser Int
+minute =
+ validated B.minute (decimalOfLength 2) <?> "minute"
+
+{-# INLINE second #-}
+second :: Parser Pico
+second =
+ validated B.second (picoWithBasisOfLength 2) <?> "second"
+
{-|
>>> parseOnly timeOfDayInISO8601 "05:03:58"
Right 05:03:58
@@ -78,6 +94,22 @@ Right 05:03:58.02
>>> parseOnly timeOfDayInISO8601 "05:03:58.020"
Right 05:03:58.02
+
+Checks the elements to be within a proper range:
+
+>>> parseOnly timeOfDayInISO8601 "24:00:00"
+Left "timeOfDayInISO8601 > hour: Failed reading: Validator \"hour\" failed on the following input: 24"
+
+>>> parseOnly timeOfDayInISO8601 "00:00:60"
+Left "timeOfDayInISO8601 > second: Failed reading: Validator \"second\" failed on the following input: 60.000000000000"
+
+Checks the elements to be of proper length:
+
+>>> parseOnly timeOfDayInISO8601 "1:00:00"
+Left "timeOfDayInISO8601 > hour: Failed reading: Invalid decimal length"
+
+>>> parseOnly timeOfDayInISO8601 "01:1:00"
+Left "timeOfDayInISO8601 > minute: Failed reading: Invalid decimal length"
-}
{-# INLINE timeOfDayInISO8601 #-}
timeOfDayInISO8601 :: Parser TimeOfDay
@@ -86,13 +118,26 @@ timeOfDayInISO8601 =
where
unnamedParser =
A.timeOfDay <$>
- (validated B.hour (decimalOfLength 2) <* char ':') <*>
- (validated B.minute (decimalOfLength 2) <* char ':') <*>
- (validated B.second (picoWithBasisOfLength 2))
+ (hour <* char ':') <*>
+ (minute <* char ':') <*>
+ (second)
{-|
>>> parseOnly dayInISO8601 "2017-02-01"
Right 2017-02-01
+
+Checks the elements to be in proper range:
+
+>>> parseOnly dayInISO8601 "2017-13-01"
+Left "dayInISO8601: Failed reading: Invalid combination of year month and day: (2017,13,1)"
+
+That is accounting for leap year:
+
+>>> parseOnly dayInISO8601 "2017-02-29"
+Left "dayInISO8601: Failed reading: Invalid combination of year month and day: (2017,2,29)"
+
+>>> parseOnly dayInISO8601 "2016-02-29"
+Right 2016-02-29
-}
{-# INLINE dayInISO8601 #-}
dayInISO8601 :: Parser Day