【问题标题】:Comparing nanosecond precision timestamps in R比较 R 中的纳秒精度时间戳
【发布时间】:2017-04-22 09:20:42
【问题描述】:

虽然这是一个非常常见的实用程序,可能很多人都需要,但奇怪的是,谷歌没有向我显示任何匹配的答案。 我有一个时间戳,格式为 HH:MM:SS.NANOSECONDPRECISION 秒后 9 位。我在 R 中有 2 个这样的列,我需要找出差异。我无法找到如何使用 POSIX 将此类字符时间戳转换为可比较的数字。

发送时间 - 11:20:30.791372292 接收时间 11:20:30.791382216 找到这两个时间戳之间差异的好方法是什么

【问题讨论】:

  • 已经投了反对票。请评论原因
  • 我没有投票,但请分享此类时间戳的可重现示例。由于浮点精度,您绝对不能使用POSIXct,而且我对POSIXlt 也有疑问。您可能需要通过从字符输入中提取这些来进行亚秒级比较。
  • POSIXlt 实际上使用 same representation 作为 POSIXct:两者都精确到 53 位,因此大约是 16 位。我们在这里需要更多。一个基于 integer64 的纳秒表示,因为纪元可以做到这一点。

标签: r timestamp


【解决方案1】:

我即将向 CRAN 发布一个包,您可以使用 currently get from GitHub 来处理这个问题,它几乎按照 @roland 建议的方式处理这个问题——作为 S3 扩展(围绕包 bit64RcppCCTZ

以你为例:

R> sentt <- nanotime("2016-12-21T11:20:30.791372292+00:00")
R> receivet <- nanotime("2016-12-21T11:20:30.791382216+00:00")
R> format(c(sentt, receivet))
[1] "1482319230791372292" "1482319230791382216"
R> format(sentt)
[1] "2016-12-21T11:20:30.791372292+00:00"
R> format(receivet)
[1] "2016-12-21T11:20:30.791382216+00:00"
R> receivet-sentt
integer64
[1] 9924
R> 

我(目前)使用固定格式进行解析,这很容易概括。我还需要添加一个日期(因为你永远不能只用时间解析日期时间,它是不确定的)并且由于解析字符串的原因添加了一个 TZ 偏移量为 0。

我们发现两个时间戳之间有 9924 纳秒,也就是 9.924 微秒。在我的行业中,这听起来像是一个即时交易指标:)

【讨论】:

    【解决方案2】:

    我会单独处理亚秒:

    times <- c("11:20:30.791372292", "11:20:30.791382216")
    
    library(chron)
    
    fulltimes <- round(as.numeric(times(times)) * 24 * 3600)
    subtimes <- as.numeric(gsub(".+(?=\\.)", "0", times, perl = TRUE))
    
    #difference
    sprintf("%.9f", fulltimes[2] - fulltimes[1] + subtimes[2] - subtimes[1])
    #[1] "0.000009924"
    

    您可以使用这种亚秒级处理和适当的 S3 方法轻松创建一个扩展 chron 的 S3 类。

    【讨论】:

      【解决方案3】:

      只要可以安全地假设您的时间总是在同一日期,以下将起作用。它每次都重新计算自一天开始以来发生的纳秒数。它假定使用 24 小时时间。

      sent_time <- "11:20:30.791372292"
      receive_time <- "11:20:30.791382216"
      
      convert_nano <- function(x){
        require(magrittr)
        split <- 
          #* split up the time components
          strsplit(x, ":") %>%
          #* convert strings to numerics
          lapply(as.numeric) %>%
          #* convert each component to nanoseconds
          vapply(function(s) sum(s * c(3600, 60, 1) * 10 ^ 9),
                 numeric(1))
      }
      
      convert_nano(receive_time) - convert_nano(sent_time)
      

      如果您会遇到发生在不同日期的时间,您可能会采取类似的方法,但可能需要考虑可能介于两次之间的天数上限。如果你得到两个多天,你将无法充分表示纳秒。

      【讨论】:

        猜你喜欢
        • 2023-03-17
        • 2023-04-07
        • 2023-02-10
        • 2015-02-27
        • 2019-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多