diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+0.3.7
+---
+
+* Minor changes:
+    * Use [`attoparsec-iso8601`](http://hackage.haskell.org/package/attoparsec-iso8601)
+      for parsing of time types. Now the accepted formats are the same as by `aeson`,
+      i.e. parsers are more lenient
+      (see [#41](https://github.com/fizruk/http-api-data/pull/41));
+    * Preserve fractions of a second in `ToHttpApiData` instances (see [#53](https://github.com/fizruk/http-api-data/pull/53));
+    * Add `ToHttpApiData` and `FromHttpApiData` instances for `TimeOfDay` (see [#53](https://github.com/fizruk/http-api-data/pull/53)).
+
 0.3.6
 ---
 
diff --git a/http-api-data.cabal b/http-api-data.cabal
--- a/http-api-data.cabal
+++ b/http-api-data.cabal
@@ -1,5 +1,5 @@
 name:            http-api-data
-version:         0.3.6
+version:         0.3.7
 license:         BSD3
 license-file:    LICENSE
 author:          Nickolay Kudasov <nickolay.kudasov@gmail.com>
@@ -37,7 +37,9 @@
 library
     hs-source-dirs: src/
     include-dirs:   include/
-    build-depends:   base               >= 4.7    && < 4.10
+    build-depends:   base               >= 4.7      && < 4.10
+                   , attoparsec         >= 0.13.0.1 && < 0.14
+                   , attoparsec-iso8601 >= 1.0.0.0  && < 1.1
                    , bytestring
                    , containers
                    , hashable
diff --git a/src/Web/Internal/HttpApiData.hs b/src/Web/Internal/HttpApiData.hs
--- a/src/Web/Internal/HttpApiData.hs
+++ b/src/Web/Internal/HttpApiData.hs
@@ -58,7 +58,10 @@
 import qualified Data.ByteString.Builder as BS
 import qualified Network.HTTP.Types as H
 
+import qualified Data.Attoparsec.Text as Atto
+import qualified Data.Attoparsec.Time as Atto
 
+
 -- $setup
 -- >>> data BasicAuthToken = BasicAuthToken Text deriving (Show)
 -- >>> instance FromHttpApiData BasicAuthToken where parseHeader h = BasicAuthToken <$> parseHeaderWithPrefix "Basic " h; parseQueryParam p = BasicAuthToken <$> parseQueryParam p
@@ -453,24 +456,31 @@
 timeToUrlPiece fmt = T.pack . formatTime defaultTimeLocale (iso8601DateFormat (Just fmt))
 
 -- |
--- >>> toUrlPiece $ LocalTime (fromGregorian 2015 10 03) (TimeOfDay 14 55 01)
--- "2015-10-03T14:55:01"
+-- >>> toUrlPiece $ TimeOfDay 14 55 23.1
+-- "14:55:23.1"
+instance ToHttpApiData TimeOfDay where
+  toUrlPiece = T.pack . formatTime defaultTimeLocale "%H:%M:%S%Q"
+  toEncodedUrlPiece = unsafeToEncodedUrlPiece
+
+-- |
+-- >>> toUrlPiece $ LocalTime (fromGregorian 2015 10 03) (TimeOfDay 14 55 21.687)
+-- "2015-10-03T14:55:21.687"
 instance ToHttpApiData LocalTime where
-  toUrlPiece = timeToUrlPiece "%H:%M:%S"
+  toUrlPiece = timeToUrlPiece "%H:%M:%S%Q"
   toEncodedUrlPiece = unsafeToEncodedUrlPiece
 
 -- |
--- >>> toUrlPiece $ ZonedTime (LocalTime (fromGregorian 2015 10 03) (TimeOfDay 14 55 01)) utc
--- "2015-10-03T14:55:01+0000"
+-- >>> toUrlPiece $ ZonedTime (LocalTime (fromGregorian 2015 10 03) (TimeOfDay 14 55 51.001)) utc
+-- "2015-10-03T14:55:51.001+0000"
 instance ToHttpApiData ZonedTime where
-  toUrlPiece = timeToUrlPiece "%H:%M:%S%z"
+  toUrlPiece = timeToUrlPiece "%H:%M:%S%Q%z"
   toEncodedUrlPiece = unsafeToEncodedUrlPiece
 
 -- |
--- >>> toUrlPiece $ UTCTime (fromGregorian 2015 10 03) 864
--- "2015-10-03T00:14:24Z"
+-- >>> toUrlPiece $ UTCTime (fromGregorian 2015 10 03) 864.5
+-- "2015-10-03T00:14:24.5Z"
 instance ToHttpApiData UTCTime where
-  toUrlPiece = timeToUrlPiece "%H:%M:%SZ"
+  toUrlPiece = timeToUrlPiece "%H:%M:%S%QZ"
   toEncodedUrlPiece = unsafeToEncodedUrlPiece
 
 instance ToHttpApiData NominalDiffTime where
@@ -577,27 +587,30 @@
 -- |
 -- >>> toGregorian <$> parseUrlPiece "2016-12-01"
 -- Right (2016,12,1)
-instance FromHttpApiData Day      where parseUrlPiece = readTextData
+instance FromHttpApiData Day where parseUrlPiece = runAtto Atto.day
 
-timeParseUrlPiece :: ParseTime t => String -> Text -> Either Text t
-timeParseUrlPiece fmt = parseMaybeTextData (timeParseUrlPieceMaybe . T.unpack)
-  where
-    timeParseUrlPieceMaybe = parseTime defaultTimeLocale (iso8601DateFormat (Just fmt))
+-- |
+-- >>> parseUrlPiece "14:55:01.333" :: Either Text TimeOfDay
+-- Right 14:55:01.333
+instance FromHttpApiData TimeOfDay where parseUrlPiece = runAtto Atto.timeOfDay
 
 -- |
 -- >>> parseUrlPiece "2015-10-03T14:55:01" :: Either Text LocalTime
 -- Right 2015-10-03 14:55:01
-instance FromHttpApiData LocalTime where parseUrlPiece = timeParseUrlPiece "%H:%M:%S"
+instance FromHttpApiData LocalTime where parseUrlPiece = runAtto Atto.localTime
 
 -- |
 -- >>> parseUrlPiece "2015-10-03T14:55:01+0000" :: Either Text ZonedTime
 -- Right 2015-10-03 14:55:01 +0000
-instance FromHttpApiData ZonedTime where parseUrlPiece = timeParseUrlPiece "%H:%M:%S%z"
+--
+-- >>> parseQueryParam "2016-12-31T01:00:00Z" :: Either Text ZonedTime
+-- Right 2016-12-31 01:00:00 +0000
+instance FromHttpApiData ZonedTime where parseUrlPiece = runAtto Atto.zonedTime
 
 -- |
 -- >>> parseUrlPiece "2015-10-03T00:14:24Z" :: Either Text UTCTime
 -- Right 2015-10-03 00:14:24 UTC
-instance FromHttpApiData UTCTime   where parseUrlPiece = timeParseUrlPiece "%H:%M:%SZ"
+instance FromHttpApiData UTCTime   where parseUrlPiece = runAtto Atto.utcTime
 
 instance FromHttpApiData NominalDiffTime where parseUrlPiece = fmap fromInteger . parseUrlPiece
 
@@ -650,3 +663,12 @@
     parseUrlPiece   = Right . LenientData . parseUrlPiece
     parseHeader     = Right . LenientData . parseHeader
     parseQueryParam = Right . LenientData . parseQueryParam
+
+-------------------------------------------------------------------------------
+-- Attoparsec helpers
+-------------------------------------------------------------------------------
+
+runAtto :: Atto.Parser a -> Text -> Either Text a
+runAtto p t = case Atto.parseOnly (p <* Atto.endOfInput) t of
+    Left err -> Left (T.pack err)
+    Right x  -> Right x
diff --git a/test/Web/Internal/HttpApiDataSpec.hs b/test/Web/Internal/HttpApiDataSpec.hs
--- a/test/Web/Internal/HttpApiDataSpec.hs
+++ b/test/Web/Internal/HttpApiDataSpec.hs
@@ -76,6 +76,7 @@
     checkUrlPiece  (Proxy :: Proxy T.Text)    "Text.Strict"
     checkUrlPiece  (Proxy :: Proxy L.Text)    "Text.Lazy"
     checkUrlPiece  (Proxy :: Proxy Day)       "Day"
+    checkUrlPiece' timeOfDayGen               "TimeOfDay"
     checkUrlPiece' localTimeGen               "LocalTime"
     checkUrlPiece' zonedTimeGen               "ZonedTime"
     checkUrlPiece' utcTimeGen                 "UTCTime"
@@ -112,6 +113,7 @@
     checkEncodedUrlPiece  (Proxy :: Proxy T.Text)    "Text.Strict"
     checkEncodedUrlPiece  (Proxy :: Proxy L.Text)    "Text.Lazy"
     checkEncodedUrlPiece  (Proxy :: Proxy Day)       "Day"
+    checkEncodedUrlPiece' timeOfDayGen               "TimeOfDay"
     checkEncodedUrlPiece' localTimeGen               "LocalTime"
     checkEncodedUrlPiece' zonedTimeGen               "ZonedTime"
     checkEncodedUrlPiece' utcTimeGen                 "UTCTime"
@@ -144,9 +146,13 @@
 
 -- TODO: this generators don't generate full range items
 localTimeGen :: Gen LocalTime
-localTimeGen = LocalTime
-    <$> arbitrary
-    <*> liftA3 TimeOfDay (choose (0, 23)) (choose (0, 59)) (fromInteger <$> choose (0, 60))
+localTimeGen = LocalTime <$> arbitrary <*> timeOfDayGen
+
+timeOfDayGen :: Gen TimeOfDay
+timeOfDayGen = TimeOfDay
+  <$> choose (0, 23)
+  <*> choose (0, 59)
+  <*> fmap (\x -> 0.1 * fromInteger x) (choose (0, 600))
 
 zonedTimeGen :: Gen ZonedTime
 zonedTimeGen = ZonedTime
