Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R lubridate ymd_hms millisecond diff

Tags:

r

lubridate

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 
like image 493
Hakki Avatar asked Jan 25 '19 16:01

Hakki


1 Answers

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"
like image 51
Mako212 Avatar answered Oct 01 '22 22:10

Mako212