chronos 1.1.6.2 → 1.1.7.0
raw patch · 3 files changed
+78/−55 lines, 3 filesdep ~aesondep ~textdep ~text-shortPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: aeson, text, text-short
API changes (from Hackage documentation)
+ Chronos: decodeIso8601Zulu :: Text -> Maybe Datetime
- Chronos: _dateToDay :: forall f. Functor f => (Day -> f Day) -> Date -> f Date
+ Chronos: _dateToDay :: Functor f => (Day -> f Day) -> Date -> f Date
- Chronos: _datetimeToTime :: forall f. Functor f => (Time -> f Time) -> Datetime -> f Datetime
+ Chronos: _datetimeToTime :: Functor f => (Time -> f Time) -> Datetime -> f Datetime
- Chronos: _dayToDate :: forall f. Functor f => (Date -> f Date) -> Day -> f Day
+ Chronos: _dayToDate :: Functor f => (Date -> f Date) -> Day -> f Day
- Chronos: _timeToDatetime :: forall f. Functor f => (Datetime -> f Datetime) -> Time -> f Time
+ Chronos: _timeToDatetime :: Functor f => (Datetime -> f Datetime) -> Time -> f Time
Files
- CHANGELOG.md +10/−1
- chronos.cabal +7/−12
- src/Chronos.hs +61/−42
CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for chronos +## 1.1.7.0 -- 2025.07.15++* Add `decodeIso8601Zulu` for going straight from `Text` to a `Datetime`.+* Require a newer version of the `text` library so that UTF-8 encoding is used.+ ## 1.1.6.2 -- 2024-12-11 * Support GHC 9.10@@ -10,7 +15,11 @@ ## 1.1.6.0 -- 2024-01-29 -* Add `sinceEpoch` and `asSeconds` functions+* Add `sinceEpoch` and `asSeconds` functions.+* Make `boundedBuilderUtf8BytesIso8601Zoneless` suppress trailing zeros+ when a timestamp has no submillisecond part. For example, this function+ prints 2021-01-05T23:00:52.123 where it previously+ printed 2021-01-05T23:00:52.123000000. ## 1.1.5.1 -- 2023-08-24
chronos.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: chronos-version: 1.1.6.2+version: 1.1.7.0 synopsis: A high-performance time library description: Chronos is a performance-oriented time library for Haskell, with a@@ -24,7 +24,6 @@ format strings. The approach taken by Chronos is faster and catches more mistakes at compile time, at the cost of being less expressive.- homepage: https://github.com/byteverse/chronos bug-reports: https://github.com/byteverse/chronos/issues license: BSD-3-Clause@@ -38,7 +37,7 @@ CHANGELOG.md README.md -tested-with: GHC ==9.4.8 || ==9.6.3 || ==9.8.1+tested-with: GHC ==9.6.3 || ==9.8.1 common build-settings default-language: Haskell2010@@ -52,11 +51,8 @@ Chronos.Internal.CTimespec Chronos.Locale.English Chronos.Types-- -- only exposed for doctests- -- it is OPTIONS_HADDOCK-hidden build-depends:- , aeson >=1.1 && <2.3+ , aeson >=2.2 && <2.3 , attoparsec >=0.13 && <0.15 , base >=4.14 && <5 , bytebuild >=0.3.14 && <0.4@@ -67,11 +63,10 @@ , hashable >=1.2 && <1.5 , natural-arithmetic >=0.1.2 && <0.3 , primitive >=0.6.4 && <0.10- , text >=1.2 && <1.3 || >=2.0 && <2.2- , text-short >=0.1.3 && <0.2+ , text >=2.1.2 && <2.2+ , text-short >=0.1.5 && <0.2 , torsor >=0.1 && <0.2 , vector >=0.11 && <0.14- if os(windows) build-depends: Win32 >=2.2 && <2.14 @@ -85,12 +80,12 @@ main-is: Spec.hs build-depends: , aeson >=1.1 && <2.3+ , HUnit+ , QuickCheck , attoparsec , base , bytestring , chronos- , HUnit- , QuickCheck , test-framework , test-framework-hunit , test-framework-quickcheck2
src/Chronos.hs view
@@ -207,6 +207,7 @@ , decode_DmyHMS_opt_S , decode_DmyHMS_opt_S_lenient , decode_lenient+ , decodeIso8601Zulu -- *** UTF-8 ByteString , encodeUtf8_YmdHMS@@ -351,57 +352,60 @@ , _timeOfDayNanoseconds ) where -import qualified Arithmetic.Lte as Lte-import qualified Arithmetic.Nat as Nat import Control.Applicative import Control.DeepSeq (NFData (..), deepseq) import Control.Exception (evaluate) import Control.Monad import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)+import Data.Attoparsec.Text (Parser)+import Data.Bool (bool)+import Data.ByteString (ByteString)+import Data.Bytes (Bytes)+import Data.Char (isDigit)+import Data.Foldable+import Data.Hashable (Hashable)+import Data.Int (Int64)+import Data.Primitive+import Data.Text (Text)+import Data.Text.Short (ShortText)+import Data.Vector (Vector)+import Data.Word (Word64, Word8)+import Foreign.Storable+import GHC.Clock (getMonotonicTimeNSec)+import GHC.Generics (Generic)+import Torsor++import qualified Arithmetic.Lte as Lte+import qualified Arithmetic.Nat as Nat import qualified Data.Aeson as AE import qualified Data.Aeson.Encoding as AEE+import qualified Data.Aeson.Key as AK import qualified Data.Aeson.Types as AET import qualified Data.Attoparsec.ByteString.Char8 as AB-import Data.Attoparsec.Text (Parser) import qualified Data.Attoparsec.Text as AT import qualified Data.Attoparsec.Zepto as Z-import Data.Bool (bool)-import Data.ByteString (ByteString) import qualified Data.ByteString.Builder as BB import qualified Data.ByteString.Char8 as BC import qualified Data.ByteString.Lazy as LB import qualified Data.ByteString.Short.Internal as SBS-import Data.Bytes (Bytes) import qualified Data.Bytes as Bytes import qualified Data.Bytes.Builder.Bounded as Bounded import qualified Data.Bytes.Parser as BVP import qualified Data.Bytes.Parser.Latin as Latin-import Data.Char (isDigit)-import Data.Foldable-import Data.Hashable (Hashable)-import Data.Int (Int64)-import Data.Primitive+import qualified Data.Bytes.Text.Utf8 as Utf8 import qualified Data.Semigroup as SG-import Data.Text (Text) import qualified Data.Text as Text import qualified Data.Text.Lazy as LT import qualified Data.Text.Lazy.Builder as TB import qualified Data.Text.Lazy.Builder.Int as TB import qualified Data.Text.Read as Text-import Data.Text.Short (ShortText) import qualified Data.Text.Short as TS import qualified Data.Text.Short.Unsafe as TS-import Data.Vector (Vector) import qualified Data.Vector as Vector import qualified Data.Vector.Generic as GVector import qualified Data.Vector.Generic.Mutable as MGVector import qualified Data.Vector.Primitive as PVector import qualified Data.Vector.Unboxed as UVector-import Data.Word (Word64, Word8)-import Foreign.Storable-import GHC.Clock (getMonotonicTimeNSec)-import GHC.Generics (Generic)-import Torsor #ifdef mingw32_HOST_OS import System.Win32.Time (SYSTEMTIME(..))@@ -410,10 +414,6 @@ import Chronos.Internal.CTimespec (getPosixNanoseconds) #endif -#if MIN_VERSION_aeson(2,0,0)-import qualified Data.Aeson.Key as AK-#endif- {- $setup >>> import Test.QuickCheck hiding (within) >>> import Test.QuickCheck.Gen@@ -1461,7 +1461,7 @@ else quot x (raiseTenTo (totalDigits - 9)) pure (fromIntegral result) _ -> pure 0- )+ ) <|> pure 0 pure (s * 1000000000 + nanoseconds) @@ -2139,7 +2139,7 @@ else quot x (raiseTenTo (totalDigits - 9)) pure (fromIntegral result) _ -> pure 0- )+ ) <|> pure 0 pure (s * 1000000000 + nanoseconds) @@ -2835,7 +2835,7 @@ then x * raiseTenTo (9 - totalDigits) else quot x (raiseTenTo (totalDigits - 9)) pure (fromIntegral result)- )+ ) <|> pure 0 pure (s * 1000000000 + nanoseconds) @@ -3792,20 +3792,30 @@ {- | Decode an ISO-8601-encode datetime. The encoded time must be suffixed by either @Z@ or @+00:00@ or @+00@. -}+decodeIso8601Zulu :: Text -> Maybe Chronos.Datetime+{-# INLINE decodeIso8601Zulu #-}+decodeIso8601Zulu !t =+ BVP.parseBytesMaybe parserIso8601Zulu (Utf8.fromText t)++{- | 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+{-# INLINE decodeShortTextIso8601Zulu #-} 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))+ BVP.parseBytesMaybe parserIso8601Zulu (Utf8.fromShortText t) +parserIso8601Zulu :: BVP.Parser () s Chronos.Datetime+{-# NOINLINE parserIso8601Zulu #-}+parserIso8601Zulu = 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 ()+ {- | 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.@@ -3956,7 +3966,7 @@ Examples of output: > 2021-01-05T23:00:51-> 2021-01-05T23:00:52.123000000+> 2021-01-05T23:00:52.123 > 2021-01-05T23:00:53.674094347 -} boundedBuilderUtf8BytesIso8601Zoneless :: Datetime -> Bounded.Builder 44@@ -3974,10 +3984,19 @@ `Bounded.append` Bounded.ascii ':' `Bounded.append` Bounded.wordPaddedDec2 (fromIntegral s) `Bounded.append` ( case ns of- 0 -> Bounded.weaken @0 @10 Lte.constant Bounded.empty- _ ->- Bounded.ascii '.'- `Bounded.append` Bounded.wordPaddedDec9 (fromIntegral ns)+ 0 -> Bounded.weaken @0 @10 Lte.constant Bounded.empty+ _ ->+ let (ms, us) = quotRem ns 1_000_000+ in case us of+ 0 ->+ Bounded.weaken @4 @10+ Lte.constant+ ( Bounded.ascii '.'+ `Bounded.append` Bounded.wordPaddedDec3 (fromIntegral ms)+ )+ _ ->+ Bounded.ascii '.'+ `Bounded.append` Bounded.wordPaddedDec9 (fromIntegral ns) ) boundedBuilderOffset :: Offset -> Bounded.Builder 6