diff --git a/Data/Time/Units.hs b/Data/Time/Units.hs
new file mode 100644
--- /dev/null
+++ b/Data/Time/Units.hs
@@ -0,0 +1,237 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+-- |This module defines types for many useful time periods, as well as
+-- mechanisms for converting between them.
+module Data.Time.Units(
+         TimeUnit(..)
+       , Attosecond
+       , Femtosecond
+       , Picosecond
+       , Nanosecond
+       , Microsecond
+       , Millisecond
+       , Second
+       , Minute
+       , Hour
+       , Day
+       , Week
+       , Fortnight
+       , addTime
+       , subTime
+       , convertUnit
+       , getCPUTimeWithUnit
+       )
+ where
+
+import Data.Ix(Ix)
+import Data.Data(Data)
+import Data.List(isPrefixOf)
+import Data.Typeable(Typeable)
+import System.CPUTime
+
+-- |A generic class that describes all the units of time. We use microseconds
+-- here because that tends to be what GHC (at least) tends to use as its 
+-- system-level minimum tick size.
+class TimeUnit a where
+  -- |Converts the given unit of time into microseconds, flooring the value
+  -- if it comes to a fractional number of microseconds. (In other words:
+  -- be careful, you may lose precision!)
+  toMicroseconds   :: a -> Integer
+  -- |Converts the given number of microseconds into the unit of time, flooring
+  -- the value if it comes to a fraction number of the given unit. (In other
+  -- words: be careful, you may lose precision!)
+  fromMicroseconds :: Integer -> a
+
+-- |Add two times together to get a useful third time unit. As per usual,
+-- you'll want to make sure that you are careful regarding precision. This
+-- function goes through microseconds as an intermediary form.
+addTime :: (TimeUnit a, TimeUnit b, TimeUnit c) => a -> b -> c
+addTime x y = fromMicroseconds (toMicroseconds x + toMicroseconds y)
+
+-- |Subtract the second time from the first, to get a useful third time unit.
+-- As per usual, you'll want to make sure that you are careful regarding
+-- precision. This function goes through microseconds as an intermediary form.
+subTime :: (TimeUnit a, TimeUnit b, TimeUnit c) => a -> b -> c
+subTime x y = fromMicroseconds (toMicroseconds x - toMicroseconds y)
+
+-- |Convert one time unit to another. Note that if you move from a smaller
+-- time unit to a larger one, or between two time units smaller than a
+-- microsecond, you will lose precision.
+convertUnit :: (TimeUnit a, TimeUnit b) => a -> b
+convertUnit = fromMicroseconds . toMicroseconds
+
+-- |Get the current CPU time in your favorite units. This is probably not
+-- very useful in itself, but is likely useful for comparison purposes ...
+getCPUTimeWithUnit :: TimeUnit a => IO a
+getCPUTimeWithUnit =
+  (fromMicroseconds . toMicroseconds . Picosecond) `fmap` getCPUTime
+
+--
+
+newtype Attosecond  = Attosecond  Integer
+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)
+
+instance TimeUnit Attosecond where
+  toMicroseconds (Attosecond x) = x `div` (10 ^ 12)
+  fromMicroseconds x            = Attosecond (x * (10 ^ 12))
+instance Show Attosecond where
+  show (Attosecond x) = show x ++ "as"
+instance Read Attosecond where
+  readsPrec = readUnit Attosecond "as"
+
+readUnit :: (Integer -> a) -> String ->
+            Int -> String ->
+            [(a, String)]
+readUnit builder unitstr prec str = processItems builder (readsPrec prec str)
+ where
+  processItems :: (Integer -> a) -> [(Integer,String)] -> [(a,String)]
+  processItems builder  [] = []
+  processItems builder ((a,s):rest)
+    | unitstr `isPrefixOf` s =
+           (builder a, drop (length unitstr) s) : (processItems builder rest)
+        | otherwise              =
+           processItems builder rest
+
+--
+
+newtype Femtosecond = Femtosecond Integer
+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)
+
+instance TimeUnit Femtosecond where
+  toMicroseconds (Femtosecond x) = x `div` (10 ^ 9)
+  fromMicroseconds x             = Femtosecond (x * (10 ^ 9))
+instance Show Femtosecond where
+  show (Femtosecond x) = show x ++ "fs"
+instance Read Femtosecond where
+  readsPrec = readUnit Femtosecond "fs"
+
+--
+
+newtype Picosecond  = Picosecond  Integer
+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)
+
+instance TimeUnit Picosecond where
+  toMicroseconds (Picosecond x) = x `div` (10 ^ 6)
+  fromMicroseconds x            = Picosecond (x * (10 ^ 6))
+instance Show Picosecond where
+  show (Picosecond x) = show x ++ "ps"
+instance Read Picosecond where
+  readsPrec = readUnit Picosecond "ps"
+
+--
+
+newtype Nanosecond  = Nanosecond  Integer
+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)
+
+instance TimeUnit Nanosecond where
+  toMicroseconds (Nanosecond x) = x `div` (10 ^ 3)
+  fromMicroseconds x            = Nanosecond (x * (10 ^ 3))
+instance Show Nanosecond where
+  show (Nanosecond x) = show x ++ "ns"
+instance Read Nanosecond where
+  readsPrec = readUnit Nanosecond "ns"
+
+--
+
+newtype Microsecond = Microsecond Integer
+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)
+
+instance TimeUnit Microsecond where
+  toMicroseconds (Microsecond x) = x
+  fromMicroseconds x             = Microsecond x
+instance Show Microsecond where
+  show (Microsecond x) = show x ++ "µs"
+instance Read Microsecond where
+  readsPrec = readUnit Microsecond "µs"
+
+--
+
+newtype Millisecond  = Millisecond  Integer
+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)
+
+instance TimeUnit Millisecond where
+  toMicroseconds (Millisecond x) = x * (10 ^ 3)
+  fromMicroseconds x             = Millisecond (x `div` (10 ^ 3))
+instance Show Millisecond where
+  show (Millisecond x) = show x ++ "ms"
+instance Read Millisecond where
+  readsPrec = readUnit Millisecond "ms"
+
+--
+
+newtype Second      = Second      Integer
+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)
+
+instance TimeUnit Second where
+  toMicroseconds (Second x) = x * (10 ^ 6)
+  fromMicroseconds x        = Second (x `div` (10 ^ 6))
+instance Show Second where
+  show (Second x) = show x ++ "s"
+instance Read Second where
+  readsPrec = readUnit Second "s"
+
+--
+
+newtype Minute      = Minute      Integer
+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)
+
+instance TimeUnit Minute where
+  toMicroseconds (Minute x) = x * (toMicroseconds $ Second 60)
+  fromMicroseconds x        = Minute (x `div` (toMicroseconds $ Second 60))
+instance Show Minute where
+  show (Minute x) = show x ++ "m"
+instance Read Minute where
+  readsPrec = readUnit Minute "m"
+
+--
+
+newtype Hour        = Hour        Integer
+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)
+
+instance TimeUnit Hour where
+  toMicroseconds (Hour x) = x * (toMicroseconds $ Minute 60)
+  fromMicroseconds x      = Hour (x `div` (toMicroseconds $ Minute 60))
+instance Show Hour where
+  show (Hour x) = show x ++ "h"
+instance Read Hour where
+  readsPrec = readUnit Hour "h"
+
+--
+
+newtype Day         = Day         Integer
+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)
+
+instance TimeUnit Day where
+  toMicroseconds (Day x) = x * (toMicroseconds $ Hour 24)
+  fromMicroseconds x     = Day (x `div` (toMicroseconds $ Hour 24))
+instance Show Day where
+  show (Day x) = show x ++ "d"
+instance Read Day where
+  readsPrec = readUnit Day "d"
+
+--
+
+newtype Week        = Week        Integer
+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)
+
+instance TimeUnit Week where
+  toMicroseconds (Week x) = x * (toMicroseconds $ Day 7)
+  fromMicroseconds x      = Week (x `div` (toMicroseconds $ Day 7))
+instance Show Week where
+  show (Week x) = show x ++ "w"
+instance Read Week where
+  readsPrec = readUnit Week "w"
+
+--
+
+newtype Fortnight   = Fortnight   Integer
+ deriving (Enum,Eq,Integral,Data,Num,Ord,Real,Ix,Typeable)
+
+instance TimeUnit Fortnight where
+  toMicroseconds (Fortnight x) = x * (toMicroseconds $ Week 2)
+  fromMicroseconds x           = Fortnight (x `div` (toMicroseconds $ Week 2))
+instance Show Fortnight where
+  show (Fortnight x) = show x ++ "fn"
+instance Read Fortnight where
+  readsPrec = readUnit Fortnight "fn"
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,25 @@
+Copyright (c) 2011 Adam Wick
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice, this
+    list of conditions and the following disclaimer.
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution. 
+  * Neither the name Adam Wick nor the names of any contributors
+    may be used to endorse or promote products derived from this software
+    without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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/time-units.cabal b/time-units.cabal
new file mode 100644
--- /dev/null
+++ b/time-units.cabal
@@ -0,0 +1,29 @@
+Name: time-units
+Version: 1.0.0
+Build-Type: Simple
+Cabal-Version: >= 1.6
+License: BSD3
+License-File: LICENSE
+Author: Adam Wick <awick@uhsure.com>
+Maintainer: Adam Wick <awick@uhusre.com>
+Homepage: http://github.com/acw/time-units
+Category: Data
+Synopsis: A basic library for defining units of time as types.
+
+Description:
+  In many cases, it is useful (either for error checking or documentation
+  reasons) to define input and output types as having a particular unit of
+  time. In addition, by creating a type class defining type units, this
+  library should make it easier to separate the units of time the developer
+  wants to think in versus the units of time the library author wants to
+  think in.
+
+Library
+  Build-Depends: base >= 4.0 && < 5.0
+  Exposed-Modules: Data.Time.Units
+  Extensions: DeriveDataTypeable,GeneralizedNewtypeDeriving
+
+source-repository head
+  type: git
+  location: http://github.com/acw/time-units
+
