如何获取高精度系统时间?实现Erlang与Haskell时间格式统一
让Haskell获取与Erlang格式一致的高精度系统时间
Erlang的:os.system_time()默认返回的是从UNIX纪元(1970-01-01 UTC)开始的总纳秒数(也就是你看到的19位整数),而Haskell的SystemTime是把时间拆成了纪元以来的秒数,加上当前秒内的纳秒数分开存储。要得到和Erlang完全一致的格式,只需要把这两部分合并成总纳秒数就行。
具体实现方法
你已经在使用getSystemTime获取SystemTime类型的值,我们可以写一个简单的函数把它转换成总纳秒数:
import System.Time (SystemTime(..), getSystemTime) -- 获取和Erlang :os.system_time()格式一致的纳秒级时间戳 getNanoTimestamp :: IO Integer getNanoTimestamp = do SystemTime epochSecs secNanos <- getSystemTime -- 把秒数转换成纳秒,加上当前秒内的纳秒数 return $ epochSecs * 1000000000 + toInteger secNanos
代码说明
epochSecs是纪元以来的总秒数(对应你打印的systemSeconds a1),乘以1e9转换成纳秒;secNanos是当前秒内的纳秒数(对应systemNanoseconds a1),因为它是Int类型,所以用toInteger转成整数避免溢出;- 两者相加后得到的就是和Erlang完全一致的19位纳秒级时间戳。
测试验证
调用这个函数就能看到符合预期的结果:
main :: IO () main = do nanoTs <- getNanoTimestamp print nanoTs -- 输出类似1583756142069346000的19位整数
补充:用现代time包的替代方案
如果你使用的是较新版本的time包(>=1.9),也可以用getPOSIXTime直接获取POSIX时间,再转换成纳秒:
import Data.Time.Clock.POSIX (getPOSIXTime) import Data.Int (Int64) getNanoTimestamp' :: IO Int64 getNanoTimestamp' = do posixTime <- getPOSIXTime return $ floor $ posixTime * 1000000000
另外你提到两次取的时间数值差异大,是因为Erlang和Haskell的时间不是同一时刻获取的,合并后的格式一致后,同一时刻取的数值就会匹配了。
内容的提问来源于stack exchange,提问作者Jorshurau
相关产品推荐
相关产品推荐

