# Time with millisecond precision

**URL:** <https://forum.canton.network/t/time-with-millisecond-precision/314>\
**Category:** App Development\
**Created:** [May 1, 2020, 11:28am UTC](https://forum.canton.network/t/time-with-millisecond-precision/314 "2020-05-01T11:28:17Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![georg](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/georg/32/368_2.png) [@georg](https://forum.canton.network/u/georg)\
**Post date:** [May 1, 2020, 11:28am UTC](https://forum.canton.network/t/time-with-millisecond-precision/314/1 "2020-05-01T11:28:17Z")

</div>

I noticed that the `Time` type only supports resolution to the second. What’s the rationale to limiting this and is the suggested approach here to define my own type if I need higher resolution? Or is there another type I didn’t see?

---

<div class="post-metadata">

**Author:** ![Stephen](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/stephen/32/102_2.png) [@Stephen](https://forum.canton.network/u/Stephen)\
**Post date:** [May 1, 2020, 9:58pm UTC](https://forum.canton.network/t/time-with-millisecond-precision/314/2 "2020-05-01T21:58:46Z")

</div>

Since `Time` is directly based on a primitive built-in LF type, it’s generally better for the stability and compatibility of future changes to be as conservative as possible with regard to what’s allowed.

The question of what `Time` supports is really one of “what is needed of a _primitive_ LF time construct?”, rather than “what features of time might be useful in applications?”, so the best approach is certainly to define your own type if you have different requirements.

---

<div class="post-metadata">

**Author:** ![bernhard](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/bernhard/32/356_2.png) [@bernhard](https://forum.canton.network/u/bernhard)\
**Post date:** [May 29, 2020, 7:28am UTC](https://forum.canton.network/t/time-with-millisecond-precision/314/3 "2020-05-29T07:28:47Z")

</div>

`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:

```haskell
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)

```

---

<div class="post-metadata">

**Author:** ![georg](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/georg/32/368_2.png) [@georg](https://forum.canton.network/u/georg)\
**Post date:** [May 29, 2020, 7:57am UTC](https://forum.canton.network/t/time-with-millisecond-precision/314/4 "2020-05-29T07:57:51Z")

</div>

Thanks for the clarification @bernhard. This is certainly not clear from the docs, nothing there indicates that `Time` in fact does have microsecond resolution. Maybe some more helper functions in the stdlib would make this more user-friendly.

---

<div class="post-metadata">

**Author:** ![gtpaulose2](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/gtpaulose2/32/4237_2.png) [@gtpaulose2](https://forum.canton.network/u/gtpaulose2)\
**Post date:** [September 20, 2022, 4:22pm UTC](https://forum.canton.network/t/time-with-millisecond-precision/314/5 "2022-09-20T16:22:52Z")

</div>

> [@bernhard](#):
>
> `relTimeSinceEpochUTC `

Is there a reason why the above functions aren’t in a standard lib? I would have thought the ability to convert time to it’s corresponding epoch time would be less verbose then defining (at minimum),  
`epoch ` and `relTimeSinceEpochUTC (t : Time) : RelTime`

Of course omitting timezone

---

<div class="post-metadata">

**Author:** ![bernhard](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/bernhard/32/356_2.png) [@bernhard](https://forum.canton.network/u/bernhard)\
**Post date:** [September 21, 2022, 8:33am UTC](https://forum.canton.network/t/time-with-millisecond-precision/314/6 "2022-09-21T08:33:26Z")

</div>

> [@gtpaulose2](#):
>
> Is there a reason why the above functions aren’t in a standard lib? I

Yes, we don’t want to lead developers to try to work with time at microsecond precision as that precision leads to an illusion of accuracy. Time in a distributed system is a fuzzy concept and that is true for the time you get from `getTime` as well. While it has microsecond _precision_, it’s only _accurate_ to a within a few seconds or even minutes. Its accuracy is determined by the skew parameters [documented here](https://docs.daml.com/concepts/time.html#ledger-time).  
That documentation section also explains that within that window defined by the skew parameters, the submitting participant has some freedom in choosing the ledger time returned by `getTime`.

To stop developers falling into the trap of trying to use microsecond time for random number generation, or relying on the relative timings of events at that level or precision, we made it convenient to work with time at second and minute precision, but included no helpers for anything more precise.

---

<div class="post-metadata">

**Author:** ![gtpaulose2](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/gtpaulose2/32/4237_2.png) [@gtpaulose2](https://forum.canton.network/u/gtpaulose2)\
**Post date:** [September 21, 2022, 10:12am UTC](https://forum.canton.network/t/time-with-millisecond-precision/314/7 "2022-09-21T10:12:29Z")

</div>

Fair enough, that makes sense. Thank you
