From suharto_anggono at yahoo.com  Mon Nov 16 05:30:12 2009
From: suharto_anggono at yahoo.com (suharto_anggono at yahoo.com)
Date: Mon, 16 Nov 2009 05:30:12 +0100 (CET)
Subject: [Rd] (Date + difftime) and (POSIXt + difftime) does not use
	date/time arithmetics (PR#14067)
Message-ID: <20091116043012.1CC59283031A@mail.pubhealth.ku.dk>

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 '+'.



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