从DA.Time中存储和检索微秒

时间:2019-05-13 07:30:14

标签: daml

我正在使用FIX时间戳20180605-03:10:33.0240756进行解析,我需要将其解析为DA.Time才能继续作为交易信息的一部分。我还需要将微秒返回作为响应消息(ACK / NACK)的一部分。

理想情况下,我想有一种简单的方法。

当前,我仅使用DA.Time时间构造函数存储最多几秒钟的时间。 看着https://docs.daml.com/daml/stdlib/base.html#data-prelude-time-24894,看来检索微秒的方法是:

  1. 创建另一个时间(以微秒为单位)
  2. subTime都可以得到RelTime
  3. microseconds中致电RelTime

如果有更好的解决方法,请告知这是否正确。谢谢。

1 个答案:

答案 0 :(得分:0)

在通常情况下,我建议对字符串进行分类解析,并以DateTime类型的形式传递日期和时间,但是听起来您需要在以下情况下执行此操作: DAML中的分类帐。

您的第一个问题涉及将字符串解析为DA.Time。当前没有内置的通用日期/时间解析功能,因此您必须自己构建。对于像您这样的固定格式,模式匹配使操作变得非常简单:

daml 1.2
module ParseTime where

import DA.Assert
import DA.Optional
import DA.Text
import DA.Time
import DA.Date

-- | `parseUTC` takes a string in the format "yyyyMMdd-HHmmss.SSS"
-- and converts it to `Time`, assuming the time is in UTC
-- Time is truncated to whole microseconds.
parseDateTimeUTC utc = datetime yy mon dd h m s `addRelTime` micros
  where
    -- Split out the micro seconds to stay under
    -- pattern match complexity limit
    [dt, ms] = splitOn "." utc
    -- Pattern match on `explode` to check
    -- the format and assign names to characters
    [ y1, y2, y3, y4, mon1, mon2, d1, d2, "-",
      h1, h2, ":", m1, m2, ":", s1, s2
      ] = explode dt
    -- The function will fail on `fromSome` if any of the
    -- integer strings don't parse
    unsafeParse = fromSome . parseInt . implode
    -- Map the parse function over grouped characters and
    -- pattern match the result to give names to the Ints
    [yy, imon, dd, h, m, s, imic] = map unsafeParse
      [[y1, y2, y3, y4], [mon1, mon2], [d1, d2],
      [h1, h2], [m1, m2], [s1, s2], explode $ T.take 6 ms]
    -- Process month and microseconds into `Month` and
    -- `Reltime` types
    mon = toEnum $ imon - 1
    mic = 10 ^ (max 0 (6 - T.length ms)) * imic
    micros = convertMicrosecondsToRelTime mic

t = scenario do
  let t = time (date 2018 Jun 05) 03 10 33 `addRelTime` convertMicrosecondsToRelTime 24075
  parseDateTimeUTC "20180605-03:10:33.0240756" === t

要在DA.Time和微秒之间转换,我们需要在时区上进行选择。假设使用UTC,我们可以定义

epochUTC = datetime 1970 Jan 1 0 0 0
microToTimeUTC n = epoch `addRelTime` convertMicrosecondsToRelTime n
timeToMicroUTC t = convertRelTimeToMicroseconds $ t `subTime` epoch

t2 = scenario do
  microToTimeUTC 1557733583000000 === datetime 2019 May 13 07 46 23
  timeToMicroUTC (datetime 2019 May 13 07 46 23) === 1557733583000000

在日期的DA.TimeInt表示之间转换。

如果要使用现有DA.Time的微秒分量,则只需要微秒表示的最后六位:

micros t = timeToMicroUTC t % 1000000

t3 = scenario do
  micros (parseDateTimeUTC "20180605-03:10:33.0240756") === 24075

请注意此处的截断时间为整微秒,parseDateTimeUTC的说明中也提到了这一点。