Technically, there is a round() for 'Date' objects, but it doesn't seem very useful, because it basically just fall back to the default round() method, which only takes the 'digits' argument.
Here's an example: > date <- Sys.Date() > class(date) [1] "Date" We see that there are only two round() methods in addition to the implicit built-in one; > methods("round") [1] round.Date round.POSIXt see '?methods' for accessing help and source code Looking at round() for 'Date'; > round.Date function (x, ...) { .Date(NextMethod(), oldClass(x)) } <environment: namespace:base> we see that it defers to the next method here, which is the built-in one. The built-in one, only accepts 'digits', which does nothing for digits >= 0. For digits < 0, it rounds to power of ten, e.g. > date [1] "2024-02-08" > round(date, digits = 0) [1] "2024-02-08" > round(date, digits = 1) [1] "2024-02-08" > round(date, digits = 2) [1] "2024-02-08" > round(date, digits = -1) [1] "2024-02-07" > round(date, digits = -2) [1] "2024-03-18" > round(date, digits = -3) [1] "2024-10-04" > round(date, digits = -4) [1] "2024-10-04" > round(date, digits = -5) [1] "1970-01-01" So, although technically invalid, OPs remark is a valid one. I'd also expect `round()` for Date to support 'units' similar to timestamps, e.g. > time <- Sys.time() > class(time) [1] "POSIXct" "POSIXt" > time [1] "2024-02-08 09:17:02 PST" > round(time, units = "days") [1] "2024-02-08 PST" > round(time, units = "months") [1] "2024-02-01 PST" > round(time, units = "years") [1] "2024-01-01 PST" So, I agree with OP that one would expect: > round(date, units = "days") [1] "2024-02-08" > round(date, units = "months") [1] "2024-02-01" > round(date, units = "years") [1] "2024-01-01" to also work here. FWIW, I don't think we want to encourage circumventing the S3 generic and calling S3 methods directly, i.e. I don't recommend doing things like round.POSIXt(...). Ideally, all S3 methods in R would be non-exported, but some remain exported for legacy reason. But, I think we should treat them as if they in the future will become non-exported. /Henrik On Thu, Feb 8, 2024 at 8:18 AM Olivier Benz via R-devel <r-devel@r-project.org> wrote: > > > On 8 Feb 2024, at 15:15, Martin Maechler <maech...@stat.math.ethz.ch> wrote: > > > >>>>>> Jiří Moravec > >>>>>> on Wed, 7 Feb 2024 10:23:15 +1300 writes: > > > >> This is my first time working with dates, so if the answer is "Duh, work > >> with POSIXt", please ignore it. > > > >> Why is not `round.Date` and `trunc.Date` "implemented" for `Date`? > > > >> Is this because `Date` is (mostly) a virtual class setup for a better > >> inheritance or is that something that is just missing? (like > >> `sort.data.frame`). Would R core welcome a patch? > > > >> I decided to convert some dates to date using `as.Date` function, which > >> converts to a plain `Date` class, because that felt natural. > > > >> But then when trying to round to closest year, I have realized that the > >> `round` and `trunc` for `Date` do not behave as for `POSIXt`. > > > >> I would assume that these will have equivalent output: > > > >> Sys.time() |> round("years") # 2024-01-01 NZDT > > > >> Sys.Date() |> round("years") # Error in round.default(...): non-numeric > >> argument to mathematical function > > > > > >> Looking at the code (and reading the documentation more carefully) shows > >> the issue, but this looks like an omission that should be patched. > > > >> -- Jirka > > > > You are wrong: They *are* implemented, > > both even visible since they are in the 'base' package! > > > > ==> they have help pages you can read .... > > > > Here are examples: > > > >> trunc(Sys.Date()) > > [1] "2024-02-08" > >> trunc(Sys.Date(), "month") > > [1] "2024-02-01" > >> trunc(Sys.Date(), "year") > > [1] "2024-01-01" > >> > > > > Maybe he meant > > r$> Sys.time() |> round.POSIXt("years") > [1] "2024-01-01 CET" > > r$> Sys.Date() |> round.POSIXt("years") > [1] "2024-01-01 UTC" > > The only difference is the timezone > > > ______________________________________________ > > R-devel@r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel On Thu, Feb 8, 2024 at 9:06 AM Rui Barradas <ruipbarra...@sapo.pt> wrote: > > Às 14:36 de 08/02/2024, Olivier Benz via R-devel escreveu: > >> On 8 Feb 2024, at 15:15, Martin Maechler <maech...@stat.math.ethz.ch> > >> wrote: > >> > >>>>>>> Jiří Moravec > >>>>>>> on Wed, 7 Feb 2024 10:23:15 +1300 writes: > >> > >>> This is my first time working with dates, so if the answer is "Duh, work > >>> with POSIXt", please ignore it. > >> > >>> Why is not `round.Date` and `trunc.Date` "implemented" for `Date`? > >> > >>> Is this because `Date` is (mostly) a virtual class setup for a better > >>> inheritance or is that something that is just missing? (like > >>> `sort.data.frame`). Would R core welcome a patch? > >> > >>> I decided to convert some dates to date using `as.Date` function, which > >>> converts to a plain `Date` class, because that felt natural. > >> > >>> But then when trying to round to closest year, I have realized that the > >>> `round` and `trunc` for `Date` do not behave as for `POSIXt`. > >> > >>> I would assume that these will have equivalent output: > >> > >>> Sys.time() |> round("years") # 2024-01-01 NZDT > >> > >>> Sys.Date() |> round("years") # Error in round.default(...): non-numeric > >>> argument to mathematical function > >> > >> > >>> Looking at the code (and reading the documentation more carefully) shows > >>> the issue, but this looks like an omission that should be patched. > >> > >>> -- Jirka > >> > >> You are wrong: They *are* implemented, > >> both even visible since they are in the 'base' package! > >> > >> ==> they have help pages you can read .... > >> > >> Here are examples: > >> > >>> trunc(Sys.Date()) > >> [1] "2024-02-08" > >>> trunc(Sys.Date(), "month") > >> [1] "2024-02-01" > >>> trunc(Sys.Date(), "year") > >> [1] "2024-01-01" > >>> > >> > > > > Maybe he meant > > > > r$> Sys.time() |> round.POSIXt("years") > > [1] "2024-01-01 CET" > > > > r$> Sys.Date() |> round.POSIXt("years") > > [1] "2024-01-01 UTC" > > > > The only difference is the timezone > > > >> ______________________________________________ > >> R-devel@r-project.org mailing list > >> https://stat.ethz.ch/mailman/listinfo/r-devel > > ______________________________________________ > > R-devel@r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > Hello, > > You are right that the timezones are different but Sys.date() returns an > object of class "Date" so the method called is not that one. > Here an example with trunc. > > > Sys.Date() |> class() > Sys.Date() |> trunc("years") > Sys.Date() |> trunc.Date("years") > Sys.Date() |> trunc.POSIXt("years") > > > As for the OP, the problem is thhat the generic roun())) doesn't have > unit argument. So I am nnnot understanding why round.POSIXt works. > > > Sys.Date() |> round("years") > #> Error in round.default(structure(19761, class = "Date"), "years"): > non-numeric argument to mathematical function > Sys.Date() |> round.Date("years") > #> Error in NextMethod(): generic function not specified > > Sys.Date() |> round.POSIXt("years") > #> [1] "2024-01-01 UTC" > Sys.Date() |> round.POSIXt("months") > #> [1] "2024-02-01 UTC" > Sys.Date() |> round.POSIXt("days") > #> [1] "2024-02-08 UTC" > > > Hope this helps, > > Rui Barradas > > > > -- > Este e-mail foi analisado pelo software antivírus AVG para verificar a > presença de vírus. > www.avg.com > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel