0

Consider the date:

options(digits.secs = 6)
library(lubridate)

this_special_date <- with_tz(as.POSIXct(strptime('2017-11-20 23:00:00.051438000',
                                                 '%Y-%m-%d %H:%M:%OS', tz = 'GMT')),
                             tzone='Asia/Tokyo')

Now, I can use the function myformat.POSIXct from this answer to round it to the nearest milisecond:

myformat.POSIXct <- function(x, digits=0) {
  x2 <- round(unclass(x), digits)
  attributes(x2) <- attributes(x)
  x <- as.POSIXlt(x2)
  x$sec <- round(x$sec, digits) + 10^(-digits-1)
  format.POSIXlt(x, paste("%Y-%m-%d %H:%M:%OS",digits,sep=""))
}
myformat.POSIXct(this_special_date, digits=3)

return: "2017-11-21 08:00:00.051". But how to round a POSIXct time to the next miliseconds? --i.e. in the case above it would be "2017-11-21 08:00:00.052".

user189035
  • 5,589
  • 13
  • 52
  • 112

2 Answers2

2
myceil.POSIXct <- function(x, digits=0) {
  x1 <- as.numeric(x)
  x1 <- ceiling(x1 * 10 ^ digits) / 10 ^ digits
  attributes(x1) <- attributes(x)
  x1
}

myceil.POSIXct(this_special_date, 3)
#[1] "2017-11-21 08:00:00.052 JST"
Roland
  • 127,288
  • 10
  • 191
  • 288
1

Could you add 00.0005 to all values? This would ensure that they are always rounded up relative to the starting value.

myformat.POSIXct <- function(x, digits=0) {
  x2 <- round(unclass(x + (5*10^(-digits-1))), digits)
  attributes(x2) <- attributes(x)
  x <- as.POSIXlt(x2)
  x$sec <- round(x$sec, digits) + 10^(-digits-1)
  format.POSIXlt(x, paste("%Y-%m-%d %H:%M:%OS",digits,sep=""))
}
myformat.POSIXct(this_special_date, digits=3)
David Foster
  • 447
  • 4
  • 16
  • that works for the example. But not for '2017-11-20 23:00:00.097249000' – user189035 Feb 22 '18 at 13:05
  • It does when I try it: `round(0.097249000 + 0.0005, digits = 3)` returning `[1] 0.098`. Though it won't of course work when rounding to any other number of digits, you'd have to alter the number of decimal places of the modifier also. – David Foster Feb 22 '18 at 13:18
  • if you plug '2017-11-20 23:00:00.097249000' as time string in the example above and run `myformat.POSIXct(., digits=3)` you get `"2017-11-21 08:00:00.097"` – user189035 Feb 22 '18 at 13:49
  • 1
    @user189035 Please see the above edit to see how the addition of 0.0005 (in the case of `digits = 3`) would be implemented in your code. This gives an output of `"2017-11-21 08:00:00.098"` with your example. – David Foster Feb 22 '18 at 14:04
  • thanks for your comment. I was using your answer all wrong! – user189035 Feb 22 '18 at 16:59
  • 1
    No worries, happy to clarify it :) – David Foster Feb 22 '18 at 17:16