chronos 1.1.4 → 1.1.5
raw patch · 3 files changed
+58/−19 lines, 3 filesdep ~basedep ~primitivedep ~semigroupsPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base, primitive, semigroups, text, vector
API changes (from Hackage documentation)
+ Chronos: decodeShortTextIso8601Zulu :: ShortText -> Maybe Datetime
+ Chronos: decodeUtf8BytesIso8601ZonelessSpaced :: Bytes -> Maybe Datetime
Files
- chronos.cabal +7/−7
- src/Chronos.hs +30/−6
- test/Spec.hs +21/−6
chronos.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: chronos-version: 1.1.4+version: 1.1.5 synopsis: A high-performance time library description: Chronos is a performance-oriented time library for Haskell, with a@@ -46,15 +46,15 @@ -- it is OPTIONS_HADDOCK-hidden Chronos.Internal.CTimespec build-depends:- , aeson >= 1.1 && < 2.1+ , aeson >= 1.1 && < 2.2 , attoparsec >= 0.13 && < 0.15- , base >= 4.14 && < 4.16+ , base >= 4.14 && < 4.18 , bytestring >= 0.10 && < 0.12 , deepseq >= 1.4.4.0- , hashable >= 1.2 && < 1.4+ , hashable >= 1.2 && < 1.5 , primitive >= 0.6.4 && < 0.8- , semigroups >= 0.16 && < 0.20- , text >= 1.2 && < 1.3+ , semigroups >= 0.16 && < 0.21+ , text >= 1.2 && < 1.3 || >= 2.0 && < 2.1 , torsor >= 0.1 && < 0.2 , vector >= 0.11 && < 0.13 , bytebuild >= 0.3.8 && < 0.4@@ -77,7 +77,7 @@ build-depends: , HUnit , QuickCheck- , aeson >= 1.1 && < 1.6+ , aeson >= 1.1 && < 2.2 , attoparsec , base , bytestring
src/Chronos.hs view
@@ -3,6 +3,7 @@ {-# language DeriveGeneric #-} {-# language GeneralizedNewtypeDeriving #-} {-# language LambdaCase #-}+{-# language MagicHash #-} {-# language MultiParamTypeClasses #-} {-# language NumericUnderscores #-} {-# language OverloadedStrings #-}@@ -201,7 +202,9 @@ -- *** UTF-8 Bytes , boundedBuilderUtf8BytesIso8601Zoneless , decodeUtf8BytesIso8601Zoneless+ , decodeUtf8BytesIso8601ZonelessSpaced -- *** Short Text+ , decodeShortTextIso8601Zulu , decodeShortTextIso8601Zoneless , encodeShortTextIso8601Zulu , encodeShortTextIso8601Zoneless@@ -3364,7 +3367,20 @@ , timePartsOffset = getOffset o } --- | Decode an ISO-8601-encode datetime. The encoded time must not by suffixed+-- | Decode an ISO-8601-encode datetime. The encoded time must be suffixed+-- by either @Z@ or @+00:00@ or @+00@.+decodeShortTextIso8601Zulu :: ShortText -> Maybe Chronos.Datetime+decodeShortTextIso8601Zulu !t = BVP.parseBytesMaybe+ ( do d <- parserUtf8BytesIso8601Zoneless 'T'+ remaining <- BVP.remaining+ case Bytes.length remaining of+ 1 | Bytes.unsafeIndex remaining 0 == 0x5A -> pure d+ 3 | Bytes.equalsCString (Ptr "+00"#) remaining -> pure d+ 6 | Bytes.equalsCString (Ptr "+00:00"#) remaining -> pure d+ _ -> BVP.fail ()+ ) (Bytes.fromShortByteString (TS.toShortByteString t))++-- | Decode an ISO-8601-encode datetime. The encoded time must not be suffixed -- by an offset. Any offset (e.g. @-05:00@, @+00:00@, @Z@) will cause a decode -- failure. decodeShortTextIso8601Zoneless :: ShortText -> Maybe Chronos.Datetime@@ -3377,17 +3393,25 @@ decodeShortTextIso8601 !t = decodeUtf8BytesIso8601 (Bytes.fromShortByteString (TS.toShortByteString t)) +-- | Decode an ISO-8601-encode datetime. decodeUtf8BytesIso8601Zoneless :: Bytes -> Maybe Chronos.Datetime decodeUtf8BytesIso8601Zoneless !b =- BVP.parseBytesMaybe (parserUtf8BytesIso8601Zoneless <* BVP.endOfInput ()) b+ BVP.parseBytesMaybe (parserUtf8BytesIso8601Zoneless 'T' <* BVP.endOfInput ()) b +-- | Decode a datetime that is nearly ISO-8601-encoded but uses a space+-- instead of a T to separate the date and the time. For example:+-- @2022-10-29 14:00:05@.+decodeUtf8BytesIso8601ZonelessSpaced :: Bytes -> Maybe Chronos.Datetime+decodeUtf8BytesIso8601ZonelessSpaced !b =+ BVP.parseBytesMaybe (parserUtf8BytesIso8601Zoneless ' ' <* BVP.endOfInput ()) b+ decodeUtf8BytesIso8601 :: Bytes -> Maybe Chronos.OffsetDatetime decodeUtf8BytesIso8601 !b = BVP.parseBytesMaybe (parserUtf8BytesIso8601 <* BVP.endOfInput ()) b -parserUtf8BytesIso8601Zoneless :: BVP.Parser () s Chronos.Datetime+parserUtf8BytesIso8601Zoneless :: Char -> BVP.Parser () s Chronos.Datetime {-# noinline parserUtf8BytesIso8601Zoneless #-}-parserUtf8BytesIso8601Zoneless = do+parserUtf8BytesIso8601Zoneless !sep = do year <- Latin.decWord () Latin.char () '-' month' <- Latin.decWord ()@@ -3400,7 +3424,7 @@ (Chronos.Year (fromIntegral year)) (Chronos.Month (fromIntegral month)) (Chronos.DayOfMonth (fromIntegral dayWord))- Latin.char () 'T'+ Latin.char () sep hourWord <- Latin.decWord8 () when (hourWord > 23) (BVP.fail ()) Latin.char () ':'@@ -3436,7 +3460,7 @@ parserUtf8BytesIso8601 :: BVP.Parser () s Chronos.OffsetDatetime {-# noinline parserUtf8BytesIso8601 #-} parserUtf8BytesIso8601 = do- dt <- parserUtf8BytesIso8601Zoneless+ dt <- parserUtf8BytesIso8601Zoneless 'T' off <- Latin.any () >>= \case 'Z' -> pure 0 '+' -> parserBytesOffset
test/Spec.hs view
@@ -389,6 +389,18 @@ (LText.toStrict . Builder.toLazyText . C.builder_YmdHMS (SubsecondPrecisionFixed 9) (DatetimeFormat Nothing Nothing Nothing)) (either (const Nothing) Just . Atto.parseOnly (C.parser_YmdHMS (DatetimeFormat Nothing Nothing Nothing))) ]+ , testProperty "ISO-8601 Roundtrip" $ propEncodeDecodeIso+ C.encodeShortTextIso8601Zulu+ (\input -> case C.decodeShortTextIso8601 input of+ Just (OffsetDatetime dt (Offset 0)) -> Just dt+ _ -> Nothing+ )+ , testProperty "ISO-8601 Zoneless Roundtrip" $ propEncodeDecodeIso+ C.encodeShortTextIso8601Zoneless+ (\input -> case C.decodeShortTextIso8601Zoneless input of+ Just dt -> Just dt+ _ -> Nothing+ ) ] , testGroup "Offset Datetime" [ testGroup "Builder Spec Tests" $@@ -408,12 +420,6 @@ either (const Nothing) Just $ flip Atto.parseOnly input $ C.parser_YmdHMSz offsetFormat datetimeFormat )- , testProperty "ISO-8601 Roundtrip" $ propEncodeDecodeIso- C.encodeShortTextIso8601Zulu- (\input -> case C.decodeShortTextIso8601 input of- Just (OffsetDatetime dt (Offset 0)) -> Just dt- _ -> Nothing- ) ] , testGroup "Posix Time" [ PH.testCase "Get now" $ do@@ -491,6 +497,15 @@ (C.timeToDayOfWeek (Time (-17308800000000000)) @?= DayOfWeek 6) , PH.testCase "Tuesday, June 6, 1944 4:00:00 PM" (C.timeToDayOfWeek (Time (-806918400000000000)) @?= DayOfWeek 2)+ ]+ , testGroup "timeToOffsetDatetime"+ [ PH.testCase "EpochNeg4h"+ (C.timeToOffsetDatetime (Offset (-240)) (Time 0) @?= OffsetDatetime+ ( Datetime+ ( Date (Year 1969) C.december (DayOfMonth 31) )+ ( TimeOfDay 20 0 0 )+ ) (Offset (-240))+ ) ] , testGroup "json" [ PH.testCase "Datetime" $