You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@arrow.apache.org by "sorhawell (via GitHub)" <gi...@apache.org> on 2023/12/07 21:29:29 UTC
Re: [I] [R] Microsecond is not sufficient unit for POSIXct [arrow]
sorhawell commented on issue #32693:
URL: https://github.com/apache/arrow/issues/32693#issuecomment-1846140077
Floats have a variable precision which is the greatest around `0` and decreases towards higher values. R integer is something close to i32 which has a very inferior range. R never really adopted i64/u64 and chose instead to use the Real ~ f64 is a substitute for i64/u64.
However f64 has a bound to where it behaves "integerish" because floating point space is less than 1. Above and below this bound, the f64 cannot unambiguously represent each integer value.
Since picking origin 1970-1-1 and working with datetime around 2024 as of this writing it not possible to use `ns`. It became impossible after the 4th Jan 1970.
The `us` will become ambiguous for dates after year 2112(rlang) 2225(practical limit). rlang limit matters as a lot packages uses integerish to clip values out of bound.
See more details on integerish bounds here: https://github.com/r-lib/rlang/pull/1530
``` r
rlang::is_integerish(2^52) # last number with full precision according to rlang
#> [1] TRUE
rlang::is_integerish(2^52+1) # last number with full precision according to rlang
#> [1] FALSE
rlang::is_integerish(2^53-1) # however 2^53-1 is last full precision value in practice
#> [1] FALSE
# but lang choose to match length "long-vectors" see https://github.com/r-lib/rlang/pull/1530
#seconds since
since_origin_in = floor(c(s = as.numeric(Sys.time())))
since_origin_in["ms"] = floor(since_origin_in["s"]*1E3)
since_origin_in["us"] = floor(since_origin_in["s"]*1E6)
since_origin_in["ns"] = floor(since_origin_in["s"]*1E9)
# has today full precision
print(sapply(since_origin_in,rlang::is_integerish))
#> s ms us ns
#> TRUE TRUE TRUE FALSE
#last day with full precisions according to rlang
as.POSIXct( 2^52 * c(s = 1, ms = 1E-3, us = 1E-6, ns = 1E-9), origin = "1970-1-1")
#> s ms
#> "142715360-12-06 04:48:16 CET" "144683-05-23 18:29:30 CEST"
#> us ns
#> "2112-09-18 01:53:47 CEST" "1970-02-22 03:59:59 CET"
#last day with full precisions according in practice
as.POSIXct( (2^53-1) * c(s = 1, ms = 1E-3, us = 1E-6, ns = 1E-9), origin = "1970-1-1")
#> s ms
#> "285428751-11-12 08:36:31 CET" "287396-10-12 10:59:00 CEST"
#> us ns
#> "2255-06-06 01:47:34 CEST" "1970-04-15 06:59:59 CET"
```
<sup>Created on 2023-12-07 with [reprex v2.0.2](https://reprex.tidyverse.org)</sup>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org