1 | /* |
2 | This file is part of the kcalcore library. |
3 | |
4 | Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> |
5 | Copyright (c) 2007 David Jarvie <djarvie@kde.org> |
6 | |
7 | This library is free software; you can redistribute it and/or |
8 | modify it under the terms of the GNU Library General Public |
9 | License as published by the Free Software Foundation; either |
10 | version 2 of the License, or (at your option) any later version. |
11 | |
12 | This library is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | Library General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU Library General Public License |
18 | along with this library; see the file COPYING.LIB. If not, write to |
19 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 | Boston, MA 02110-1301, USA. |
21 | */ |
22 | /** |
23 | @file |
24 | This file is part of the API for handling calendar data and |
25 | defines the Duration class. |
26 | |
27 | @brief |
28 | Represents a span of time measured in seconds. |
29 | |
30 | @author Cornelius Schumacher \<schumacher@kde.org\> |
31 | @author David Jarvie \<software@astrojar.org.uk\> |
32 | */ |
33 | #include "duration.h" |
34 | #include <KDateTime> |
35 | |
36 | #include <QTime> |
37 | |
38 | using namespace KCalCore; |
39 | |
40 | /** |
41 | Private class that helps to provide binary compatibility between releases. |
42 | @internal |
43 | */ |
44 | //@cond PRIVATE |
45 | class KCalCore::Duration::Private |
46 | { |
47 | public: |
48 | int seconds() const { |
49 | return mDaily ? mDuration * 86400 : mDuration; |
50 | } |
51 | int mDuration; // number of seconds or days in the duration |
52 | bool mDaily; // specified in terms of days rather than seconds |
53 | }; |
54 | //@endcond |
55 | |
56 | Duration::Duration() |
57 | : d(new KCalCore::Duration::Private()) |
58 | { |
59 | } |
60 | |
61 | Duration::Duration(const KDateTime &start, const KDateTime &end) |
62 | : d(new KCalCore::Duration::Private()) |
63 | { |
64 | if (start.time() == end.time() && start.timeSpec() == end.timeSpec()) { |
65 | d->mDuration = start.daysTo(end); |
66 | d->mDaily = true; |
67 | } else { |
68 | d->mDuration = start.secsTo(end); |
69 | d->mDaily = false; |
70 | } |
71 | } |
72 | |
73 | Duration::Duration(const KDateTime &start, const KDateTime &end, Type type) |
74 | : d(new KCalCore::Duration::Private()) |
75 | { |
76 | if (type == Days) { |
77 | KDateTime endSt(end.toTimeSpec(start)); |
78 | d->mDuration = start.daysTo(endSt); |
79 | if (d->mDuration) { |
80 | // Round down to whole number of days if necessary |
81 | if (start < endSt) { |
82 | if (endSt.time() < start.time()) { |
83 | --d->mDuration; |
84 | } |
85 | } else { |
86 | if (endSt.time() > start.time()) { |
87 | ++d->mDuration; |
88 | } |
89 | } |
90 | } |
91 | d->mDaily = true; |
92 | } else { |
93 | d->mDuration = start.secsTo(end); |
94 | d->mDaily = false; |
95 | } |
96 | } |
97 | |
98 | Duration::Duration(int duration, Type type) |
99 | : d(new KCalCore::Duration::Private()) |
100 | { |
101 | d->mDuration = duration; |
102 | d->mDaily = (type == Days); |
103 | } |
104 | |
105 | Duration::Duration(const Duration &duration) |
106 | : d(new KCalCore::Duration::Private(*duration.d)) |
107 | { |
108 | } |
109 | |
110 | Duration::~Duration() |
111 | { |
112 | delete d; |
113 | } |
114 | |
115 | Duration &Duration::operator=(const Duration &duration) |
116 | { |
117 | // check for self assignment |
118 | if (&duration == this) { |
119 | return *this; |
120 | } |
121 | |
122 | *d = *duration.d; |
123 | return *this; |
124 | } |
125 | |
126 | Duration::operator bool() const |
127 | { |
128 | return d->mDuration; |
129 | } |
130 | |
131 | bool Duration::operator<(const Duration &other) const |
132 | { |
133 | if (d->mDaily == other.d->mDaily) { |
134 | // guard against integer overflow for two daily durations |
135 | return d->mDuration < other.d->mDuration; |
136 | } |
137 | return d->seconds() < other.d->seconds(); |
138 | } |
139 | |
140 | bool Duration::operator==(const Duration &other) const |
141 | { |
142 | // Note: daily and non-daily durations are always unequal, since a day's |
143 | // duration may differ from 24 hours if it happens to span a daylight saving |
144 | // time change. |
145 | return d->mDuration == other.d->mDuration && |
146 | d->mDaily == other.d->mDaily; |
147 | } |
148 | |
149 | Duration &Duration::operator+=(const Duration &other) |
150 | { |
151 | if (d->mDaily == other.d->mDaily) { |
152 | d->mDuration += other.d->mDuration; |
153 | } else if (d->mDaily) { |
154 | d->mDuration = d->mDuration * 86400 + other.d->mDuration; |
155 | d->mDaily = false; |
156 | } else { |
157 | d->mDuration += other.d->mDuration + 86400; |
158 | } |
159 | return *this; |
160 | } |
161 | |
162 | Duration Duration::operator-() const |
163 | { |
164 | return Duration(-d->mDuration, (d->mDaily ? Days : Seconds)); |
165 | } |
166 | |
167 | Duration &Duration::operator-=(const Duration &duration) |
168 | { |
169 | return operator+=(-duration); |
170 | } |
171 | |
172 | Duration &Duration::operator*=(int value) |
173 | { |
174 | d->mDuration *= value; |
175 | return *this; |
176 | } |
177 | |
178 | Duration &Duration::operator/=(int value) |
179 | { |
180 | d->mDuration /= value; |
181 | return *this; |
182 | } |
183 | |
184 | KDateTime Duration::end(const KDateTime &start) const |
185 | { |
186 | return d->mDaily ? start.addDays(d->mDuration) |
187 | : start.addSecs(d->mDuration); |
188 | } |
189 | |
190 | Duration::Type Duration::type() const |
191 | { |
192 | return d->mDaily ? Days : Seconds; |
193 | } |
194 | |
195 | bool Duration::isDaily() const |
196 | { |
197 | return d->mDaily; |
198 | } |
199 | |
200 | int Duration::asSeconds() const |
201 | { |
202 | return d->seconds(); |
203 | } |
204 | |
205 | int Duration::asDays() const |
206 | { |
207 | return d->mDaily ? d->mDuration : d->mDuration / 86400; |
208 | } |
209 | |
210 | int Duration::value() const |
211 | { |
212 | return d->mDuration; |
213 | } |
214 | |
215 | QDataStream &KCalCore::operator<<(QDataStream &out, const KCalCore::Duration &duration) |
216 | { |
217 | out << duration.d->mDuration << duration.d->mDaily; |
218 | return out; |
219 | } |
220 | |
221 | QDataStream &KCalCore::operator>>(QDataStream &in, KCalCore::Duration &duration) |
222 | { |
223 | in >> duration.d->mDuration >> duration.d->mDaily; |
224 | return in; |
225 | } |
226 | |