5

I am having an issue with my time stamp management. In my dataset I have two variables, namely, Time and Relative Time. Time is in HH:MM:SS.ss format while relative time is numeric variable containing amount of seconds passed since 0 (i.e. 0.76, 1.28, 1.78, 2.38 ... ). For simplicities sake lets consider the hypothetical situation:

Time <- c("09:33:23.00", "09:35:25.00", "09:36:26.00")
RTime <- c(0.78, 1.28, 3.98)

Then I do the following to add the milliseconds to the time:

ATime <- strftime(strptime(Time,format="%H:%M:%OS")+(RTime %% 1),format="%H:%M:%OS2")

I would like it to result in:
"09:33:23.78" "09:35:25.28" "09:36:26.98"

But instead I get the following:
"09:33:23.77" "09:35:25.27" "09:36:26.98"

Its only one millisecond off most of the time. And i don't understand why its doing that. I could add 0.01 in the strptime function, i.e. (RTime %% 1) + 0.01. But I don't find that very elegant and more importantly, as you can see in the above example, its not always 0.01 off - as with the last case. Any hints as to what is happening, or perhaps suggestions to improve code?

Cheers

[SOLVED]
EDIT: For the interested. This is how I eventually solved my problem:

ATime <- strftime(strptime(Time,format="%H:%M:%OS")+(RTime %% 1)+0.005,format="%H:%M:%OS2")

This 'forces' the rounding instead of truncating which leads to the difference in milliseconds.
Thanks to @Josh O'Brien and @nrussell for their comments!

tstev
  • 607
  • 1
  • 10
  • 20
  • 2
    I believe this (at least the part about *why* it's happening) is [answered here](http://stackoverflow.com/q/8889554/980833) – Josh O'Brien Feb 03 '15 at 16:23
  • 2
    Not a solution to your problem, but I think the issue is explained in the `strptime` helpfile, about 70% down from the top (2 paragraphs after the `% V` passage: `Note that %S ignores (and not rounds) fractional parts on output.`. You can see this by doing `strftime(strptime(Time,format="%H:%M:%OS")+(RTime %% 1),format="%H:%M:%OS3")` – nrussell Feb 03 '15 at 16:24
  • Thanks! To be honest, half hour posting my question, i found this [link](https://stat.ethz.ch/pipermail/r-devel/2012-May/064211.html). Before posting I had tried very hard to find an answer, but I wasn't getting anywhere. So a bit embarrassing :P. Thanks a lot for the comments! At least I know why now. – tstev Feb 03 '15 at 17:16
  • 1
    @tstev -- And if my experience is any guide, that's not a coincidence! At least half the time I've written a question up here, I *finally* figure out the answer myself while/because I'm doing the writing. Cheers. – Josh O'Brien Feb 03 '15 at 17:37
  • 1
    http://stackoverflow.com/q/7726034/210673 and http://stackoverflow.com/q/15383057/210673 may also be of interest – Aaron left Stack Overflow Feb 03 '15 at 17:37
  • @Aaron - Thanks for the links, they are indeed very useful links. Cheers. – tstev Feb 04 '15 at 10:30

1 Answers1

3

As explained here (and by @nrussel in comments above) this is caused by strftime()'s truncation (not rounding!) of the machine's slightly imprecise floating point representation of fractional seconds.

As a perhaps slightly kludgy fix, you could write a small printing function that adds a very small value -- greater than .Machine$double.eps but less than .01 -- to each time value before printing it.

strftime2 <- function(x, ...) {
    strftime(x + 1e-6, ...)
}

## Compare results
strftime(strptime(Time,format="%H:%M:%OS")+(RTime %% 1),format="%H:%M:%OS2")
# [1] "09:33:23.77" "09:35:25.27" "09:36:26.98"
strftime2(strptime(Time,format="%H:%M:%OS")+(RTime %% 1),format="%H:%M:%OS2")
# [1] "09:33:23.78" "09:35:25.28" "09:36:26.98"
Community
  • 1
  • 1
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • Thanks a lot for the solution! Its also what I eventually found - people suggested force rounding by adding 0.005 for example. Appreciate the comments! – tstev Feb 03 '15 at 17:18