1#' @include timespans.r
2#' @include durations.r
3#' @include intervals.r
4#' @include periods.r
5#' @include Dates.r
6#' @include difftimes.r
7#' @include numeric.r
8#' @include POSIXt.r
9NULL
10
11
12add_duration_to_duration <- function(dur2, dur1)
13  new("Duration", dur1@.Data + dur2@.Data)
14
15add_duration_to_date <- function(dur, date) {
16  if (is.Date(date)) {
17    date <- as.POSIXct(date)
18    ans <- with_tz(date + dur@.Data, "UTC")
19
20    if (all(is.na(ans))) return(as.Date(ans))  # ALL NAs
21
22    if (all(hour(na.omit(ans)) == 0  &
23            minute(na.omit(ans)) == 0 &
24            second(na.omit(ans)) == 0)) {
25      return(as.Date(ans))
26    }
27
28    return(ans)
29  }
30  new <- date + dur@.Data
31  attr(new, "tzone") <- tz(date)
32  reclass_date(new, date)
33}
34
35add_period_to_period <- function(per2, per1) {
36  new("Period", per1@.Data + per2@.Data,
37      year = per1@year + per2@year,
38      month = per1@month + per2@month,
39      day = per1@day + per2@day,
40      hour = per1@hour + per2@hour,
41      minute = per1@minute + per2@minute)
42}
43
44add_period_to_date <- function(per, date) {
45
46  lt <- as.POSIXlt(date)
47
48  ## add months and years with no backwards rollover
49  ms <- month(per) + year(per) * 12
50  lt <- add_months(lt, ms)
51
52  if (is.Date(date)) {
53    new <- update(as.Date(lt),
54                  days = mday(lt) + per@day,
55                  hours = per@hour,
56                  minutes = per@minute,
57                  seconds = per@.Data)
58    return(new)
59  }
60
61  new <- update(lt,
62                days = mday(lt) + per@day,
63                hours = hour(lt) + per@hour,
64                minutes = minute(lt) + per@minute,
65                seconds = second(lt) + per@.Data)
66
67  reclass_date(new, date)
68}
69
70add_months <- function(mt, mos) {
71  nnas <- !is.na(mos)
72  if (all(mos[nnas] == 0L)) {
73    return(mt)
74  }
75  mt$mon <- mt$mon + mos
76  ndays <- as.numeric(format.POSIXlt(mt, "%d", usetz = FALSE))
77  mt$mon[mt$mday != ndays] <- NA
78  mt
79}
80
81add_number_to_duration <- function(num, dur) {
82  new("Duration", dur@.Data + num)
83}
84
85add_number_to_period <- function(num, per) {
86  slot(per, ".Data") <- per@.Data + num
87  per
88}
89
90#' @export
91setMethod("+", signature(e1 = "Duration", e2 = "Duration"),
92          function(e1, e2) add_duration_to_duration(e2, e1))
93
94#' @export
95setMethod("+", signature(e1 = "Duration", e2 = "Date"),
96          function(e1, e2) add_duration_to_date(e1, e2))
97
98#' @export
99setMethod("+", signature(e1 = "Duration", e2 = "difftime"),
100          function(e1, e2) add_duration_to_duration(as.duration(e2), e1))
101
102#' @export
103setMethod("+", signature(e1 = "Duration", e2 = "numeric"),
104          function(e1, e2) add_number_to_duration(e2, e1))
105
106#' @export
107setMethod("+", signature(e1 = "Duration", e2 = "POSIXct"),
108          function(e1, e2) add_duration_to_date(e1, e2))
109
110#' @export
111setMethod("+", signature(e1 = "Duration", e2 = "POSIXlt"),
112          function(e1, e2) add_duration_to_date(e1, e2))
113
114#' @export
115setMethod("+", signature(e1 = "Period", e2 = "Period"),
116          function(e1, e2) add_period_to_period(e2, e1))
117
118#' @export
119setMethod("+", signature(e1 = "Period", e2 = "Date"),
120          function(e1, e2) add_period_to_date(e1, e2))
121
122#' @export
123setMethod("+", signature(e1 = "Period", e2 = "numeric"),
124          function(e1, e2) add_number_to_period(e2, e1))
125
126#' @export
127setMethod("+", signature(e1 = "Period", e2 = "POSIXct"),
128          function(e1, e2) add_period_to_date(e1, e2))
129
130#' @export
131setMethod("+", signature(e1 = "Period", e2 = "POSIXlt"),
132          function(e1, e2) add_period_to_date(e1, e2))
133
134#' @export
135setMethod("+", signature(e1 = "Date", e2 = "Duration"),
136          function(e1, e2) add_duration_to_date(e2, e1))
137
138#' @export
139setMethod("+", signature(e1 = "Date", e2 = "Period"),
140          function(e1, e2) add_period_to_date(e2, e1))
141
142#' @export
143setMethod("+", signature(e1 = "difftime", e2 = "Duration"),
144          function(e1, e2) as.difftime(e2, units = "secs") + e1)
145
146#' @export
147setMethod("+", signature(e1 = "numeric", e2 = "Duration"),
148          function(e1, e2) add_number_to_duration(e1, e2))
149
150#' @export
151setMethod("+", signature(e1 = "numeric", e2 = "Period"),
152          function(e1, e2) add_number_to_period(e1, e2))
153
154#' @export
155setMethod("+", signature(e1 = "POSIXct", e2 = "Duration"),
156          function(e1, e2) add_duration_to_date(e2, e1))
157
158#' @export
159setMethod("+", signature(e1 = "POSIXct", e2 = "Period"),
160          function(e1, e2) add_period_to_date(e2, e1))
161
162#' @export
163setMethod("+", signature(e1 = "POSIXlt", e2 = "Duration"),
164          function(e1, e2) add_duration_to_date(e2, e1))
165
166#' @export
167setMethod("+", signature(e1 = "POSIXlt", e2 = "Period"),
168          function(e1, e2) add_period_to_date(e2, e1))
169