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!
Asked
Active
Viewed 1,844 times
5

tstev
- 607
- 1
- 10
- 20
-
2I 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
-
2Not 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
-
1http://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 Answers
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