Switch from Data.Time to Data.Thyme

[?]
Apr 19, 2015, 10:41 PM
7KZP4RHZ3QSYTPPQ257A65Z5UPX44TF2LAI2U5EMULQCLDCEUK2AC

Dependencies

  • [2] FD7SV5I6 Fix handling of event_t columns.
  • [3] WO2MINIF Auctions now compile!
  • [4] SLL7262C Make depreciation functions more flexible.
  • [5] 4IQVQL4T Added client for payouts endpoint.
  • [6] A6HKMINB Attempting to improve JSON handling.
  • [7] EQXRXRZD Changed to use tasty instead of test-framework
  • [8] GKGVYBZG Added JSON serialization to TimeLog
  • [9] A2J7B4SC Initial impl of depreciation function.
  • [10] 2KZPOGRB Once you get Haskell to compile, the tests pass!
  • [11] WZUHEZSB Start of migration back toward snap.
  • [12] XTBSG4C7 Adding serveJSON combinator to eliminate some boilerplate from handlers.
  • [13] 4QX5E5AC Initial compilation of payouts function succeeds.
  • [14] 7XN3I3QJ Add 'loggedIntervals' endpoint.
  • [15] N4NDAZYT Initial implementation of payouts.
  • [16] TNR3TEHK Switch to Postgres + snaplet arch compiles.
  • [17] 64C6AWH6 Rename Ananke -> Quixotic, project reboot.
  • [18] HE3JTXO3 Added client call to payouts.
  • [19] OBFPJS2G Project successfully builds and tests under nix.
  • [20] IZEVQF62 Work in progress replacing sqlite with postgres.
  • [21] TCOAKCGG Completed conversion to snap.
  • [22] RSEB2NFG Replacing Snap with Scotty.
  • [23] P6NR2CGX Beginning of implementation of depreciation.
  • [24] TJEUE7TY Added OverloadedStrings to eliminate Text fiddling.
  • [25] 7DBNV3GV Initial, stack-based impl of time log event reduction.
  • [26] TLQ72DSJ Lenses, sqlite-simple
  • [27] Z7KS5XHH Very WIP. Wow.
  • [28] I2KHGVD4 Require project permissions for access to most data.
  • [29] 2OIPAQCB Merge branch 'master' of github.com:nuttycom/ananke
  • [30] NMWWP4ZN Trying out Hspec
  • [31] NVOCQVAS Initial failing tests.
  • [32] BROSTG5K Beginning of modularization of server.
  • [33] Y35QCWYW Minor improvement in WorkIndex type to eliminate duplicated information.
  • [34] EMVTF2IW WIP moving back to snap.
  • [35] EZQG2APB Update task list.
  • [*] PBD7LZYQ Postgres & auth are beginning to function.

