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