When parsing strings to POSIXct the default resolution is seconds. Consider a timestamp with second resolution:
(t1 <- as.POSIXct("2020-02-29 12:34:56", format = "%Y-%m-%d %H:%M:%S", tz = "UTC"))
## [1] "2020-02-29 12:34:56 UTC"
Another timestamp that also includes milliseconds is here parsed with only the integer part of the second (by the %S part of the format argument):
(t2 <- as.POSIXct("2020-02-29 12:34:56.123", format = "%Y-%m-%d %H:%M:%S", tz = "UTC"))
## [1] "2020-02-29 12:34:56 UTC"
We can check that they are indeed equal
t1 - t2
## Time difference of 0 secs
Sub-second parsing
We can parse the timestamp with the milliseconds by changing the format slightly (%OS instead of %S for the seconds). However, the parsed timestamp is printed just like above:
(t3 <- as.POSIXct("2020-02-29 12:34:56.123", format = "%Y-%m-%d %H:%M:%OS", tz = "UTC"))
## [1] "2020-02-29 12:34:56 UTC"
However, there is a difference now:
t1 - t3
## Time difference of -0.1229999 secs
We can make this apparent by changing the option that controls printing timestamps:
withr::with_options(list("digits.secs" = 3), print(t3))
## [1] "2020-02-29 12:34:56.122 UTC"