[Rd] Revisit c.POSIXlt , [<-.POSIXlt , [[<-.POSIXlt ?
Suharto Anggono Suharto Anggono
@uh@rto_@nggono @end|ng |rom y@hoo@com
Sun Jun 14 15:37:13 CEST 2026
Could at least a minimalistic fix be put for the upcoming R 4.6.1? For example:
ln '[<-.POSIXlt' and '[[<-.POSIXlt', change
else as.POSIXlt(as.POSIXct(value), tz = tz[1L]))
to
else as.POSIXlt(as.POSIXct(value), tz = if(is.null(tz)) "" else tz[1L]))
In 'c.POSIXlt', apply 'floor' to the 'sec' component before converting to POSIXct like in Bug 18989 Comment 9 (https://bugs.r-project.org/show_bug.cgi?id=18989#c9).
______
On Friday, 17 April 2026 at 02:13:48 pm GMT+7, Suharto Anggono Suharto Anggono <suharto_anggono using yahoo.com> wrote:
One more thing.
A POSIXlt object without 'tzone' attribute (attr(*, "tzone") is NULL) is valid.
If 'x' is a POSIXct object,
as.POSIXlt(x, tz = NULL)
uses 'tzone' attribute of 'x', same as
as.POSIXlt(x) .
So, with current '[<-.POSIXlt' in R devel and R 4.6.0 RC, subassigning a POSIXct object without 'tzone' attribute to a POSIXlt object without 'tzone' attribute gives error. For example,
x1 <- as.POSIXlt(Sys.time()); attr(x1, "tzone") <- NULL
x1[1L] <- Sys.time()
Additionally, after
x1 <- as.POSIXlt(Sys.time()); attr(x1, "tzone") <- NULL; x2 <- x1
y1 <- as.POSIXlt(.POSIXct(0, tz = "UTC"))
y2 <- as.POSIXlt(.POSIXct(0, tz = "America/Toronto"))
x1[1L] <- y1
x2[1L] <- y2
, either
x1[1L] - y1
or
x2[1L] - y2
(or both) is not 0.
The script datetime3_lt_subsec.R doesn't use `c`. Also, if 'x' is a POSIXlt object,
x[i] <- val
or
x[[i]] <- val
in R devel is different from R 4.5.3 only when 'val' is not a POSIXlt object with identical 'tzone' attribute as 'x'.
No, such a NEWS item should be for R 4.6.0. The porting of time zone reconciliation in '[<-.POSIXlt' and '[<-.POSIXlt' has been removed from R-4-5-branch.
--------
On Friday, 10 April 2026 at 09:58:25 pm GMT+7, Martin Maechler <maechler using stat.math.ethz.ch> wrote:
>>>>> Suharto Anggono Suharto Anggono via R-devel
>>>>> on Tue, 7 Apr 2026 10:34:46 +0000 (UTC) writes:
> As I have proposed in Bug 18989 Comment 1 (https://bugs.r-project.org/show_bug.cgi?id=18989#c1), 'c.POSIXlt' in R devel and R 4.6.0 alpha currently tries to preserve sub-second accuracy by proceeding as usual and then replacing the fractional part of the 'sec' component with the "fractional part" of the 'sec' component (x$sec - floor(x$sec), or x$sec %% 1) of the original POSIXlt object.
> However, as I have raised in Bug 18989 Comment 8 (https://bugs.r-project.org/show_bug.cgi?id=18989#c8), there are boundary cases, like
> c(as.POSIXlt("9999-12-31 23:59:59.99999", tz="UTC")) ,
> where the result is a full second ahead of the correct time, worse than not correcting the 'sec' component.
I have not seen a case where R-devel (and 4.6.0 beta) differ
from R 4.5.x -- see below for my test code
> Because of the issue and with '[<-.POSIXlt' and '[[<-.POSIXlt' still using as.POSIXlt(as.POSIXct(*), tz = *) without correction, reverting to the original code is an option for 'c.POSIXlt' for R 4.6.0.
R 4.6.0 will not be changed for this. It is R 4.6.0 beta for
almost a day now which means "code freeze" it will not receive
not very important and in this case untested code changes.
> Alternatively, if the 'c.POSIXlt' feature is to be kept, I think the fixed I have proposed in Bug 18989 Comment 9 (https://bugs.r-project.org/show_bug.cgi?id=18989#c9), applying 'floor' to the 'sec' component before converting to POSIXct, is good enough. It can be wrong only in range where not all whole seconds can be represented by POSIXct ("double" type). Or fixing the issue should wait for a future release?
My problem is that I have (locally) implemented some of your
proposals you mention above and below __but__ I have not been
able to find _any_ difference in behaviour of my local R-devel
version and the current "R-devel" ... even R 4.5.3 not showing
any different behavior.
My test script file, `datetime3_lt_subsec.R`, is attached here
https://bugs.r-project.org/show_bug.cgi?id=18989#c13
I may have been "unlucky" somehow, but that script runs two
nested for loops on POSIXlt vector length 11, with increasing
number of relevant digits in the <POSIXlt> x$sec,
inspired by your
as.POSIXlt("9999-12-31 23:59:59.99999", tz="UTC")
above; it uses all of
`[`, `[[`, `$`,
`[<-`, `[[<-`, `$<-`,
(I think) and looks at "balanced" and "tzone" attributes, but I
don't see any problem.
I'd be really glad if you could modify (part of) it, or extend
it with examples were your proposed changes make a difference.
> As I have raised in Bug 18919 Comment 9 (https://bugs.r-project.org/show_bug.cgi?id=18919#c9), an intriguing case for me with current '[<-.POSIXlt' in R devel and R 4.6.0 alpha is that subassigning a POSIXlt object with the same time zone can have different result to subassigning a POSIXlt object with the exact same time with different, but equivalent, time zone. For example,
> x1 <- as.POSIXlt(.POSIXct(0, tz = "UTC"))
> x1[1L] <- as.POSIXlt("2006-02-20 11:16:16.683", tz = "UTC")
> versus
> x1 <- as.POSIXlt(.POSIXct(0, tz = "UTC"))
> x1[1L] <- as.POSIXlt("2006-02-20 11:16:16.683", tz = "GMT")
> .
> Because the branching condition in '[<-.POSIXlt' uses 'identical' on 'tzone' attributes, the case is not only like "UTC" versus "GMT" or "Etc/UTC". "Non-deterministic POSIXlt tzone in Europe/London around UTC 0" was a case (has been fixed). It can also be 3-element versus 1-element 'tzone' attribute.
Indeed, (3-element vs 1-element "tzone" in <POSIXlt>): That is
sometimes kind of ugly / inconsistent currently, but probably
not relevant in much R code around and would be a different topic.
> As noted in Description of Bug 19005 (https://bugs.r-project.org/show_bug.cgi?id=19005#c0), 'as.POSIXlt.character' produces 1-element 'tzone' attribute. Example:
> x1 <- as.POSIXlt(.POSIXct(1e9, tz = "Europe/London"))
> x1[1L] <- strptime("2006-02-20 11:16:16.683", "%Y-%m-%d %H:%M:%OS", tz = "Europe/London")
> versus
> x1 <- as.POSIXlt(.POSIXct(1e9, tz = "Europe/London"))
> x1[1L] <- as.POSIXlt("2006-02-20 11:16:16.683", tz = "Europe/London")
> The difference can be eliminated by removing branching and using as.POSIXlt(as.POSIXct(*), tz = *) in all cases. However, I expect subassignment to be precise. Using the subassigned object as is is more expected for me. Will the issue be tackled, maybe in a future release of R?
> In '[<-.POSIXlt',
> as.POSIXlt(as.POSIXct(*), tz = *)
> is also applied when 'value' is not a POSIXlt object. I think
> as.POSIXlt(*, tz = *)
> could be used instead. Bug 18919 Comment 10 says that the behaviour was chosen to be consistent with 'c.POSIXlt', which seemed desirable. Does R Core agree?
> For character string, yes, 'Ops.POSIXt' also uses as.POSIXct(*),
> which interprets it as being in the current time zone.
Indeed; Ops.POSIXt working via as.POSIXct() in all cases is
something I'd like to change, notably for what in S4 is the "Compare" subgroup
of the "Ops".
Here (with S3), we'd need to "dispatch" inside Ops.POSIXt();
__however__ that is yet another topic, in my view not part of
any of the open Bugzilla PRs you've been mentioning here.
> Finally, I think the change of
> as.POSIXlt(value)
> to
> if(inherits(value, "POSIXlt") && identical(tz, attr(value, "tzone")))
> value
> else as.POSIXlt(as.POSIXct(value), tz = tz[1L]))
> in '[<-.POSIXlt' and '[[<-.POSIXlt', which is the core of PR#18919, deserves a NEWS item mentioning time zone. For example,
> In subassigning 'val' to a POSIXlt object 'x', x[i] <- val and x[[i]] <- val, now 'val' is converted to the time zone of 'x'.
Yes, you are right; I will add this to the (relatively old) NEWS of R 4.5.2 ..
Thank you for trying to help with the Wishlist in
https://bugs.r-project.org/show_bug.cgi?id=18989
Best regards,
Martin
More information about the R-devel
mailing list