Reputation: 2146
Although this is a pretty common utility which might be required by many, but strangely google does not show me any matching answers.
I have a time stamp which in the format HH:MM:SS.NANOSECONDPRECISION
9digits after seconds. I have 2 such columns in R and I need to find the difference. I am unable to find how using POSIX we can convert such character time stamps to comparable numbers .
Sent time - 11:20:30.791372292 Receive time 11:20:30.791382216 What's a good way to find difference between these 2 time stamps
Upvotes: 1
Views: 1046
Reputation: 368191
I am about to release a package to CRAN which you can currently get from GitHub which deals with this pretty much in the way suggested by @roland -- as an S3 extension (around packages bit64 and RcppCCTZ.
To take your example:
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>
I (currently) use a fixed format for parsing, this is easy to generalize. I also needed to add a date (as you can never parse datetime only with times, it is indeterminate) and for the parse string reason added a TZ offet of 0.
With that we find 9924 nsec aka 9.924 microsec between the two timestamps. In my industry that sounds like a tick-to-trade metric :)
Upvotes: 6
Reputation: 132651
I'd handle the subseconds separately:
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"
You can easily create an S3 class extending chron with this subsecond handling and appropriate S3 methods.
Upvotes: 0
Reputation: 17369
As long as it is safe to assume that your times are always on the same date, the following will work. It recalculates each time as the number of nanoseconds occurring since the start of the day. It assumes using 24 hours time.
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)
If you will encounter times occurring on different days, you may take a similar approach, but may want to consider an upper limit to the number of days that may be between two times. If you get two many days, you won't be able to represent nanoseconds adequately.
Upvotes: 2