Change contents

  • edit in lib/Quixotic/Database/PostgreSQL.hs at line 10
    [3.753]
    [3.753]
    import Data.Thyme.Clock as C
    import Data.Thyme.Time
  • edit in lib/Quixotic/Database/PostgreSQL.hs at line 51
    [3.51]
    [3.1605]
    utcParser :: FieldParser C.UTCTime
    utcParser f v = toThyme <$> fromField f v
  • replacement in lib/Quixotic/Database/PostgreSQL.hs at line 57
    [3.1646][2.225:303]()
    workEventParser = WorkEvent <$> fieldWith eventTypeParser <*> field <*> field
    [3.1646]
    [3.1715]
    workEventParser = WorkEvent <$> fieldWith eventTypeParser <*> fieldWith utcParser <*> field
  • replacement in lib/Quixotic/Database/PostgreSQL.hs at line 144
    [3.3378][3.3378:3399]()
    , e ^. eventTime
    [3.3378]
    [3.3666]
    , fromThyme $ e ^. eventTime
  • replacement in lib/Quixotic/Database/PostgreSQL.hs at line 153
    [3.1920][3.1920:1951]()
    ( eid, mt ^. _ModTime, t )
    [3.1920]
    [3.1951]
    ( eid, fromThyme $ mt ^. _ModTime, fromThyme t )
  • replacement in lib/Quixotic/Database/PostgreSQL.hs at line 158
    [3.2108][3.2108:2154]()
    ( eid, mt ^. _ModTime, addr ^. _BtcAddr )
    [3.2108]
    [3.2154]
    ( eid, fromThyme $ mt ^. _ModTime, addr ^. _BtcAddr )
  • replacement in lib/Quixotic/Database/PostgreSQL.hs at line 163
    [3.2315][3.2315:2346]()
    ( eid, mt ^. _ModTime, v )
    [3.2315]
    [3.2346]
    ( eid, fromThyme $ mt ^. _ModTime, v )
  • edit in lib/Quixotic/Interval.hs at line 12
    [3.3285]
    [3.3285]
    import Data.AffineSpace
  • replacement in lib/Quixotic/Interval.hs at line 14
    [3.114][3.1494:1517](),[3.487][3.1494:1517](),[3.1747][3.1494:1517](),[3.3309][3.1494:1517](),[3.1494][3.1494:1517](),[3.1517][3.2546:2575]()
    import Data.Time.Clock
    import Data.Time.LocalTime()
    [3.3309]
    [3.1544]
    import Data.Thyme.Clock as C
    import Data.Thyme.LocalTime()
    import Data.Thyme.Format.Aeson()
  • replacement in lib/Quixotic/Interval.hs at line 18
    [3.1545][3.1748:1839]()
    data Interval = Interval { _start :: UTCTime
    , _end :: UTCTime
    [3.1545]
    [3.1634]
    data Interval = Interval { _start :: C.UTCTime
    , _end :: C.UTCTime
  • replacement in lib/Quixotic/Interval.hs at line 23
    [3.335][3.2576:2619](),[3.1682][3.2576:2619]()
    interval :: UTCTime -> UTCTime -> Interval
    [3.116]
    [3.3]
    interval :: C.UTCTime -> C.UTCTime -> Interval
  • replacement in lib/Quixotic/Interval.hs at line 26
    [3.1745][3.45:81](),[3.81][3.1888:1929]()
    ilen :: Interval -> NominalDiffTime
    ilen i = diffUTCTime (_end i) (_start i)
    [3.1745]
    [3.120]
    ilen :: Interval -> C.NominalDiffTime
    ilen i = (_end i) .-. (_start i)
  • edit in lib/Quixotic/TimeLog.hs at line 27
    [3.3656]
    [3.3855]
    import Data.AdditiveGroup
  • edit in lib/Quixotic/TimeLog.hs at line 30
    [3.5660]
    [3.65]
    import Data.AffineSpace
  • replacement in lib/Quixotic/TimeLog.hs at line 34
    [3.21][3.1028:1051](),[3.119][3.1028:1051](),[3.258][3.1028:1051](),[3.2665][3.1028:1051](),[3.1028][3.1028:1051]()
    import Data.Time.Clock
    [3.2665]
    [3.618]
    import Data.Thyme.Clock as C
    import Data.VectorSpace
  • replacement in lib/Quixotic/TimeLog.hs at line 54
    [3.4011][3.4011:4037]()
    , _eventTime :: UTCTime
    [3.4011]
    [3.3879]
    , _eventTime :: C.UTCTime
  • replacement in lib/Quixotic/TimeLog.hs at line 70
    [3.5757][3.5757:5791]()
    newtype ModTime = ModTime UTCTime
    [3.5757]
    [3.5791]
    newtype ModTime = ModTime C.UTCTime
  • replacement in lib/Quixotic/TimeLog.hs at line 73
    [3.5813][3.5813:5863]()
    data LogModification = TimeChange ModTime UTCTime
    [3.5813]
    [3.5863]
    data LogModification = TimeChange ModTime C.UTCTime
  • replacement in lib/Quixotic/TimeLog.hs at line 102
    [3.434][3.50:77]()
    type NDT = NominalDiffTime
    [3.434]
    [3.350]
    type NDT = C.NominalDiffTime
  • replacement in lib/Quixotic/TimeLog.hs at line 111
    [3.93][3.93:278](),[3.278][3.78:118]()
    The depreciation function should return a value between 0 and 1;
    this result is multiplied by the length of an interval of work to determine
    the depreciated value of the work.
    -}
    type DepF = UTCTime -> Interval -> NDT
    [3.93]
    [3.2353]
    - The depreciation function should return a value between 0 and 1;
    - this result is multiplied by the length of an interval of work to determine
    - the depreciated value of the work.
    -}
    type DepF = C.UTCTime -> Interval -> NDT
  • replacement in lib/Quixotic/TimeLog.hs at line 118
    [3.348][3.348:529](),[3.529][3.119:170]()
    Payouts are determined by computing a depreciated duration value for
    each work interval. This function computes the percentage of the total
    work allocated to each address.
    -}
    payouts :: DepF -> UTCTime -> WorkIndex -> Payouts
    [3.348]
    [3.850]
    - Given a depreciation function, the "current" time, and a foldable functor of log intervals,
    - produce the total, depreciated length of work to be credited to an address.
    -}
    workCredit :: (Functor f, Foldable f) => DepF -> C.UTCTime -> f Interval -> NDT
    workCredit depf ptime ivals = getSum $ F.foldMap (Sum . depf ptime) ivals
    {-|
    - Payouts are determined by computing a depreciated duration value for
    - each work interval. This function computes the percentage of the total
    - work allocated to each address.
    -}
    payouts :: DepF -> C.UTCTime -> WorkIndex -> Payouts
  • replacement in lib/Quixotic/TimeLog.hs at line 132
    [3.960][3.960:1052](),[3.1052][3.435:516](),[3.516][3.6767:6834]()
    addIntervalDiff total ivals = (\dt -> (dt + total, dt)) $ workCredit dep ptime ivals
    (totalTime, keyTimes) = MS.mapAccum addIntervalDiff (fromInteger 0) $ widx
    in Payouts $ fmap (\kt -> toRational $ kt / totalTime) keyTimes
    [3.960]
    [3.1011]
    addIntervalDiff total ivals = (^+^ total) &&& id $ workCredit dep ptime ivals
  • replacement in lib/Quixotic/TimeLog.hs at line 134
    [3.1012][3.1012:1016](),[3.1016][3.1200:1372](),[3.1372][3.1019:1022](),[3.1019][3.1019:1022](),[3.1022][3.171:337]()
    {-|
    Given a depreciation function, the "current" time, and a foldable functor of log intervals,
    produce the total, depreciated length of work to be credited to an address.
    -}
    workCredit :: (Functor f, Foldable f) => DepF -> UTCTime -> f Interval -> NDT
    workCredit depf ptime ivals =
    F.foldl' (+) (fromInteger 0) $ fmap (depf ptime) ivals
    [3.1012]
    [3.1581]
    (totalTime, keyTimes) = MS.mapAccum addIntervalDiff zeroV $ widx
    in Payouts $ fmap ((/ toSeconds totalTime) . toSeconds) keyTimes
  • replacement in lib/Quixotic/TimeLog.hs at line 160
    [3.57][3.57:162](),[3.162][3.338:444](),[3.444][3.261:375](),[3.261][3.261:375]()
    monthsLength :: Months -> NominalDiffTime
    monthsLength (Months i) = fromInteger $ 60 * 60 * 24 * 30 * i
    linearDepreciation :: Months -> Months -> DepF
    linearDepreciation undepPeriod depPeriod = \ptime ival ->
    let maxDepreciable :: NominalDiffTime
    maxDepreciable = monthsLength undepPeriod + monthsLength depPeriod
    [3.57]
    [3.323]
    {-|
    - A very simple linear function for calculating depreciation.
    -
    -}
    linearDepreciation :: Months -> -- ^ The number of initial months during which no depreciation occurs
    Months -> -- ^ The number of months over which each logged interval will be depreciated
    DepF
    linearDepreciation undepPeriod depPeriod =
    let monthsLength :: Months -> NDT
    monthsLength (Months i) = fromSeconds $ 60 * 60 * 24 * 30 * i
  • replacement in lib/Quixotic/TimeLog.hs at line 171
    [3.324][3.324:389]()
    zeroTime :: NominalDiffTime
    zeroTime = fromInteger 0
    [3.324]
    [3.970]
    maxDepreciable :: NDT
    maxDepreciable = monthsLength undepPeriod ^+^ monthsLength depPeriod
  • replacement in lib/Quixotic/TimeLog.hs at line 174
    [3.971][3.445:489]()
    depPct :: NominalDiffTime -> Rational
    [3.971]
    [3.489]
    depPct :: NDT -> Rational
  • replacement in lib/Quixotic/TimeLog.hs at line 177
    [3.556][3.497:586](),[3.497][3.497:586]()
    else toRational (max zeroTime (maxDepreciable - dt)) / toRational maxDepreciable
    [3.556]
    [3.557]
    else toSeconds (max zeroV (maxDepreciable ^-^ dt)) / toSeconds maxDepreciable
  • replacement in lib/Quixotic/TimeLog.hs at line 179
    [3.558][3.2563:2687]()
    depreciation = depPct $ diffUTCTime ptime (ival ^. end)
    in fromRational $ depreciation * (toRational $ ilen ival)
    [3.558]
    in \ptime ival ->
    let depreciation = depPct $ ptime .-. (ival ^. end)
    in depreciation *^ (ilen ival)
  • replacement in quixotic.cabal at line 50
    [3.1981][3.1981:2029]()
    , time >= 1.4.2 && < 1.5
    [3.1981]
    [3.2029]
    , thyme >= 0.3.5
  • edit in quixotic.cabal at line 55
    [37.1200]
    [3.1070]
    , vector-space
  • edit in quixotic.cabal at line 71
    [3.2159]
    [3.3090]
    , QuickCheck >= 2.7
  • replacement in quixotic.cabal at line 78
    [3.2199][3.2199:2210]()
    , time
    [3.2199]
    [3.3130]
    , thyme
  • edit in quixotic.cabal at line 81
    [3.2231]
    [3.1706]
    , vector-space
  • replacement in quixotic.cabal at line 104
    [3.233][3.233:244]()
    , time
    [3.233]
    [3.73]
    , thyme
  • replacement in quixotic.cabal at line 136
    [3.3567][3.3567:3578]()
    , time
    [3.3567]
    [3.3578]
    , thyme
  • edit in server/Quixotic/Snaplet/WorkLog.hs at line 8
    [3.5625]
    [3.5641]
    import Data.Thyme.Clock as C
  • replacement in server/Quixotic/Snaplet/WorkLog.hs at line 28
    [3.4361][3.6005:6042](),[3.6005][3.6005:6042]()
    timestamp <- liftIO getCurrentTime
    [3.4361]
    [2.550]
    timestamp <- liftIO C.getCurrentTime
  • replacement in server/Quixotic/Snaplet/WorkLog.hs at line 48
    [3.3780][3.6744:6779](),[3.6744][3.6744:6779]()
    ptime <- liftIO $ getCurrentTime
    [3.3780]
    [3.1705]
    ptime <- liftIO $ C.getCurrentTime
  • edit in test/Quixotic/TimeLogSpec.hs at line 2
    [3.1658]
    [3.148]
    {-# OPTIONS_GHC -Wwarn -fno-warn-orphans #-}
  • edit in test/Quixotic/TimeLogSpec.hs at line 13
    [3.270]
    [3.201]
    import Data.AffineSpace
  • edit in test/Quixotic/TimeLogSpec.hs at line 16
    [3.357]
    [3.2088]
    import Data.Thyme.Clock
    import Data.Thyme.Time
    import qualified Data.Text as T
    import Test.QuickCheck
    instance Arbitrary EventType where
    arbitrary = elements [StartWork, StopWork]
    newtype EventLog = EventLog [LogEntry]
    instance Arbitrary BtcAddr where
    arbitrary = BtcAddr . T.pack <$> vectorOf 34 arbitrary
  • edit in test/Quixotic/TimeLogSpec.hs at line 29
    [3.2089]
    [3.358]
    instance Arbitrary Interval where
    arbitrary = do
    start <- arbitrary
    delta <- arbitrary
    pure $ I.interval start (start .+^ delta)
  • replacement in test/Quixotic/TimeLogSpec.hs at line 43
    [3.4127][3.619:761]()
    starts = catMaybes [ parseISO8601 "2014-01-01T00:08:00Z"
    , parseISO8601 "2014-02-12T00:12:00Z" ]
    [3.4127]
    [3.4253]
    starts = toThyme <$> catMaybes [ parseISO8601 "2014-01-01T00:08:00Z"
    , parseISO8601 "2014-02-12T00:12:00Z" ]
  • replacement in test/Quixotic/TimeLogSpec.hs at line 46
    [3.4254][3.762:904]()
    ends = catMaybes [ parseISO8601 "2014-01-01T00:12:00Z"
    , parseISO8601 "2014-02-12T00:18:00Z" ]
    [3.4254]
    [3.2686]
    ends = toThyme <$> catMaybes [ parseISO8601 "2014-01-01T00:12:00Z"
    , parseISO8601 "2014-02-12T00:18:00Z" ]
  • edit in test/Quixotic/TimeLogSpec.hs at line 68
    [3.4083]
    [3.974]
    describe "EventType serialization" $ do
    it "serialization is invertible" $ property $
    \e -> (nameEvent . eventName) e == Just e