diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017-2020 Tom Sydney Kerckhove
+
+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/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+import Distribution.Simple
+
+main = defaultMain
diff --git a/bench/Bench.hs b/bench/Bench.hs
new file mode 100644
--- /dev/null
+++ b/bench/Bench.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE TypeApplications #-}
+
+module Main where
+
+import Criterion.Main as Criterion
+
+import Data.GenValidity.Criterion
+
+import Cursor.FuzzyDay
+import Cursor.FuzzyDay.Gen ()
+import Cursor.FuzzyLocalTime
+import Cursor.FuzzyLocalTime.Gen ()
+import Cursor.FuzzyTimeOfDay
+import Cursor.FuzzyTimeOfDay.Gen ()
+
+main :: IO ()
+main =
+  Criterion.defaultMain
+    [ genValidBench @FuzzyDayCursor
+    , genValidBench @FuzzyLocalTimeCursor
+    , genValidBench @FuzzyTimeOfDayCursor
+    ]
diff --git a/cursor-fuzzy-time-gen.cabal b/cursor-fuzzy-time-gen.cabal
new file mode 100644
--- /dev/null
+++ b/cursor-fuzzy-time-gen.cabal
@@ -0,0 +1,87 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.33.0.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 6e24e29e40687b3222d1ff320499f360a01a7a4956719fe9097bf01a83cb1b08
+
+name:           cursor-fuzzy-time-gen
+version:        0.0.0.0
+description:    Generators for the fuzzy time cursors
+category:       Time
+homepage:       https://github.com/NorfairKing/fuzzy-time
+author:         Tom Sydney Kerckhove
+maintainer:     syd@cs-syd.eu
+copyright:      Copyright: (c) 2017-2020 Tom Sydney Kerckhove
+license:        MIT
+license-file:   LICENSE
+build-type:     Simple
+
+library
+  exposed-modules:
+      Cursor.FuzzyDay.Gen
+      Cursor.FuzzyLocalTime.Gen
+      Cursor.FuzzyTimeOfDay.Gen
+  other-modules:
+      Paths_cursor_fuzzy_time_gen
+  hs-source-dirs:
+      src/
+  ghc-options: -Wall
+  build-depends:
+      base >=4.9 && <=5
+    , containers
+    , cursor-fuzzy-time
+    , cursor-gen
+    , deepseq
+    , fuzzy-time
+    , fuzzy-time-gen
+    , genvalidity
+    , genvalidity-time
+    , megaparsec
+    , time
+  default-language: Haskell2010
+
+test-suite cursor-fuzzy-time-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Cursor.FuzzyDaySpec
+      Cursor.FuzzyLocalTimeSpec
+      Cursor.FuzzyTimeOfDaySpec
+      Paths_cursor_fuzzy_time_gen
+  hs-source-dirs:
+      test/
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
+  build-depends:
+      QuickCheck
+    , base >=4.9 && <=5
+    , cursor-fuzzy-time
+    , cursor-fuzzy-time-gen
+    , fuzzy-time
+    , genvalidity
+    , genvalidity-hspec
+    , genvalidity-hspec-optics
+    , genvalidity-time
+    , hspec
+    , megaparsec
+    , text
+    , time
+  default-language: Haskell2010
+
+benchmark cursor-fuzzy-time-bench
+  type: exitcode-stdio-1.0
+  main-is: Bench.hs
+  other-modules:
+      Paths_cursor_fuzzy_time_gen
+  hs-source-dirs:
+      bench/
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
+  build-depends:
+      QuickCheck
+    , base >=4.9 && <=5
+    , criterion
+    , cursor-fuzzy-time
+    , cursor-fuzzy-time-gen
+    , genvalidity-criterion
+  default-language: Haskell2010
diff --git a/src/Cursor/FuzzyDay/Gen.hs b/src/Cursor/FuzzyDay/Gen.hs
new file mode 100644
--- /dev/null
+++ b/src/Cursor/FuzzyDay/Gen.hs
@@ -0,0 +1,16 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module Cursor.FuzzyDay.Gen where
+
+import Data.GenValidity
+import Data.GenValidity.Time ()
+
+import Cursor.Text.Gen ()
+
+import Cursor.FuzzyDay
+
+instance GenUnchecked FuzzyDayCursor
+
+instance GenValid FuzzyDayCursor where
+  genValid = genValidStructurallyWithoutExtraChecking
+  shrinkValid = shrinkValidStructurallyWithoutExtraFiltering
diff --git a/src/Cursor/FuzzyLocalTime/Gen.hs b/src/Cursor/FuzzyLocalTime/Gen.hs
new file mode 100644
--- /dev/null
+++ b/src/Cursor/FuzzyLocalTime/Gen.hs
@@ -0,0 +1,17 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module Cursor.FuzzyLocalTime.Gen where
+
+import Data.FuzzyTime.Types.Gen ()
+import Data.GenValidity
+import Data.GenValidity.Time ()
+
+import Cursor.Text.Gen ()
+
+import Cursor.FuzzyLocalTime
+
+instance GenUnchecked FuzzyLocalTimeCursor
+
+instance GenValid FuzzyLocalTimeCursor where
+  genValid = genValidStructurallyWithoutExtraChecking
+  shrinkValid = shrinkValidStructurallyWithoutExtraFiltering
diff --git a/src/Cursor/FuzzyTimeOfDay/Gen.hs b/src/Cursor/FuzzyTimeOfDay/Gen.hs
new file mode 100644
--- /dev/null
+++ b/src/Cursor/FuzzyTimeOfDay/Gen.hs
@@ -0,0 +1,16 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module Cursor.FuzzyTimeOfDay.Gen where
+
+import Data.GenValidity
+import Data.GenValidity.Time ()
+
+import Cursor.Text.Gen ()
+
+import Cursor.FuzzyTimeOfDay
+
+instance GenUnchecked FuzzyTimeOfDayCursor
+
+instance GenValid FuzzyTimeOfDayCursor where
+  genValid = genValidStructurallyWithoutExtraChecking
+  shrinkValid = shrinkValidStructurallyWithoutExtraFiltering
diff --git a/test/Cursor/FuzzyDaySpec.hs b/test/Cursor/FuzzyDaySpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Cursor/FuzzyDaySpec.hs
@@ -0,0 +1,36 @@
+{-# LANGUAGE TypeApplications #-}
+
+module Cursor.FuzzyDaySpec where
+
+import Data.Int
+import Data.Time
+
+import Test.Hspec
+import Test.QuickCheck
+import Test.Validity
+import Test.Validity.Optics
+
+import Cursor.FuzzyDay
+import Cursor.FuzzyDay.Gen ()
+
+spec :: Spec
+spec = do
+  eqSpecOnValid @FuzzyDayCursor
+  genValidSpec @FuzzyDayCursor
+  describe "emptyFuzzyDayCursor" $ do
+    it "produces valid cursors" $ producesValidsOnValids emptyFuzzyDayCursor
+    it "makes cursors that makes the guessing produce nothing" $
+      forAllValid $ \today ->
+        fuzzyDayCursorGuess (emptyFuzzyDayCursor today) `shouldBe` Nothing
+  describe "makeFuzzyDayCursor" $ do
+    it "produces valid cursors" $ producesValidsOnValids makeFuzzyDayCursor
+    it
+      "makes cursors that makes the guessing produce the given time for recent days" $
+      forAll (ModifiedJulianDay . fromIntegral <$> (genValid :: Gen Int16)) $ \d ->
+        fuzzyDayCursorGuess (makeFuzzyDayCursor d) `shouldBe` Just d
+  describe "rebuildFuzzyDayCursor" $ do
+    it "produces valid days" $ producesValidsOnValids rebuildFuzzyDayCursor
+  describe "fuzzyDayCursorTextCursorL" $
+    lensSpecOnValid fuzzyDayCursorTextCursorL
+  describe "fuzzyDayCursorGuess" $
+    it "guesses a valid day" $ producesValidsOnValids fuzzyDayCursorGuess
diff --git a/test/Cursor/FuzzyLocalTimeSpec.hs b/test/Cursor/FuzzyLocalTimeSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Cursor/FuzzyLocalTimeSpec.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE TypeApplications #-}
+
+module Cursor.FuzzyLocalTimeSpec where
+
+import Data.Int
+import Data.Time
+
+import Test.Hspec
+import Test.QuickCheck
+import Test.Validity
+import Test.Validity.Optics
+
+import Cursor.FuzzyLocalTime
+import Cursor.FuzzyLocalTime.Gen ()
+import Data.FuzzyTime.Types
+
+spec :: Spec
+spec = do
+  eqSpecOnValid @FuzzyLocalTimeCursor
+  genValidSpec @FuzzyLocalTimeCursor
+  describe "emptyFuzzyLocalTimeCursor" $ do
+    it "produces valid cursors" $
+      producesValidsOnValids emptyFuzzyLocalTimeCursor
+    it "makes cursors that makes the guessing produce nothing" $
+      forAllValid $ \today ->
+        fuzzyLocalTimeCursorGuess (emptyFuzzyLocalTimeCursor today) `shouldBe`
+        Nothing
+  describe "makeFuzzyLocalTimeCursor" $ do
+    it "produces valid cursors" $
+      producesValidsOnValids makeFuzzyLocalTimeCursor
+    it
+      "makes cursors that makes the guessing produce the given time for recent days" $
+      forAll (ModifiedJulianDay . fromIntegral <$> (genValid :: Gen Int16)) $ \d ->
+        fuzzyLocalTimeCursorGuess
+          (makeFuzzyLocalTimeCursor (OnlyDaySpecified d)) `shouldBe`
+        Just (OnlyDaySpecified d)
+  describe "rebuildFuzzyLocalTimeCursor" $ do
+    it "produces valid time of day" $
+      producesValidsOnValids rebuildFuzzyLocalTimeCursor
+  describe "fuzzyLocalTimeCursorTextCursorL" $
+    lensSpecOnValid fuzzyLocalTimeCursorTextCursorL
+  describe "fuzzyLocalTimeCursorGuess" $
+    it "guesses a valid time of day" $
+    producesValidsOnValids fuzzyLocalTimeCursorGuess
diff --git a/test/Cursor/FuzzyTimeOfDaySpec.hs b/test/Cursor/FuzzyTimeOfDaySpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Cursor/FuzzyTimeOfDaySpec.hs
@@ -0,0 +1,36 @@
+{-# LANGUAGE TypeApplications #-}
+
+module Cursor.FuzzyTimeOfDaySpec where
+
+import Test.Hspec
+import Test.Validity
+import Test.Validity.Optics
+
+import Cursor.FuzzyTimeOfDay
+import Cursor.FuzzyTimeOfDay.Gen ()
+
+spec :: Spec
+spec = do
+  eqSpecOnValid @FuzzyTimeOfDayCursor
+  genValidSpec @FuzzyTimeOfDayCursor
+  describe "emptyFuzzyTimeOfDayCursor" $ do
+    it "produces valid cursors" $
+      producesValidsOnValids emptyFuzzyTimeOfDayCursor
+    it "makes cursors that makes the guessing produce nothing" $
+      forAllValid $ \today ->
+        fuzzyTimeOfDayCursorGuess (emptyFuzzyTimeOfDayCursor today) `shouldBe`
+        Nothing
+  describe "makeFuzzyTimeOfDayCursor" $ do
+    it "produces valid cursors" $
+      producesValidsOnValids makeFuzzyTimeOfDayCursor
+    it "makes cursors that makes the guessing produce the given time" $
+      forAllValid $ \d ->
+        fuzzyTimeOfDayCursorGuess (makeFuzzyTimeOfDayCursor d) `shouldBe` Just d
+  describe "rebuildFuzzyTimeOfDayCursor" $ do
+    it "produces valid time of day" $
+      producesValidsOnValids rebuildFuzzyTimeOfDayCursor
+  describe "fuzzyTimeOfDayCursorTextCursorL" $
+    lensSpecOnValid fuzzyTimeOfDayCursorTextCursorL
+  describe "fuzzyTimeOfDayCursorGuess" $
+    it "guesses a valid time of day" $
+    producesValidsOnValids fuzzyTimeOfDayCursorGuess
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 #-}
