diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,3 @@
+# Changelog for freer-simple-time
+
+## Unreleased changes
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Co—Star Astrology, Ben Weitzman
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,1 @@
+# freer-simple-time
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/freer-simple-time.cabal b/freer-simple-time.cabal
new file mode 100644
--- /dev/null
+++ b/freer-simple-time.cabal
@@ -0,0 +1,57 @@
+-- This file has been generated from package.yaml by hpack version 0.28.2.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 5ab33c3a11c5c741efb773c2fa89cf511f5ed2861ed19cd1f7c7c3a363fa16d4
+
+name:           freer-simple-time
+version:        0.1.0.0
+synopsis:       freer-simple interface to IO based time functions
+description:    Please see the README on Gitlab at <https://gitlab.com/costar-astrology/freer-simple-contrib/tree/master/freer-simple-time>
+category:       Control, Time
+author:         Ben Weitzman
+maintainer:     ben@costarastrology.com
+copyright:      2018 Ben Weitzman
+license:        MIT
+license-file:   LICENSE
+build-type:     Simple
+cabal-version:  >= 1.10
+extra-source-files:
+    ChangeLog.md
+    README.md
+
+source-repository head
+  type: git
+  location: https://gitlab.com/costar-astrology/freer-simple-contrib/tree/master/freer-simple-time
+
+library
+  exposed-modules:
+      Control.Monad.Freer.Time
+  other-modules:
+      Paths_freer_simple_time
+  hs-source-dirs:
+      src
+  default-extensions: GADTs FlexibleContexts TypeOperators DataKinds StandaloneDeriving DeriveDataTypeable MultiParamTypeClasses FlexibleInstances UndecidableInstances TypeApplications ScopedTypeVariables TypeFamilies RankNTypes DeriveAnyClass OverloadedStrings FunctionalDependencies ConstraintKinds EmptyCase BangPatterns
+  build-depends:
+      base >=4.7 && <5
+    , freer-simple >=1.1 && <1.2
+    , time >=1.8 && <1.9
+  default-language: Haskell2010
+
+test-suite freer-simple-time-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Control.Monad.Freer.TimeSpec
+      Paths_freer_simple_time
+  hs-source-dirs:
+      test
+  default-extensions: GADTs FlexibleContexts TypeOperators DataKinds StandaloneDeriving DeriveDataTypeable MultiParamTypeClasses FlexibleInstances UndecidableInstances TypeApplications ScopedTypeVariables TypeFamilies RankNTypes DeriveAnyClass OverloadedStrings FunctionalDependencies ConstraintKinds EmptyCase BangPatterns
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      base >=4.7 && <5
+    , freer-simple >=1.1 && <1.2
+    , freer-simple-time
+    , hspec
+    , time >=1.8 && <1.9
+  default-language: Haskell2010
diff --git a/src/Control/Monad/Freer/Time.hs b/src/Control/Monad/Freer/Time.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Freer/Time.hs
@@ -0,0 +1,46 @@
+{-|
+Module      : Control.Monad.Freer.Time
+Description : Effect for working with the current time
+Copyright   : (c) Ben Weitzman 2018
+License     : MIT
+Maintainer  : ben@costarastrolgoy.com
+Stability   : experimental
+Portability : POSIX
+-}
+
+module Control.Monad.Freer.Time
+  (currentTime
+  ,Time
+  ,runTime
+  ,runTimeAt
+  ,runInstantaneously
+  )
+where
+
+import Control.Monad.Freer
+import Data.Time
+
+-- | The 'Time' effect gives an interface to accessing the current time
+data Time a where
+  CurrentTime :: Time UTCTime
+
+-- | Get the current time
+currentTime :: (Member Time r) => Eff r UTCTime
+currentTime = send CurrentTime
+
+-- | Use 'IO' to handle getting the current time
+runTime :: Member IO r => Eff (Time ': r) a -> Eff r a
+runTime = interpret $ \CurrentTime -> send getCurrentTime
+
+-- | Use a given time that the program will consider "current"
+runTimeAt :: UTCTime -> Eff (Time ': r) a -> Eff r a
+runTimeAt instant = interpret $ \CurrentTime -> return instant  
+
+-- | Use 'IO' get the current time, but make the program think that
+-- everything is happening at the same instant. All calls to 'currentTime'
+-- will return the same, present-ish 'UTCTime'
+runInstantaneously :: (Member IO r) => Eff (Time ': r) a -> Eff r a
+runInstantaneously eff = do
+  now <- runTime currentTime
+  runTimeAt now eff
+  
diff --git a/test/Control/Monad/Freer/TimeSpec.hs b/test/Control/Monad/Freer/TimeSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Control/Monad/Freer/TimeSpec.hs
@@ -0,0 +1,23 @@
+module Control.Monad.Freer.TimeSpec where
+
+import Control.Monad.Freer.Time
+
+import Control.Monad.Freer
+import Test.Hspec
+
+spec :: Spec
+spec = do
+  describe "runTimeAt" $ do
+    it "should give the expected time" $ do
+      let time = read "2018-11-10 18:39:54.228369 UTC"
+          gotTime = run $ runTimeAt time currentTime
+      gotTime `shouldBe` time
+      
+  describe "runInstantaneously" $ do
+    it "should make all times seem the same" $ do
+      let getTwoTimes = (,) <$> currentTime <*> currentTime
+      (timeA, timeB) <- runM $ runTime getTwoTimes
+      timeA `shouldNotBe` timeB
+      (timeC,  timeD) <- runM $ runInstantaneously getTwoTimes
+      timeC `shouldBe` timeD
+
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
