Time with millisecond precision

Time and RelTime in DAML are stored to microsecond precision, and there is a function convertRelTimeToMicroseconds to extract the microseconds from RelTime. If we ignore time zones, you can then write the following functions:

module Main where

import DA.Assert
import DA.Time
import DA.Date

epoch : Time = datetime 1970 Jan 1 0 0 0

microsInSecond : Int = 1000000
microsInMinute : Int = 60 * microsInSecond
microsInHour : Int = 60 * microsInMinute
microsInDay : Int = 24 * microsInHour

relTimeSinceEpochUTC (t : Time) : RelTime = 
  subTime t epoch

timeToMicrosSinceEpochUTC = 
  convertRelTimeToMicroseconds . relTimeSinceEpochUTC

wholeHours (r : RelTime) = 
  ((convertRelTimeToMicroseconds r) % microsInDay) / microsInHour

wholeMinutes (r : RelTime) = 
  ((convertRelTimeToMicroseconds r) % microsInHour) / microsInMinute

wholeSeconds (r : RelTime) = 
  ((convertRelTimeToMicroseconds r) % microsInMinute) / microsInSecond

remainingMicros (r : RelTime) = 
  (convertRelTimeToMicroseconds r) % microsInSecond

decomposeDateTime (t : Time) : (Int, Month, Int, Int, Int, Int, Int) =
  ( y, mon, d, h, min, s, micros)
  where
    (y, mon, d) = toGregorian (toDateUTC t)
    r = relTimeSinceEpochUTC t
    h = wholeHours r
    min = wholeMinutes r
    s = wholeSeconds r
    micros = remainingMicros r

template Timer
  with
    p : Party
  where
    signatory p
    controller p can
      GetTime : Time
        do
          getTime

deriving instance Show (Int, Month, Int, Int, Int, Int, Int)

setup = scenario do
  p <- getParty "p"

  cid <- submit p do
    create Timer with ..

  pass (convertMicrosecondsToRelTime 1590736235123456)

  submit p do
    decomposedTime <- decomposeDateTime <$> exercise cid GetTime
    assertEq decomposedTime (2020, May, 29, 7, 10, 35, 123456)
5 Likes