从 DA.Time 存储和检索微秒
Storing and retrieving microseconds from DA.Time
我正在使用 FIX 时间戳 20180605-03:10:33.0240756
,我需要将其解析为 DA.Time
以作为贸易信息的一部分保留下来。我还需要将微秒作为响应消息的一部分返回 (ACK/NACK)。
理想情况下,我希望有一种简单的方法来做到这一点。
目前我使用 DA.Time 时间构造函数最多只能存储几秒钟。
查看 https://docs.daml.com/daml/stdlib/base.html#data-prelude-time-24894,似乎检索微秒的方法是:
- 创造另一个没有微秒的时间
subTime
两者都得到 RelTime
- 在
RelTime
中调用 microseconds
如果有更好的方法,请告知这是否正确。谢谢。
在通常情况下,我建议进行字符串解析 off-ledger 并将日期和时间作为 Date
和 Time
类型传递,但听起来您有这样的要求在 DAML 中执行 on-ledger。
您的第一个问题涉及将字符串解析为 DA.Time
。目前没有内置的通用 date/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.Time
和 Int
日期表示之间转换。
如果您想要现有 DA.Time
的微秒部分,您只需要微秒表示的最后六位数字:
micros t = timeToMicroUTC t % 1000000
t3 = scenario do
micros (parseDateTimeUTC "20180605-03:10:33.0240756") === 24075
注意此处截断为整微秒,parseDateTimeUTC
的描述中也提到了这一点。
我正在使用 FIX 时间戳 20180605-03:10:33.0240756
,我需要将其解析为 DA.Time
以作为贸易信息的一部分保留下来。我还需要将微秒作为响应消息的一部分返回 (ACK/NACK)。
理想情况下,我希望有一种简单的方法来做到这一点。
目前我使用 DA.Time 时间构造函数最多只能存储几秒钟。 查看 https://docs.daml.com/daml/stdlib/base.html#data-prelude-time-24894,似乎检索微秒的方法是:
- 创造另一个没有微秒的时间
subTime
两者都得到RelTime
- 在
RelTime
中调用
microseconds
如果有更好的方法,请告知这是否正确。谢谢。
在通常情况下,我建议进行字符串解析 off-ledger 并将日期和时间作为 Date
和 Time
类型传递,但听起来您有这样的要求在 DAML 中执行 on-ledger。
您的第一个问题涉及将字符串解析为 DA.Time
。目前没有内置的通用 date/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.Time
和 Int
日期表示之间转换。
如果您想要现有 DA.Time
的微秒部分,您只需要微秒表示的最后六位数字:
micros t = timeToMicroUTC t % 1000000
t3 = scenario do
micros (parseDateTimeUTC "20180605-03:10:33.0240756") === 24075
注意此处截断为整微秒,parseDateTimeUTC
的描述中也提到了这一点。