7

Is there something I'm missing in time conversions? Very simple example:

library(lubridate)
time <- "2019-01-14 10:58:23.438000"

op <- options(digits.secs=6)
ymd_hms(time, tz = "Europe/Helsinki")
[1] "2019-01-14 10:58:23.437 EET"

ymd_hms(time)
[1] "2019-01-14 10:58:23.437 UTC"

Why is milliseconds one off here? Doesn't seem to be rounding issue?

While this seems to work:

time <- "2019-01-14 10:58:23.123456"

op <- options(digits.secs=6)

ymd_hms(time)
[1] "2019-01-14 10:58:23.123456 UTC"

SessionInfo

sessionInfo()
R version 3.5.1 (2018-07-02)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=Finnish_Finland.1252  LC_CTYPE=Finnish_Finland.1252    LC_MONETARY=Finnish_Finland.1252 LC_NUMERIC=C                    
[5] LC_TIME=Finnish_Finland.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] lubridate_1.7.4

loaded via a namespace (and not attached):
[1] compiler_3.5.1 magrittr_1.5   tools_3.5.1    yaml_2.2.0     Rcpp_1.0.0     stringi_1.2.4  stringr_1.3.1 
Hakki
  • 1,440
  • 12
  • 26

1 Answers1

7

Edit: this answer Milliseconds in POSIXct Class addresses what is happening with POSIXct

(Note that you get rounding errors, and R's datetime formatting always rounds downwards, so if you show less decimal places it sometimes looks like you've lost a millisecond.)


The problem seems to exist with ymd_hms and also as.POSIXct.

If I call strptime directly, or use as.POSIXlt, the milliseconds parse correctly:

strptime(time, "%Y-%m-%d %H:%M:%OS", tz = "Europe/Helsinki")

as.POSIXlt(time, "%Y-%m-%d %H:%M:%OS", tz = "Europe/Helsinki")

Either of those options should fix your problem.

"2019-01-14 10:58:23.438 EET"

POSIXlt and POSIXct are behaving differently however:

as.POSIXlt(time, "%Y-%m-%d %H:%M:%OS", tz = "Europe/Helsinki") %>% 
  format(., "%Y-%m-%d %H:%M:%OS6")

[1] "2019-01-14 10:58:23.438000"

as.POSIXct(time, "%Y-%m-%d %H:%M:%OS", tz = "Europe/Helsinki") %>% 
  format(., "%Y-%m-%d %H:%M:%OS6")

[1] "2019-01-14 10:58:23.437999"
Mako212
  • 6,787
  • 1
  • 18
  • 37
  • doesn't seem that it truncates too much, as .123456 works normally to my understanding. Have to keep thinking. – Hakki Jan 25 '19 at 17:01
  • 1
    Just edited with a link to another SO question that addresses it. Although I don't know that I'm satisfied with the answer that R is rounding somewhere when provided with a definite time that should have an exact decimal representation. – Mako212 Jan 25 '19 at 17:02
  • 1
    yeah, my problem is that I'm working in tibble and it won't allow POSIXlt format. – Hakki Jan 25 '19 at 17:04
  • @Hakki also see [this answer](https://stackoverflow.com/a/9788598/4421870). It sounds like may really be a floating point issue, and unless you need accuracy beyond something like `1e-16`, it really shouldn't be a problem. – Mako212 Jan 25 '19 at 17:14