[Rd] (Date + difftime) and (POSIXt + difftime) does not use date/time arithmetics (PR#14067)

suharto_anggono at yahoo.com suharto_anggono at yahoo.com
Mon Nov 16 05:30:12 CET 2009


Full_Name: Suharto Anggono
Version: 2.8.1
OS: Windows
Submission from: (NULL) (125.165.81.48)


There is already PR#13369. But, the problem is not just the warning.


C:\Program Files\R\R-2.8.1\bin>R --vanilla

R version 2.8.1 (2008-12-22)
Copyright (C) 2008 The R Foundation for Statistical Computing
ISBN 3-900051-07-0

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> as.Date("2009-09-15") + as.difftime(8, units="weeks")
[1] "2009-09-23"
Warning message:
Incompatible methods ("+.Date", "Ops.difftime") for "+"


I expect to get the date 8 weeks after 2009-09-15, but I get 8 days after
2009-09-15.
To get the date 8 weeks after 2009-09-15, I have to call '+.Date' directly, or
convert weeks to days.


> `+.Date`(as.Date("2009-09-15"), as.difftime(8, units="weeks"))
[1] "2009-11-10"


The problem is the same for class "POSIXt".


> as.POSIXct("2009-09-09 09:09:09") + as.difftime(1, units="hours")
[1] "2009-09-09 09:09:10 ICT"
Warning message:
Incompatible methods ("+.POSIXt", "Ops.difftime") for "+"


I inspect the function definition for '+.Date' and 'Ops.difftime'.


> `+.Date`
function (e1, e2)
{
    coerceTimeUnit <- function(x) {
        round(switch(attr(x, "units"), secs = x/86400, mins = x/1440,
            hours = x/24, days = x, weeks = 7 * x))
    }
    if (nargs() == 1)
        return(e1)
    if (inherits(e1, "Date") && inherits(e2, "Date"))
        stop("binary + is not defined for Date objects")
    if (inherits(e1, "difftime"))
        e1 <- coerceTimeUnit(e1)
    if (inherits(e2, "difftime"))
        e2 <- coerceTimeUnit(e2)
    structure(unclass(e1) + unclass(e2), class = "Date")
}
<environment: namespace:base>
> Ops.difftime
function (e1, e2)
{
    coerceTimeUnit <- function(x) {
        switch(attr(x, "units"), secs = x, mins = 60 * x, hours = 60 *
            60 * x, days = 60 * 60 * 24 * x, weeks = 60 * 60 *
            24 * 7 * x)
    }
    if (nargs() == 1) {
        switch(.Generic, `+` = {
        }, `-` = {
            e1[] <- -unclass(e1)
        }, stop(gettextf("unary '%s' not defined for \"difftime\" objects",
            .Generic), domain = NA, call. = FALSE))
        return(e1)
    }
    boolean <- switch(.Generic, `<` = , `>` = , `==` = , `!=` = ,
        `<=` = , `>=` = TRUE, FALSE)
    if (boolean) {
        if (inherits(e1, "difftime") && inherits(e2, "difftime")) {
            e1 <- coerceTimeUnit(e1)
            e2 <- coerceTimeUnit(e2)
        }
        NextMethod(.Generic)
    }
    else if (.Generic == "+" || .Generic == "-") {
        if (inherits(e1, "difftime") && !inherits(e2, "difftime"))
            return(structure(NextMethod(.Generic), units = attr(e1,
                "units"), class = "difftime"))
        if (!inherits(e1, "difftime") && inherits(e2, "difftime"))
            return(structure(NextMethod(.Generic), units = attr(e2,
                "units"), class = "difftime"))
        u1 <- attr(e1, "units")
        if (attr(e2, "units") == u1) {
            structure(NextMethod(.Generic), units = u1, class = "difftime")
        }
        else {
            e1 <- coerceTimeUnit(e1)
            e2 <- coerceTimeUnit(e2)
            structure(NextMethod(.Generic), units = "secs", class = "difftime")
        }
    }
    else {
        stop(gettextf("'%s' not defined for \"difftime\" objects",
            .Generic), domain = NA)
    }
}
<environment: namespace:base>


I can see the conflict. In '+.Date', the result of operating "Date" and
"difftime" is of class "Date". In 'Ops.difftime', the result of '+' when one of
its operand is "difftime" is of class "difftime". So, maybe, both are not used;
what is used is the usual '+'.



More information about the R-devel mailing list