diff --git a/chronos.cabal b/chronos.cabal
--- a/chronos.cabal
+++ b/chronos.cabal
@@ -1,5 +1,5 @@
 name: chronos
-version: 1.0
+version: 1.0.1
 synopsis: A performant time library
 description:
   Performance-oriented time library for haskell. The main differences
@@ -55,6 +55,7 @@
     , hashable >= 1.2 && < 1.3
     , primitive >= 0.6 && < 0.7
     , torsor >= 0.1 && < 0.2
+    , clock >= 0.7 && < 0.8
   default-language:    Haskell2010
   c-sources:           src/cbits/hs-time.c
 
diff --git a/src/Chronos.hs b/src/Chronos.hs
--- a/src/Chronos.hs
+++ b/src/Chronos.hs
@@ -1,6 +1,12 @@
-{-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UnboxedTuples #-}
 
 {-# OPTIONS_GHC -Wall #-}
 
@@ -12,6 +18,11 @@
   , tomorrow
   , yesterday
   , epoch
+    -- ** Duration
+  , stopwatch
+  , stopwatch_
+  , stopwatchWith
+  , stopwatchWith_
     -- ** Construction
   , datetimeFromYmdhms
   , timeFromYmdhms
@@ -24,6 +35,10 @@
   , dayToTimeMidnight
   , dayToDate
   , dateToDay
+  , dayToOrdinalDate
+  , ordinalDateToDay
+  , monthDateToDayOfYear
+  , dayOfYearToMonthDay
     -- ** Build Timespan
   , second
   , minute
@@ -61,6 +76,10 @@
   , thursday
   , friday
   , saturday
+    -- ** Utility
+  , daysInMonth
+  , isLeapYear
+  , observedOffsets
     -- * Textual Conversion
     -- ** Date
     -- *** Text
@@ -128,14 +147,48 @@
   , builder_YmdIMS_p_z
   , builder_DmyIMS_p_z
   , builderW3Cz
+  , builderOffset
+  , parserOffset
     -- *** UTF-8 ByteString
   , builderUtf8_YmdHMSz
   , parserUtf8_YmdHMSz
   , builderUtf8_YmdIMS_p_z
   , builderUtf8W3Cz
+  , builderOffsetUtf8
+  , parserOffsetUtf8
+    -- ** Timespan
+    -- *** Text
+  , encodeTimespan 
+  , builderTimespan 
+    -- *** UTF-8 ByteString
+  , encodeTimespanUtf8
+  , builderTimespanUtf8
+    -- * Types
+  , Day(..)
+  , DayOfWeek(..)
+  , DayOfMonth(..)
+  , DayOfYear(..)
+  , Month(..)
+  , Year(..)
+  , Offset(..)
+  , Time(..)
+  , DayOfWeekMatch(..)
+  , MonthMatch(..)
+  , UnboxedMonthMatch(..)
+  , Timespan(..)
+  , SubsecondPrecision(..)
+  , Date(..)
+  , OrdinalDate(..)
+  , MonthDate(..)
+  , Datetime(..)
+  , OffsetDatetime(..)
+  , TimeOfDay(..)
+  , DatetimeFormat(..)
+  , OffsetFormat(..)
+  , DatetimeLocale(..)
+  , MeridiemLocale(..)
   ) where
 
-import Chronos.Types
 import Data.Text (Text)
 import Data.Vector (Vector)
 import Data.Monoid
@@ -149,6 +202,14 @@
 import Torsor (add,difference,scale,plus)
 import Chronos.Internal.CTimespec (getPosixNanoseconds)
 import Data.Word (Word64)
+import Torsor
+import GHC.Generics (Generic)
+import Data.Aeson (FromJSON,ToJSON)
+import Data.Primitive
+import Foreign.Storable
+import Data.Hashable (Hashable)
+import Control.Exception (evaluate)
+import qualified System.Clock as CLK
 import qualified Data.Text as Text
 import qualified Data.Text.Read as Text
 import qualified Data.Attoparsec.Text as AT
@@ -161,6 +222,9 @@
 import qualified Data.Text.Lazy as LT
 import qualified Data.ByteString.Lazy as LB
 import qualified Data.Vector.Unboxed as UVector
+import qualified Data.Vector.Generic as GVector
+import qualified Data.Vector.Primitive as PVector
+import qualified Data.Vector.Generic.Mutable as MGVector
 
 second :: Timespan
 second = Timespan 1000000000
@@ -231,18 +295,55 @@
 today :: IO Day
 today = fmap timeToDayTruncate now
 
+-- | Gets the 'Day' of tomorrow.
 tomorrow :: IO Day
 tomorrow = fmap (add 1 . timeToDayTruncate) now
 
+-- | Gets the 'Day' of yesterday.
 yesterday :: IO Day
 yesterday = fmap (add (-1) . timeToDayTruncate) now
 
+-- | Get the current time from the system clock.
 now :: IO Time
 now = fmap Time getPosixNanoseconds
 
+-- | The Unix epoch, that is 1970-01-01 00:00:00.
 epoch :: Time
 epoch = Time 0
 
+-- | Measures the time it takes to run an action and evaluate
+--   its result to WHNF. This measurement uses a monotonic clock
+--   instead of the standard system clock.
+stopwatch :: IO a -> IO (Timespan, a)
+stopwatch = stopwatchWith CLK.Monotonic
+
+-- | Measures the time it takes to run an action. The result
+--   is discarded. This measurement uses a monotonic clock
+--   instead of the standard system clock.
+stopwatch_ :: IO a -> IO Timespan
+stopwatch_ = stopwatchWith_ CLK.Monotonic
+
+-- | Variant of 'stopwatch' that accepts a clock type. Users
+--   need to import @System.Clock@ from the @clock@ package
+--   in order to provide the clock type.
+stopwatchWith :: CLK.Clock -> IO a -> IO (Timespan, a)
+stopwatchWith c action = do
+  start <- CLK.getTime c
+  a <- action >>= evaluate
+  end <- CLK.getTime c
+  return (timeSpecToTimespan (CLK.diffTimeSpec end start),a)
+
+-- | Variant of 'stopwatch_' that accepts a clock type.
+stopwatchWith_ :: CLK.Clock -> IO a -> IO Timespan
+stopwatchWith_ c action = do
+  start <- CLK.getTime c
+  _ <- action
+  end <- CLK.getTime c
+  return (timeSpecToTimespan (CLK.diffTimeSpec end start))
+
+timeSpecToTimespan :: CLK.TimeSpec -> Timespan
+timeSpecToTimespan (CLK.TimeSpec s ns) = Timespan (s * 1000000000 + ns)
+
 data UtcTime = UtcTime
   {-# UNPACK #-} !Day -- day
   {-# UNPACK #-} !Int64 -- nanoseconds
@@ -272,6 +373,50 @@
 nanosecondsInMinute :: Int64
 nanosecondsInMinute = 60000000000
 
+observedOffsets :: Vector Offset
+observedOffsets = Vector.fromList $ map Offset
+  [ -1200
+  , -1100
+  , -1000
+  , -930
+  , -900
+  , -800
+  , -700
+  , -600
+  , -500
+  , -400
+  , -330
+  , -300
+  , -230
+  , -200
+  , -100
+  , 0
+  , 100
+  , 200
+  , 300
+  , 330
+  , 400
+  , 430
+  , 500
+  , 530
+  , 545
+  , 600
+  , 630
+  , 700
+  , 800
+  , 845
+  , 900
+  , 930
+  , 1000
+  , 1030
+  , 1100
+  , 1200
+  , 1245
+  , 1300
+  , 1345
+  , 1400
+  ]
+
 -- | The first argument in the resulting tuple in a day
 --   adjustment. It should be either -1, 0, or 1, as no
 --   offset should ever exceed 24 hours.
@@ -303,7 +448,7 @@
 dayToDate theDay = Date year month dayOfMonth
   where
   OrdinalDate year yd = dayToOrdinalDate theDay
-  MonthDate month dayOfMonth = dayOfYearToMonthAndDay (isLeapYear year) yd
+  MonthDate month dayOfMonth = dayOfYearToMonthDay (isLeapYear year) yd
 
 -- datetimeToOffsetDatetime :: Offset -> Datetime -> OffsetDatetime
 -- datetimeToOffsetDatetime offset
@@ -341,7 +486,7 @@
 monthDateToDayOfYear isLeap (MonthDate month@(Month m) (DayOfMonth dayOfMonth)) =
   DayOfYear ((div (367 * (fromIntegral m + 1) - 362) 12) + k + day')
   where
-  day' = fromIntegral $ clip 1 (monthLength isLeap month) dayOfMonth
+  day' = fromIntegral $ clip 1 (daysInMonth isLeap month) dayOfMonth
   k = if month < Month 2 then 0 else if isLeap then -1 else -2
 
 ordinalDateToDay :: OrdinalDate -> Day
@@ -357,8 +502,8 @@
 isLeapYear :: Year -> Bool
 isLeapYear (Year year) = (mod year 4 == 0) && ((mod year 400 == 0) || not (mod year 100 == 0))
 
-dayOfYearToMonthAndDay :: Bool -> DayOfYear -> MonthDate
-dayOfYearToMonthAndDay isLeap dayOfYear =
+dayOfYearToMonthDay :: Bool -> DayOfYear -> MonthDate
+dayOfYearToMonthDay isLeap dayOfYear =
   let (!upperBound,!monthTable,!dayTable) =
         if isLeap
           then (DayOfYear 366, leapYearDayOfYearMonthTable, leapYearDayOfYearDayOfMonthTable)
@@ -413,8 +558,8 @@
 internalMatchMonth :: MonthMatch a -> Month -> a
 internalMatchMonth (MonthMatch v) (Month ix) = Vector.unsafeIndex v (fromIntegral ix)
 
-monthLength :: Bool -> Month -> Int
-monthLength isLeap m = if isLeap
+daysInMonth :: Bool -> Month -> Int
+daysInMonth isLeap m = if isLeap
   then internalMatchMonth leapYearMonthLength m
   else internalMatchMonth normalYearMonthLength m
 
@@ -737,6 +882,17 @@
   (milli,milliRem) = quotRem nano 1000000
   (micro,microRem) = quotRem nano 1000
 
+
+encodeTimespan :: SubsecondPrecision -> Timespan -> Text
+encodeTimespan sp =
+  LT.toStrict . TB.toLazyText . builderTimespan sp
+
+builderTimespan :: SubsecondPrecision -> Timespan -> TB.Builder
+builderTimespan sp (Timespan ns) = 
+  TB.decimal sInt64 <> prettyNanosecondsBuilder sp nsRemainder
+  where
+  (!sInt64,!nsRemainder) = quotRem ns 1000000000
+
 internalBuilder_NS :: SubsecondPrecision -> Maybe Char -> Int -> Int64 -> TB.Builder
 internalBuilder_NS sp msep m ns = case msep of
   Nothing -> indexTwoDigitTextBuilder m
@@ -1013,13 +1169,23 @@
     then mempty
     else
       let newSubsecondPart = quot nano (raiseTenTo (9 - d))
-       in "."
+       in BB.char7 '.'
           <> BB.byteString (BC.replicate (d - countDigits newSubsecondPart) '0')
           <> int64Builder newSubsecondPart
   where
   (milli,milliRem) = quotRem nano 1000000
   (micro,microRem) = quotRem nano 1000
 
+encodeTimespanUtf8 :: SubsecondPrecision -> Timespan -> ByteString
+encodeTimespanUtf8 sp =
+  LB.toStrict . BB.toLazyByteString . builderTimespanUtf8 sp
+
+builderTimespanUtf8 :: SubsecondPrecision -> Timespan -> BB.Builder
+builderTimespanUtf8 sp (Timespan ns) = 
+  int64Builder sInt64 <> prettyNanosecondsBuilderUtf8 sp nsRemainder
+  where
+  (!sInt64,!nsRemainder) = quotRem ns 1000000000
+
 int64Builder :: Int64 -> BB.Builder
 int64Builder = BB.integerDec . fromIntegral
 
@@ -1096,18 +1262,18 @@
 builder_YmdHMSz :: OffsetFormat -> SubsecondPrecision -> DatetimeFormat -> OffsetDatetime -> TB.Builder
 builder_YmdHMSz offsetFormat sp datetimeFormat (OffsetDatetime datetime offset) =
      builder_YmdHMS sp datetimeFormat datetime
-  <> offsetBuilder offsetFormat offset
+  <> builderOffset offsetFormat offset
 
 parser_YmdHMSz :: OffsetFormat -> DatetimeFormat -> Parser OffsetDatetime
 parser_YmdHMSz offsetFormat datetimeFormat = OffsetDatetime
   <$> parser_YmdHMS datetimeFormat
-  <*> offsetParser offsetFormat
+  <*> parserOffset offsetFormat
 
 builder_YmdIMS_p_z :: OffsetFormat -> MeridiemLocale Text -> SubsecondPrecision -> DatetimeFormat -> OffsetDatetime -> TB.Builder
 builder_YmdIMS_p_z offsetFormat meridiemLocale sp datetimeFormat (OffsetDatetime datetime offset) =
      builder_YmdIMS_p meridiemLocale sp datetimeFormat datetime
   <> " "
-  <> offsetBuilder offsetFormat offset
+  <> builderOffset offsetFormat offset
 
 encode_YmdHMSz :: OffsetFormat -> SubsecondPrecision -> DatetimeFormat -> OffsetDatetime -> Text
 encode_YmdHMSz offsetFormat sp datetimeFormat =
@@ -1116,18 +1282,18 @@
 builder_DmyHMSz :: OffsetFormat -> SubsecondPrecision -> DatetimeFormat -> OffsetDatetime -> TB.Builder
 builder_DmyHMSz offsetFormat sp datetimeFormat (OffsetDatetime datetime offset) = 
      builder_DmyHMS sp datetimeFormat datetime
-  <> offsetBuilder offsetFormat offset
+  <> builderOffset offsetFormat offset
 
 parser_DmyHMSz :: OffsetFormat -> DatetimeFormat -> AT.Parser OffsetDatetime
 parser_DmyHMSz offsetFormat datetimeFormat = OffsetDatetime
   <$> parser_DmyHMS datetimeFormat
-  <*> offsetParser offsetFormat
+  <*> parserOffset offsetFormat
 
 builder_DmyIMS_p_z :: OffsetFormat -> MeridiemLocale Text -> SubsecondPrecision -> DatetimeFormat -> OffsetDatetime -> TB.Builder
 builder_DmyIMS_p_z offsetFormat meridiemLocale sp datetimeFormat (OffsetDatetime datetime offset) = 
       builder_DmyIMS_p meridiemLocale sp datetimeFormat datetime
    <> " "
-   <> offsetBuilder offsetFormat offset
+   <> builderOffset offsetFormat offset
 
 encode_DmyHMSz :: OffsetFormat -> SubsecondPrecision -> DatetimeFormat -> OffsetDatetime -> Text
 encode_DmyHMSz offsetFormat sp datetimeFormat =
@@ -1139,19 +1305,19 @@
   SubsecondPrecisionAuto
   (DatetimeFormat (Just '-') (Just 'T') (Just ':'))
 
-offsetBuilder :: OffsetFormat -> Offset -> TB.Builder
-offsetBuilder x = case x of
-  OffsetFormatColonOff -> buildOffset_z
-  OffsetFormatColonOn -> buildOffset_z1
-  OffsetFormatSecondsPrecision -> buildOffset_z2
-  OffsetFormatColonAuto -> buildOffset_z3
+builderOffset :: OffsetFormat -> Offset -> TB.Builder
+builderOffset x = case x of
+  OffsetFormatColonOff -> builderOffset_z
+  OffsetFormatColonOn -> builderOffset_z1
+  OffsetFormatSecondsPrecision -> builderOffset_z2
+  OffsetFormatColonAuto -> builderOffset_z3
 
-offsetParser :: OffsetFormat -> Parser Offset
-offsetParser x = case x of
-  OffsetFormatColonOff -> parseOffset_z
-  OffsetFormatColonOn -> parseOffset_z1
-  OffsetFormatSecondsPrecision -> parseOffset_z2
-  OffsetFormatColonAuto -> parseOffset_z3
+parserOffset :: OffsetFormat -> Parser Offset
+parserOffset x = case x of
+  OffsetFormatColonOff -> parserOffset_z
+  OffsetFormatColonOn -> parserOffset_z1
+  OffsetFormatSecondsPrecision -> parserOffset_z2
+  OffsetFormatColonAuto -> parserOffset_z3
 
 -- | True means positive, false means negative
 parseSignedness :: Parser Bool
@@ -1163,8 +1329,8 @@
       then return True
       else fail "while parsing offset, expected [+] or [-]"
 
-parseOffset_z :: Parser Offset
-parseOffset_z = do
+parserOffset_z :: Parser Offset
+parserOffset_z = do
   pos <- parseSignedness
   h <- parseFixedDigits 2
   m <- parseFixedDigits 2
@@ -1173,8 +1339,8 @@
     then res
     else negate res
 
-parseOffset_z1 :: Parser Offset
-parseOffset_z1 = do
+parserOffset_z1 :: Parser Offset
+parserOffset_z1 = do
   pos <- parseSignedness
   h <- parseFixedDigits 2
   _ <- AT.char ':'
@@ -1184,8 +1350,8 @@
     then res
     else negate res
 
-parseOffset_z2 :: AT.Parser Offset
-parseOffset_z2 = do
+parserOffset_z2 :: AT.Parser Offset
+parserOffset_z2 = do
   pos <- parseSignedness
   h <- parseFixedDigits 2
   _ <- AT.char ':'
@@ -1199,8 +1365,8 @@
 -- | This is generous in what it accepts. If you give
 --   something like +04:00 as the offset, it will be
 --   allowed, even though it could be shorter.
-parseOffset_z3 :: AT.Parser Offset
-parseOffset_z3 = do
+parserOffset_z3 :: AT.Parser Offset
+parserOffset_z3 = do
   pos <- parseSignedness
   h <- parseFixedDigits 2
   mc <- AT.peekChar
@@ -1216,16 +1382,16 @@
       then h * 60
       else h * (-60)
 
-buildOffset_z :: Offset -> TB.Builder
-buildOffset_z (Offset i) =
+builderOffset_z :: Offset -> TB.Builder
+builderOffset_z (Offset i) =
   let (!a,!b) = divMod (abs i) 60
       !prefix = if signum i == (-1) then "-" else "+"
    in prefix
       <> indexTwoDigitTextBuilder a
       <> indexTwoDigitTextBuilder b
 
-buildOffset_z1 :: Offset -> TB.Builder
-buildOffset_z1 (Offset i) =
+builderOffset_z1 :: Offset -> TB.Builder
+builderOffset_z1 (Offset i) =
   let (!a,!b) = divMod (abs i) 60
       !prefix = if signum i == (-1) then "-" else "+"
    in prefix
@@ -1233,8 +1399,8 @@
       <> ":"
       <> indexTwoDigitTextBuilder b
 
-buildOffset_z2 :: Offset -> TB.Builder
-buildOffset_z2 (Offset i) =
+builderOffset_z2 :: Offset -> TB.Builder
+builderOffset_z2 (Offset i) =
   let (!a,!b) = divMod (abs i) 60
       !prefix = if signum i == (-1) then "-" else "+"
    in prefix
@@ -1243,8 +1409,8 @@
       <> indexTwoDigitTextBuilder b
       <> ":00"
 
-buildOffset_z3 :: Offset -> TB.Builder
-buildOffset_z3 (Offset i) =
+builderOffset_z3 :: Offset -> TB.Builder
+builderOffset_z3 (Offset i) =
   let (!a,!b) = divMod (abs i) 60
       !prefix = if signum i == (-1) then "-" else "+"
    in if b == 0
@@ -1258,18 +1424,18 @@
 builderUtf8_YmdHMSz :: OffsetFormat -> SubsecondPrecision -> DatetimeFormat -> OffsetDatetime -> BB.Builder
 builderUtf8_YmdHMSz offsetFormat sp datetimeFormat (OffsetDatetime datetime offset) =
      builderUtf8_YmdHMS sp datetimeFormat datetime
-  <> offsetBuilderUtf8 offsetFormat offset
+  <> builderOffsetUtf8 offsetFormat offset
 
 parserUtf8_YmdHMSz :: OffsetFormat -> DatetimeFormat -> AB.Parser OffsetDatetime
 parserUtf8_YmdHMSz offsetFormat datetimeFormat = OffsetDatetime
   <$> parserUtf8_YmdHMS datetimeFormat
-  <*> offsetParserUtf8 offsetFormat
+  <*> parserOffsetUtf8 offsetFormat
 
 builderUtf8_YmdIMS_p_z :: OffsetFormat -> MeridiemLocale ByteString -> SubsecondPrecision -> DatetimeFormat -> OffsetDatetime -> BB.Builder
 builderUtf8_YmdIMS_p_z offsetFormat meridiemLocale sp datetimeFormat (OffsetDatetime datetime offset) =
      builderUtf8_YmdIMS_p meridiemLocale sp datetimeFormat datetime
   <> " "
-  <> offsetBuilderUtf8 offsetFormat offset
+  <> builderOffsetUtf8 offsetFormat offset
 
 builderUtf8W3Cz :: OffsetDatetime -> BB.Builder
 builderUtf8W3Cz = builderUtf8_YmdHMSz
@@ -1277,19 +1443,19 @@
   SubsecondPrecisionAuto
   (DatetimeFormat (Just '-') (Just 'T') (Just ':'))
 
-offsetBuilderUtf8 :: OffsetFormat -> Offset -> BB.Builder
-offsetBuilderUtf8 x = case x of
-  OffsetFormatColonOff -> buildOffsetUtf8_z
-  OffsetFormatColonOn -> buildOffsetUtf8_z1
-  OffsetFormatSecondsPrecision -> buildOffsetUtf8_z2
-  OffsetFormatColonAuto -> buildOffsetUtf8_z3
+builderOffsetUtf8 :: OffsetFormat -> Offset -> BB.Builder
+builderOffsetUtf8 x = case x of
+  OffsetFormatColonOff -> builderOffsetUtf8_z
+  OffsetFormatColonOn -> builderOffsetUtf8_z1
+  OffsetFormatSecondsPrecision -> builderOffsetUtf8_z2
+  OffsetFormatColonAuto -> builderOffsetUtf8_z3
 
-offsetParserUtf8 :: OffsetFormat -> AB.Parser Offset
-offsetParserUtf8 x = case x of
-  OffsetFormatColonOff -> parseOffsetUtf8_z
-  OffsetFormatColonOn -> parseOffsetUtf8_z1
-  OffsetFormatSecondsPrecision -> parseOffsetUtf8_z2
-  OffsetFormatColonAuto -> parseOffsetUtf8_z3
+parserOffsetUtf8 :: OffsetFormat -> AB.Parser Offset
+parserOffsetUtf8 x = case x of
+  OffsetFormatColonOff -> parserOffsetUtf8_z
+  OffsetFormatColonOn -> parserOffsetUtf8_z1
+  OffsetFormatSecondsPrecision -> parserOffsetUtf8_z2
+  OffsetFormatColonAuto -> parserOffsetUtf8_z3
 
 -- | True means positive, false means negative
 parseSignednessUtf8 :: AB.Parser Bool
@@ -1301,8 +1467,8 @@
       then return True
       else fail "while parsing offset, expected [+] or [-]"
 
-parseOffsetUtf8_z :: AB.Parser Offset
-parseOffsetUtf8_z = do
+parserOffsetUtf8_z :: AB.Parser Offset
+parserOffsetUtf8_z = do
   pos <- parseSignednessUtf8
   h <- parseFixedDigitsIntBS 2
   m <- parseFixedDigitsIntBS 2
@@ -1311,8 +1477,8 @@
     then res
     else negate res
 
-parseOffsetUtf8_z1 :: AB.Parser Offset
-parseOffsetUtf8_z1 = do
+parserOffsetUtf8_z1 :: AB.Parser Offset
+parserOffsetUtf8_z1 = do
   pos <- parseSignednessUtf8
   h <- parseFixedDigitsIntBS 2
   _ <- AB.char ':'
@@ -1322,8 +1488,8 @@
     then res
     else negate res
 
-parseOffsetUtf8_z2 :: AB.Parser Offset
-parseOffsetUtf8_z2 = do
+parserOffsetUtf8_z2 :: AB.Parser Offset
+parserOffsetUtf8_z2 = do
   pos <- parseSignednessUtf8
   h <- parseFixedDigitsIntBS 2
   _ <- AB.char ':'
@@ -1337,8 +1503,8 @@
 -- | This is generous in what it accepts. If you give
 --   something like +04:00 as the offset, it will be
 --   allowed, even though it could be shorter.
-parseOffsetUtf8_z3 :: AB.Parser Offset
-parseOffsetUtf8_z3 = do
+parserOffsetUtf8_z3 :: AB.Parser Offset
+parserOffsetUtf8_z3 = do
   pos <- parseSignednessUtf8
   h <- parseFixedDigitsIntBS 2
   mc <- AB.peekChar
@@ -1354,16 +1520,16 @@
       then h * 60
       else h * (-60)
 
-buildOffsetUtf8_z :: Offset -> BB.Builder
-buildOffsetUtf8_z (Offset i) =
+builderOffsetUtf8_z :: Offset -> BB.Builder
+builderOffsetUtf8_z (Offset i) =
   let (!a,!b) = divMod (abs i) 60
       !prefix = if signum i == (-1) then "-" else "+"
    in prefix
       <> indexTwoDigitByteStringBuilder a
       <> indexTwoDigitByteStringBuilder b
 
-buildOffsetUtf8_z1 :: Offset -> BB.Builder
-buildOffsetUtf8_z1 (Offset i) =
+builderOffsetUtf8_z1 :: Offset -> BB.Builder
+builderOffsetUtf8_z1 (Offset i) =
   let (!a,!b) = divMod (abs i) 60
       !prefix = if signum i == (-1) then "-" else "+"
    in prefix
@@ -1371,8 +1537,8 @@
       <> ":"
       <> indexTwoDigitByteStringBuilder b
 
-buildOffsetUtf8_z2 :: Offset -> BB.Builder
-buildOffsetUtf8_z2 (Offset i) =
+builderOffsetUtf8_z2 :: Offset -> BB.Builder
+builderOffsetUtf8_z2 (Offset i) =
   let (!a,!b) = divMod (abs i) 60
       !prefix = if signum i == (-1) then "-" else "+"
    in prefix
@@ -1381,8 +1547,8 @@
       <> indexTwoDigitByteStringBuilder b
       <> ":00"
 
-buildOffsetUtf8_z3 :: Offset -> BB.Builder
-buildOffsetUtf8_z3 (Offset i) =
+builderOffsetUtf8_z3 :: Offset -> BB.Builder
+builderOffsetUtf8_z3 (Offset i) =
   let (!a,!b) = divMod (abs i) 60
       !prefix = if signum i == (-1) then "-" else "+"
    in if b == 0
@@ -1557,4 +1723,297 @@
 
 zeroPadDayOfMonthBS :: DayOfMonth -> BB.Builder
 zeroPadDayOfMonthBS (DayOfMonth d) = indexTwoDigitByteStringBuilder d
+
+-- | A day represented as the modified Julian date, the number of days
+--   since midnight on November 17, 1858.
+newtype Day = Day { getDay :: Int }
+  deriving (Show,Read,Eq,Ord,Hashable,Enum,ToJSON,FromJSON,Storable,Prim)
+
+instance Torsor Day Int where
+  add i (Day d) = Day (d + i)
+  difference (Day a) (Day b) = a - b
+
+-- | The day of the week.
+newtype DayOfWeek = DayOfWeek { getDayOfWeek :: Int }
+  deriving (Show,Read,Eq,Ord,Hashable)
+
+-- | The day of the month.
+newtype DayOfMonth = DayOfMonth { getDayOfMonth :: Int }
+  deriving (Show,Read,Eq,Ord,Prim,Enum)
+
+-- | The day of the year.
+newtype DayOfYear = DayOfYear { getDayOfYear :: Int }
+  deriving (Show,Read,Eq,Ord,Prim)
+
+-- | The month of the year.
+newtype Month = Month { getMonth :: Int }
+  deriving (Show,Read,Eq,Ord,Prim)
+
+instance Bounded Month where
+  minBound = Month 0
+  maxBound = Month 11
+
+-- | The number of years elapsed since the beginning
+--   of the Common Era.
+newtype Year = Year { getYear :: Int }
+  deriving (Show,Read,Eq,Ord)
+
+newtype Offset = Offset { getOffset :: Int }
+  deriving (Show,Read,Eq,Ord,Enum)
+
+-- | POSIX time with nanosecond resolution.
+newtype Time = Time { getTime :: Int64 }
+  deriving (FromJSON,ToJSON,Hashable,Eq,Ord,Show,Read,Storable,Prim)
+
+newtype DayOfWeekMatch a = DayOfWeekMatch { getDayOfWeekMatch :: Vector a }
+
+newtype MonthMatch a = MonthMatch { getMonthMatch :: Vector a }
+
+newtype UnboxedMonthMatch a = UnboxedMonthMatch { getUnboxedMonthMatch :: UVector.Vector a }
+
+-- | A timespan. This is represented internally as a number
+--   of nanoseconds.
+newtype Timespan = Timespan { getTimespan :: Int64 }
+  deriving (Show,Read,Eq,Ord,ToJSON,FromJSON,Additive)
+
+instance Monoid Timespan where
+  mempty = Timespan 0
+  mappend (Timespan a) (Timespan b) = Timespan (a + b)
+
+instance Torsor Time Timespan where
+  add (Timespan ts) (Time t) = Time (t + ts)
+  difference (Time t) (Time s) = Timespan (t - s)
+
+instance Scaling Timespan Int64 where
+  scale i (Timespan ts) = Timespan (i * ts)
+
+instance Torsor Offset Int where
+  add i (Offset x) = Offset (x + i)
+  difference (Offset x) (Offset y) = x - y
+
+-- | The precision used when encoding seconds to a human-readable format.
+data SubsecondPrecision
+  = SubsecondPrecisionAuto -- ^ Rounds to second, millisecond, microsecond, or nanosecond
+  | SubsecondPrecisionFixed {-# UNPACK #-} !Int -- ^ Specify number of places after decimal
+
+-- | A date as represented by the Gregorian calendar.
+data Date = Date
+  { dateYear  :: {-# UNPACK #-} !Year
+  , dateMonth :: {-# UNPACK #-} !Month
+  , dateDay   :: {-# UNPACK #-} !DayOfMonth
+  } deriving (Show,Read,Eq,Ord)
+
+-- | The year and number of days elapsed since the beginning it began.
+data OrdinalDate = OrdinalDate
+  { ordinalDateYear :: {-# UNPACK #-} !Year
+  , ordinalDateDayOfYear :: {-# UNPACK #-} !DayOfYear
+  } deriving (Show,Read,Eq,Ord)
+
+-- | A month and the day of the month. This does not actually represent
+--   a specific date, since this recurs every year.
+data MonthDate = MonthDate
+  { monthDateMonth :: {-# UNPACK #-} !Month
+  , monthDateDay :: {-# UNPACK #-} !DayOfMonth
+  } deriving (Show,Read,Eq,Ord)
+
+-- | A date as represented by the Gregorian calendar
+--   and a time of day.
+data Datetime = Datetime
+  { datetimeDate :: {-# UNPACK #-} !Date
+  , datetimeTime :: {-# UNPACK #-} !TimeOfDay
+  } deriving (Show,Read,Eq,Ord)
+
+data OffsetDatetime = OffsetDatetime
+  { offsetDatetimeDatetime :: {-# UNPACK #-} !Datetime
+  , offsetDatetimeOffset :: {-# UNPACK #-} !Offset
+  } deriving (Show,Read,Eq,Ord)
+
+-- | A time of day with nanosecond resolution.
+data TimeOfDay = TimeOfDay
+  { timeOfDayHour :: {-# UNPACK #-} !Int
+  , timeOfDayMinute :: {-# UNPACK #-} !Int
+  , timeOfDayNanoseconds :: {-# UNPACK #-} !Int64
+  } deriving (Show,Read,Eq,Ord)
+
+data DatetimeFormat = DatetimeFormat
+  { datetimeFormatDateSeparator :: !(Maybe Char)
+    -- ^ Separator in the date
+  , datetimeFormatSeparator :: !(Maybe Char)
+    -- ^ Separator between date and time
+  , datetimeFormatTimeSeparator :: !(Maybe Char)
+    -- ^ Separator in the time
+  } deriving (Show,Read,Eq,Ord)
+
+-- | Formatting settings for a timezone offset.
+data OffsetFormat
+  = OffsetFormatColonOff -- ^ @%z@ (e.g., -0400)
+  | OffsetFormatColonOn -- ^ @%:z@ (e.g., -04:00)
+  | OffsetFormatSecondsPrecision -- ^ @%::z@ (e.g., -04:00:00)
+  | OffsetFormatColonAuto -- ^ @%:::z@ (e.g., -04, +05:30)
+  deriving (Show,Read,Eq,Ord,Enum,Bounded,Generic)
+
+-- | Locale-specific formatting for weekdays and months. The
+--   type variable will likely be instantiated to @Text@
+--   or @ByteString@.
+data DatetimeLocale a = DatetimeLocale
+  { datetimeLocaleDaysOfWeekFull :: !(DayOfWeekMatch a)
+    -- ^ full weekdays starting with Sunday, 7 elements
+  , datetimeLocaleDaysOfWeekAbbreviated :: !(DayOfWeekMatch a)
+    -- ^ abbreviated weekdays starting with Sunday, 7 elements
+  , datetimeLocaleMonthsFull :: !(MonthMatch a)
+    -- ^ full months starting with January, 12 elements
+  , datetimeLocaleMonthsAbbreviated :: !(MonthMatch a)
+    -- ^ abbreviated months starting with January, 12 elements
+  }
+
+-- | Locale-specific formatting for AM and PM.
+data MeridiemLocale a = MeridiemLocale
+  { meridiemLocaleAm :: !a
+  , meridiemLocalePm :: !a
+  } deriving (Read,Show,Eq,Ord)
+
+newtype instance UVector.MVector s Month = MV_Month (PVector.MVector s Month)
+newtype instance UVector.Vector Month = V_Month (PVector.Vector Month)
+
+instance UVector.Unbox Month
+
+instance MGVector.MVector UVector.MVector Month where
+  {-# INLINE basicLength #-}
+  {-# INLINE basicUnsafeSlice #-}
+  {-# INLINE basicOverlaps #-}
+  {-# INLINE basicUnsafeNew #-}
+  {-# INLINE basicInitialize #-}
+  {-# INLINE basicUnsafeReplicate #-}
+  {-# INLINE basicUnsafeRead #-}
+  {-# INLINE basicUnsafeWrite #-}
+  {-# INLINE basicClear #-}
+  {-# INLINE basicSet #-}
+  {-# INLINE basicUnsafeCopy #-}
+  {-# INLINE basicUnsafeGrow #-}
+  basicLength (MV_Month v) = MGVector.basicLength v
+  basicUnsafeSlice i n (MV_Month v) = MV_Month $ MGVector.basicUnsafeSlice i n v
+  basicOverlaps (MV_Month v1) (MV_Month v2) = MGVector.basicOverlaps v1 v2
+  basicUnsafeNew n = MV_Month `liftM` MGVector.basicUnsafeNew n
+  basicInitialize (MV_Month v) = MGVector.basicInitialize v
+  basicUnsafeReplicate n x = MV_Month `liftM` MGVector.basicUnsafeReplicate n x
+  basicUnsafeRead (MV_Month v) i = MGVector.basicUnsafeRead v i
+  basicUnsafeWrite (MV_Month v) i x = MGVector.basicUnsafeWrite v i x
+  basicClear (MV_Month v) = MGVector.basicClear v
+  basicSet (MV_Month v) x = MGVector.basicSet v x
+  basicUnsafeCopy (MV_Month v1) (MV_Month v2) = MGVector.basicUnsafeCopy v1 v2
+  basicUnsafeMove (MV_Month v1) (MV_Month v2) = MGVector.basicUnsafeMove v1 v2
+  basicUnsafeGrow (MV_Month v) n = MV_Month `liftM` MGVector.basicUnsafeGrow v n
+
+instance GVector.Vector UVector.Vector Month where
+  {-# INLINE basicUnsafeFreeze #-}
+  {-# INLINE basicUnsafeThaw #-}
+  {-# INLINE basicLength #-}
+  {-# INLINE basicUnsafeSlice #-}
+  {-# INLINE basicUnsafeIndexM #-}
+  {-# INLINE elemseq #-}
+  basicUnsafeFreeze (MV_Month v) = V_Month `liftM` GVector.basicUnsafeFreeze v
+  basicUnsafeThaw (V_Month v) = MV_Month `liftM` GVector.basicUnsafeThaw v
+  basicLength (V_Month v) = GVector.basicLength v
+  basicUnsafeSlice i n (V_Month v) = V_Month $ GVector.basicUnsafeSlice i n v
+  basicUnsafeIndexM (V_Month v) i = GVector.basicUnsafeIndexM v i
+  basicUnsafeCopy (MV_Month mv) (V_Month v) = GVector.basicUnsafeCopy mv v
+  elemseq _ = seq
+
+newtype instance UVector.MVector s DayOfMonth = MV_DayOfMonth (PVector.MVector s DayOfMonth)
+newtype instance UVector.Vector DayOfMonth = V_DayOfMonth (PVector.Vector DayOfMonth)
+
+instance UVector.Unbox DayOfMonth
+
+instance MGVector.MVector UVector.MVector DayOfMonth where
+  {-# INLINE basicLength #-}
+  {-# INLINE basicUnsafeSlice #-}
+  {-# INLINE basicOverlaps #-}
+  {-# INLINE basicUnsafeNew #-}
+  {-# INLINE basicInitialize #-}
+  {-# INLINE basicUnsafeReplicate #-}
+  {-# INLINE basicUnsafeRead #-}
+  {-# INLINE basicUnsafeWrite #-}
+  {-# INLINE basicClear #-}
+  {-# INLINE basicSet #-}
+  {-# INLINE basicUnsafeCopy #-}
+  {-# INLINE basicUnsafeGrow #-}
+  basicLength (MV_DayOfMonth v) = MGVector.basicLength v
+  basicUnsafeSlice i n (MV_DayOfMonth v) = MV_DayOfMonth $ MGVector.basicUnsafeSlice i n v
+  basicOverlaps (MV_DayOfMonth v1) (MV_DayOfMonth v2) = MGVector.basicOverlaps v1 v2
+  basicUnsafeNew n = MV_DayOfMonth `liftM` MGVector.basicUnsafeNew n
+  basicInitialize (MV_DayOfMonth v) = MGVector.basicInitialize v
+  basicUnsafeReplicate n x = MV_DayOfMonth `liftM` MGVector.basicUnsafeReplicate n x
+  basicUnsafeRead (MV_DayOfMonth v) i = MGVector.basicUnsafeRead v i
+  basicUnsafeWrite (MV_DayOfMonth v) i x = MGVector.basicUnsafeWrite v i x
+  basicClear (MV_DayOfMonth v) = MGVector.basicClear v
+  basicSet (MV_DayOfMonth v) x = MGVector.basicSet v x
+  basicUnsafeCopy (MV_DayOfMonth v1) (MV_DayOfMonth v2) = MGVector.basicUnsafeCopy v1 v2
+  basicUnsafeMove (MV_DayOfMonth v1) (MV_DayOfMonth v2) = MGVector.basicUnsafeMove v1 v2
+  basicUnsafeGrow (MV_DayOfMonth v) n = MV_DayOfMonth `liftM` MGVector.basicUnsafeGrow v n
+
+instance GVector.Vector UVector.Vector DayOfMonth where
+  {-# INLINE basicUnsafeFreeze #-}
+  {-# INLINE basicUnsafeThaw #-}
+  {-# INLINE basicLength #-}
+  {-# INLINE basicUnsafeSlice #-}
+  {-# INLINE basicUnsafeIndexM #-}
+  {-# INLINE elemseq #-}
+  basicUnsafeFreeze (MV_DayOfMonth v) = V_DayOfMonth `liftM` GVector.basicUnsafeFreeze v
+  basicUnsafeThaw (V_DayOfMonth v) = MV_DayOfMonth `liftM` GVector.basicUnsafeThaw v
+  basicLength (V_DayOfMonth v) = GVector.basicLength v
+  basicUnsafeSlice i n (V_DayOfMonth v) = V_DayOfMonth $ GVector.basicUnsafeSlice i n v
+  basicUnsafeIndexM (V_DayOfMonth v) i = GVector.basicUnsafeIndexM v i
+  basicUnsafeCopy (MV_DayOfMonth mv) (V_DayOfMonth v) = GVector.basicUnsafeCopy mv v
+  elemseq _ = seq
+
+------------------------
+-- The Torsor and Enum instances for Date and OrdinalDate
+-- are both bad. This only causes problems for dates
+-- at least a million years in the future. Some of this
+-- badness is caused by pragmatism, and some of it is caused by
+-- my own laziness.
+--
+-- The badness that comes from pragmatism:
+--   - Int technically is not a good delta for Date. Date
+--     has too many inhabitants. If we subtract the lowest
+--     Date from the highest Date, we get something too
+--     big to fit in a machine integer.
+--   - There is no good way to write fromEnum or toEnum for
+--     Date. Again, Date has more inhabitants than Int, so
+--     it simply cannot be done.
+-- The badness that comes from laziness:
+--   - Technically, we should still be able to add deltas to
+--     Dates that do not fit in machine integers. We should
+--     also be able to correctly subtract Dates to cannot
+--     fit in machine integers.
+--   - For similar reasons, the Enum functions succ, pred,
+--     enumFromThen, enumFromThenTo, etc. could all have
+--     better definitions than the default ones currently
+--     used.
+-- If, for some reason, anyone ever wants to fix the badness
+-- that comes from laziness, all
+-- you really have to do is define a version of dateToDay,
+-- dayToDate, ordinalDateToDay, and dayToOrdinalDate
+-- that uses something bigger instead of Day. Maybe something like
+-- (Int,Word) or (Int,Word,Word). I'm not exactly sure how
+-- big it would need to be to work correctly. Then you could
+-- handle deltas of two very far off days correctly, provided
+-- that the two days weren't also super far from each other.
+--
+------------------------
+instance Torsor Date Int where
+  add i d = dayToDate (add i (dateToDay d))
+  difference a b = difference (dateToDay a) (dateToDay b)
+
+instance Torsor OrdinalDate Int where
+  add i d = dayToOrdinalDate (add i (ordinalDateToDay d))
+  difference a b = difference (ordinalDateToDay a) (ordinalDateToDay b)
+
+instance Enum Date where
+  fromEnum d = fromEnum (dateToDay d)
+  toEnum i = dayToDate (toEnum i)
+
+instance Enum OrdinalDate where
+  fromEnum d = fromEnum (ordinalDateToDay d)
+  toEnum i = dayToOrdinalDate (toEnum i)
 
diff --git a/src/Chronos/Types.hs b/src/Chronos/Types.hs
--- a/src/Chronos/Types.hs
+++ b/src/Chronos/Types.hs
@@ -1,10 +1,3 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE UnboxedTuples #-}
-{-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE MagicHash #-}
-
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 {- | Data types for representing different date and time-related
@@ -62,255 +55,4 @@
   , MeridiemLocale(..)
   ) where
 
-import Torsor
-import Data.Int
-import Data.Vector (Vector)
-import Data.Aeson (FromJSON,ToJSON)
-import Data.Hashable (Hashable)
-import Data.Primitive
-import Foreign.Storable
-import Control.Monad
-import GHC.Generics (Generic)
-import Data.Monoid (Monoid(..))
-import qualified Data.Vector.Generic as GVector
-import qualified Data.Vector.Unboxed as UVector
-import qualified Data.Vector.Primitive as PVector
-import qualified Data.Vector.Generic.Mutable as MGVector
-
--- | A day represented as the modified Julian date, the number of days
---   since midnight on November 17, 1858.
-newtype Day = Day { getDay :: Int }
-  deriving (Show,Read,Eq,Ord,Hashable,Enum,ToJSON,FromJSON,Storable,Prim)
-
-instance Torsor Day Int where
-  add i (Day d) = Day (d + i)
-  difference (Day a) (Day b) = a - b
-
--- | The day of the week.
-newtype DayOfWeek = DayOfWeek { getDayOfWeek :: Int }
-  deriving (Show,Read,Eq,Ord,Hashable)
-
--- | The day of the month.
-newtype DayOfMonth = DayOfMonth { getDayOfMonth :: Int }
-  deriving (Show,Read,Eq,Ord,Prim,Enum)
-
--- | The day of the year.
-newtype DayOfYear = DayOfYear { getDayOfYear :: Int }
-  deriving (Show,Read,Eq,Ord,Prim)
-
--- | The month of the year.
-newtype Month = Month { getMonth :: Int }
-  deriving (Show,Read,Eq,Ord,Prim)
-
-instance Bounded Month where
-  minBound = Month 0
-  maxBound = Month 11
-
--- | The number of years elapsed since the beginning
---   of the Common Era.
-newtype Year = Year { getYear :: Int }
-  deriving (Show,Read,Eq,Ord)
-
-newtype Offset = Offset { getOffset :: Int }
-  deriving (Show,Read,Eq,Ord)
-
--- | POSIX time with nanosecond resolution.
-newtype Time = Time { getTime :: Int64 }
-  deriving (FromJSON,ToJSON,Hashable,Eq,Ord,Show,Read,Storable,Prim)
-
-newtype DayOfWeekMatch a = DayOfWeekMatch { getDayOfWeekMatch :: Vector a }
-
-newtype MonthMatch a = MonthMatch { getMonthMatch :: Vector a }
-
-newtype UnboxedMonthMatch a = UnboxedMonthMatch { getUnboxedMonthMatch :: UVector.Vector a }
-
--- | A timespan. This is represented internally as a number
---   of nanoseconds.
-newtype Timespan = Timespan { getTimespan :: Int64 }
-  deriving (Show,Read,Eq,Ord,ToJSON,FromJSON,Additive)
-
-instance Monoid Timespan where
-  mempty = Timespan 0
-  mappend (Timespan a) (Timespan b) = Timespan (a + b)
-
-instance Torsor Time Timespan where
-  add (Timespan ts) (Time t) = Time (t + ts)
-  difference (Time t) (Time s) = Timespan (t - s)
-
-instance Scaling Timespan Int64 where
-  scale i (Timespan ts) = Timespan (i * ts)
-
--- | The precision used when encoding seconds to a human-readable format.
-data SubsecondPrecision
-  = SubsecondPrecisionAuto -- ^ Rounds to second, millisecond, microsecond, or nanosecond
-  | SubsecondPrecisionFixed {-# UNPACK #-} !Int -- ^ Specify number of places after decimal
-
--- | A date as represented by the Gregorian calendar.
-data Date = Date
-  { dateYear  :: {-# UNPACK #-} !Year
-  , dateMonth :: {-# UNPACK #-} !Month
-  , dateDay   :: {-# UNPACK #-} !DayOfMonth
-  } deriving (Show,Read,Eq,Ord)
-
--- | The year and number of days elapsed since the beginning it began.
-data OrdinalDate = OrdinalDate
-  { ordinalDateYear :: {-# UNPACK #-} !Year
-  , ordinalDateDayOfYear :: {-# UNPACK #-} !DayOfYear
-  } deriving (Show,Read,Eq,Ord)
-
--- | A month and the day of the month. This does not actually represent
---   a specific date, since this recurs every year.
-data MonthDate = MonthDate
-  { monthDateMonth :: {-# UNPACK #-} !Month
-  , monthDateDay :: {-# UNPACK #-} !DayOfMonth
-  } deriving (Show,Read,Eq,Ord)
-
--- | A date as represented by the Gregorian calendar
---   and a time of day.
-data Datetime = Datetime
-  { datetimeDate :: {-# UNPACK #-} !Date
-  , datetimeTime :: {-# UNPACK #-} !TimeOfDay
-  } deriving (Show,Read,Eq,Ord)
-
-data OffsetDatetime = OffsetDatetime
-  { offsetDatetimeDatetime :: {-# UNPACK #-} !Datetime
-  , offsetDatetimeOffset :: {-# UNPACK #-} !Offset
-  } deriving (Show,Read,Eq,Ord)
-
--- | A time of day with nanosecond resolution.
-data TimeOfDay = TimeOfDay
-  { timeOfDayHour :: {-# UNPACK #-} !Int
-  , timeOfDayMinute :: {-# UNPACK #-} !Int
-  , timeOfDayNanoseconds :: {-# UNPACK #-} !Int64
-  } deriving (Show,Read,Eq,Ord)
-
-data DatetimeFormat = DatetimeFormat
-  { datetimeFormatDateSeparator :: !(Maybe Char)
-    -- ^ Separator in the date
-  , datetimeFormatSeparator :: !(Maybe Char)
-    -- ^ Separator between date and time
-  , datetimeFormatTimeSeparator :: !(Maybe Char)
-    -- ^ Separator in the time
-  } deriving (Show,Read,Eq,Ord)
-
--- | Formatting settings for a timezone offset.
-data OffsetFormat
-  = OffsetFormatColonOff -- ^ @%z@ (e.g., -0400)
-  | OffsetFormatColonOn -- ^ @%:z@ (e.g., -04:00)
-  | OffsetFormatSecondsPrecision -- ^ @%::z@ (e.g., -04:00:00)
-  | OffsetFormatColonAuto -- ^ @%:::z@ (e.g., -04, +05:30)
-  deriving (Show,Read,Eq,Ord,Enum,Bounded,Generic)
-
--- | Locale-specific formatting for weekdays and months. The
---   type variable will likely be instantiated to @Text@
---   or @ByteString@.
-data DatetimeLocale a = DatetimeLocale
-  { datetimeLocaleDaysOfWeekFull :: !(DayOfWeekMatch a)
-    -- ^ full weekdays starting with Sunday, 7 elements
-  , datetimeLocaleDaysOfWeekAbbreviated :: !(DayOfWeekMatch a)
-    -- ^ abbreviated weekdays starting with Sunday, 7 elements
-  , datetimeLocaleMonthsFull :: !(MonthMatch a)
-    -- ^ full months starting with January, 12 elements
-  , datetimeLocaleMonthsAbbreviated :: !(MonthMatch a)
-    -- ^ abbreviated months starting with January, 12 elements
-  }
-
--- | Locale-specific formatting for AM and PM.
-data MeridiemLocale a = MeridiemLocale
-  { meridiemLocaleAm :: !a
-  , meridiemLocalePm :: !a
-  } deriving (Read,Show,Eq,Ord)
-
-newtype instance UVector.MVector s Month = MV_Month (PVector.MVector s Month)
-newtype instance UVector.Vector Month = V_Month (PVector.Vector Month)
-
-instance UVector.Unbox Month
-
-instance MGVector.MVector UVector.MVector Month where
-  {-# INLINE basicLength #-}
-  {-# INLINE basicUnsafeSlice #-}
-  {-# INLINE basicOverlaps #-}
-  {-# INLINE basicUnsafeNew #-}
-  {-# INLINE basicInitialize #-}
-  {-# INLINE basicUnsafeReplicate #-}
-  {-# INLINE basicUnsafeRead #-}
-  {-# INLINE basicUnsafeWrite #-}
-  {-# INLINE basicClear #-}
-  {-# INLINE basicSet #-}
-  {-# INLINE basicUnsafeCopy #-}
-  {-# INLINE basicUnsafeGrow #-}
-  basicLength (MV_Month v) = MGVector.basicLength v
-  basicUnsafeSlice i n (MV_Month v) = MV_Month $ MGVector.basicUnsafeSlice i n v
-  basicOverlaps (MV_Month v1) (MV_Month v2) = MGVector.basicOverlaps v1 v2
-  basicUnsafeNew n = MV_Month `liftM` MGVector.basicUnsafeNew n
-  basicInitialize (MV_Month v) = MGVector.basicInitialize v
-  basicUnsafeReplicate n x = MV_Month `liftM` MGVector.basicUnsafeReplicate n x
-  basicUnsafeRead (MV_Month v) i = MGVector.basicUnsafeRead v i
-  basicUnsafeWrite (MV_Month v) i x = MGVector.basicUnsafeWrite v i x
-  basicClear (MV_Month v) = MGVector.basicClear v
-  basicSet (MV_Month v) x = MGVector.basicSet v x
-  basicUnsafeCopy (MV_Month v1) (MV_Month v2) = MGVector.basicUnsafeCopy v1 v2
-  basicUnsafeMove (MV_Month v1) (MV_Month v2) = MGVector.basicUnsafeMove v1 v2
-  basicUnsafeGrow (MV_Month v) n = MV_Month `liftM` MGVector.basicUnsafeGrow v n
-
-instance GVector.Vector UVector.Vector Month where
-  {-# INLINE basicUnsafeFreeze #-}
-  {-# INLINE basicUnsafeThaw #-}
-  {-# INLINE basicLength #-}
-  {-# INLINE basicUnsafeSlice #-}
-  {-# INLINE basicUnsafeIndexM #-}
-  {-# INLINE elemseq #-}
-  basicUnsafeFreeze (MV_Month v) = V_Month `liftM` GVector.basicUnsafeFreeze v
-  basicUnsafeThaw (V_Month v) = MV_Month `liftM` GVector.basicUnsafeThaw v
-  basicLength (V_Month v) = GVector.basicLength v
-  basicUnsafeSlice i n (V_Month v) = V_Month $ GVector.basicUnsafeSlice i n v
-  basicUnsafeIndexM (V_Month v) i = GVector.basicUnsafeIndexM v i
-  basicUnsafeCopy (MV_Month mv) (V_Month v) = GVector.basicUnsafeCopy mv v
-  elemseq _ = seq
-
-newtype instance UVector.MVector s DayOfMonth = MV_DayOfMonth (PVector.MVector s DayOfMonth)
-newtype instance UVector.Vector DayOfMonth = V_DayOfMonth (PVector.Vector DayOfMonth)
-
-instance UVector.Unbox DayOfMonth
-
-instance MGVector.MVector UVector.MVector DayOfMonth where
-  {-# INLINE basicLength #-}
-  {-# INLINE basicUnsafeSlice #-}
-  {-# INLINE basicOverlaps #-}
-  {-# INLINE basicUnsafeNew #-}
-  {-# INLINE basicInitialize #-}
-  {-# INLINE basicUnsafeReplicate #-}
-  {-# INLINE basicUnsafeRead #-}
-  {-# INLINE basicUnsafeWrite #-}
-  {-# INLINE basicClear #-}
-  {-# INLINE basicSet #-}
-  {-# INLINE basicUnsafeCopy #-}
-  {-# INLINE basicUnsafeGrow #-}
-  basicLength (MV_DayOfMonth v) = MGVector.basicLength v
-  basicUnsafeSlice i n (MV_DayOfMonth v) = MV_DayOfMonth $ MGVector.basicUnsafeSlice i n v
-  basicOverlaps (MV_DayOfMonth v1) (MV_DayOfMonth v2) = MGVector.basicOverlaps v1 v2
-  basicUnsafeNew n = MV_DayOfMonth `liftM` MGVector.basicUnsafeNew n
-  basicInitialize (MV_DayOfMonth v) = MGVector.basicInitialize v
-  basicUnsafeReplicate n x = MV_DayOfMonth `liftM` MGVector.basicUnsafeReplicate n x
-  basicUnsafeRead (MV_DayOfMonth v) i = MGVector.basicUnsafeRead v i
-  basicUnsafeWrite (MV_DayOfMonth v) i x = MGVector.basicUnsafeWrite v i x
-  basicClear (MV_DayOfMonth v) = MGVector.basicClear v
-  basicSet (MV_DayOfMonth v) x = MGVector.basicSet v x
-  basicUnsafeCopy (MV_DayOfMonth v1) (MV_DayOfMonth v2) = MGVector.basicUnsafeCopy v1 v2
-  basicUnsafeMove (MV_DayOfMonth v1) (MV_DayOfMonth v2) = MGVector.basicUnsafeMove v1 v2
-  basicUnsafeGrow (MV_DayOfMonth v) n = MV_DayOfMonth `liftM` MGVector.basicUnsafeGrow v n
-
-instance GVector.Vector UVector.Vector DayOfMonth where
-  {-# INLINE basicUnsafeFreeze #-}
-  {-# INLINE basicUnsafeThaw #-}
-  {-# INLINE basicLength #-}
-  {-# INLINE basicUnsafeSlice #-}
-  {-# INLINE basicUnsafeIndexM #-}
-  {-# INLINE elemseq #-}
-  basicUnsafeFreeze (MV_DayOfMonth v) = V_DayOfMonth `liftM` GVector.basicUnsafeFreeze v
-  basicUnsafeThaw (V_DayOfMonth v) = MV_DayOfMonth `liftM` GVector.basicUnsafeThaw v
-  basicLength (V_DayOfMonth v) = GVector.basicLength v
-  basicUnsafeSlice i n (V_DayOfMonth v) = V_DayOfMonth $ GVector.basicUnsafeSlice i n v
-  basicUnsafeIndexM (V_DayOfMonth v) i = GVector.basicUnsafeIndexM v i
-  basicUnsafeCopy (MV_DayOfMonth mv) (V_DayOfMonth v) = GVector.basicUnsafeCopy mv v
-  elemseq _ = seq
+import Chronos
