diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 0.2.3.0 (2015-12-08)
+
+- `Data.Time.TH` module with `mkUTCTime`
+- `encodeStrict` in `Data.Aeson.Extra`
+
 # 0.2.2.0 (2015-11-10)
 
 - `U` and `Z` to parse `UTCTime` and `ZonedTime` compatibly
diff --git a/aeson-extra.cabal b/aeson-extra.cabal
--- a/aeson-extra.cabal
+++ b/aeson-extra.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           aeson-extra
-version:        0.2.2.0
+version:        0.2.3.0
 synopsis:       Extra goodies for aeson
 description:    The package motivation is twofold:
                 .
@@ -42,6 +42,7 @@
     , exceptions               >=0.8  && <0.9
     , hashable                 >=1.2  && <1.3
     , scientific               >=0.3  && <0.4
+    , template-haskell         >=2.8  && <2.11
     , text                     >=1.2  && <1.3
     , time                     >=1.4.2 && <1.6
     , unordered-containers     >=0.2  && <0.3
@@ -49,6 +50,7 @@
   exposed-modules:
       Data.Aeson.Compat
       Data.Aeson.Extra
+      Data.Time.TH
   other-modules:
       Data.Aeson.Extra.Time
   default-language: Haskell2010
@@ -68,6 +70,7 @@
     , exceptions               >=0.8  && <0.9
     , hashable                 >=1.2  && <1.3
     , scientific               >=0.3  && <0.4
+    , template-haskell         >=2.8  && <2.11
     , text                     >=1.2  && <1.3
     , time                     >=1.4.2 && <1.6
     , unordered-containers     >=0.2  && <0.3
diff --git a/src/Data/Aeson/Extra.hs b/src/Data/Aeson/Extra.hs
--- a/src/Data/Aeson/Extra.hs
+++ b/src/Data/Aeson/Extra.hs
@@ -18,6 +18,8 @@
 --
 -- More or less useful newtypes for writing 'FromJSON' & 'ToJSON' instances
 module Data.Aeson.Extra (
+  -- * Strict encoding
+  encodeStrict,
   -- * Generic maps
   M(..),
   FromJSONKey(..),
@@ -51,6 +53,8 @@
 
 import           Control.Applicative
 import           Data.Monoid
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Lazy as LBS
 import           Data.Aeson.Compat
 import           Data.Aeson.Types hiding ((.:?))
 import qualified Data.Foldable as Foldable
@@ -70,6 +74,10 @@
 #if !MIN_VERSION_aeson (0,10,0)
 import qualified Data.Aeson.Extra.Time as ExtraTime
 #endif
+
+-- | Like 'encode', but produces strict 'BS.ByteString'.
+encodeStrict :: ToJSON a => a -> BS.ByteString
+encodeStrict = LBS.toStrict . encode
 
 -- | A wrapper type to parse arbitrary maps
 --
diff --git a/src/Data/Time/TH.hs b/src/Data/Time/TH.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Time/TH.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE TemplateHaskell #-}
+-- | Template Haskell extras for `Data.Time`.
+--
+-- This module is in a wrong place, but it reuses the same parser as aeson parser.
+module Data.Time.TH (mkUTCTime) where
+
+import Control.Applicative ((<*))
+import Data.Time (UTCTime(..), Day(..))
+import qualified Data.Text as T
+import qualified Data.Attoparsec.Text as A
+import Language.Haskell.TH
+import Data.Aeson.Extra.Time (utcTime)
+
+-- | Make  a 'UTCTime'. Accepts the same strings as aeson `UTCTime` parser accepts.
+--
+-- > t :: UTCTime
+-- > t = $(mkUTCTime "2014-05-12 00:02:03.456000Z")
+mkUTCTime :: String -> Q Exp
+mkUTCTime s =
+    case A.parseOnly (utcTime <* A.endOfInput) (T.pack s) of
+        Left err -> fail $ "could not parse UTCTime: " ++ err
+        Right (UTCTime (ModifiedJulianDay d) dt) ->
+            [| UTCTime (ModifiedJulianDay $(d')) $(dt') :: UTCTime |]
+          where d'  = return $ LitE $ integerL d
+                dt' = return $ LitE $ rationalL $ toRational dt
diff --git a/test/Tests.hs b/test/Tests.hs
--- a/test/Tests.hs
+++ b/test/Tests.hs
@@ -2,18 +2,18 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE TemplateHaskell #-}
 module Main (main) where
 
 #if !MIN_VERSION_base(4,8,0)
 import           Control.Applicative
 #endif
 
-import           Data.Aeson.Extra
 import qualified Data.HashMap.Lazy as H
 import           Data.Map (Map)
 import           Data.Maybe (isJust)
 import           Data.String (fromString)
-import           Data.Time (zonedTimeToUTC)
+import           Data.Time (zonedTimeToUTC, UTCTime(..), Day(..))
 import           Data.Vector (Vector)
 import           Test.QuickCheck.Instances ()
 import           Test.Tasty
@@ -24,11 +24,15 @@
 import           Data.Proxy
 #endif
 
+import           Data.Aeson.Extra
+import           Data.Time.TH
+
 import           Orphans ()
 
 main :: IO ()
 main = defaultMain $ testGroup "Tests"
   [ dotColonMark
+  , encodeStrictTests
   , mTests
 #if MIN_VERSION_base(4,7,0)
   , symTests
@@ -37,9 +41,22 @@
   , collapsedListTests
   , utctimeTests
   , zonedtimeTests
+  , timeTHTests
   ]
 
 ------------------------------------------------------------------------------
+-- encodeStrict
+------------------------------------------------------------------------------
+encodeStrictTests :: TestTree
+encodeStrictTests = testGroup "encodeStrict"
+  [ testProperty "decodeStrict . encodeStrict" prop
+  ]
+  where prop :: Int -> Property
+        prop i = let lhs = decodeStrict . encodeStrict $ i
+                     rhs = Just i
+                 in lhs === rhs
+
+------------------------------------------------------------------------------
 -- M
 ------------------------------------------------------------------------------
 
@@ -190,3 +207,15 @@
   , "2015-09-07 11:16:40.807 +03:00"
   , "2015-09-07 05:16:40.807 -03:00"
   ]
+
+------------------------------------------------------------------------------
+-- Time Template Haskell
+------------------------------------------------------------------------------
+
+timeTHTests :: TestTree
+timeTHTests =
+    testCase "time TH example" $ assertBool "should be equal" $ lhs == rhs
+      where lhs = UTCTime (ModifiedJulianDay 56789) 123.456
+            rhs = $(mkUTCTime "2014-05-12 00:02:03.456000Z")
+
+    
