1 | /* |
2 | This file is part of the kcal 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 | |
34 | #include "duration.h" |
35 | |
36 | #include <kdatetime.h> |
37 | |
38 | using namespace KCal; |
39 | |
40 | /** |
41 | Private class that helps to provide binary compatibility between releases. |
42 | @internal |
43 | */ |
44 | //@cond PRIVATE |
45 | class KCal::Duration::Private |
46 | { |
47 | public: |
48 | int seconds() const { return mDaily ? mDuration * 86400 : mDuration; } |
49 | int mDuration; // number of seconds or days in the duration |
50 | bool mDaily; // specified in terms of days rather than seconds |
51 | }; |
52 | //@endcond |
53 | |
54 | Duration::Duration() |
55 | : d( new KCal::Duration::Private() ) |
56 | { |
57 | } |
58 | |
59 | Duration::Duration( const KDateTime &start, const KDateTime &end ) |
60 | : d( new KCal::Duration::Private() ) |
61 | { |
62 | if ( start.time() == end.time() && start.timeSpec() == end.timeSpec() ) { |
63 | d->mDuration = start.daysTo( end ); |
64 | d->mDaily = true; |
65 | } else { |
66 | d->mDuration = start.secsTo( end ); |
67 | d->mDaily = false; |
68 | } |
69 | } |
70 | |
71 | Duration::Duration( const KDateTime &start, const KDateTime &end, Type type ) |
72 | : d( new KCal::Duration::Private() ) |
73 | { |
74 | if ( type == Days ) { |
75 | KDateTime endSt( end.toTimeSpec( start ) ); |
76 | d->mDuration = start.daysTo( endSt ); |
77 | if ( d->mDuration ) { |
78 | // Round down to whole number of days if necessary |
79 | if ( start < endSt ) { |
80 | if ( endSt.time() < start.time() ) { |
81 | --d->mDuration; |
82 | } |
83 | } else { |
84 | if ( endSt.time() > start.time() ) { |
85 | ++d->mDuration; |
86 | } |
87 | } |
88 | } |
89 | d->mDaily = true; |
90 | } else { |
91 | d->mDuration = start.secsTo( end ); |
92 | d->mDaily = false; |
93 | } |
94 | } |
95 | |
96 | Duration::Duration( int duration, Type type ) |
97 | : d( new KCal::Duration::Private() ) |
98 | { |
99 | d->mDuration = duration; |
100 | d->mDaily = ( type == Days ); |
101 | } |
102 | |
103 | Duration::Duration( const Duration &duration ) |
104 | : d( new KCal::Duration::Private( *duration.d ) ) |
105 | { |
106 | } |
107 | |
108 | Duration::~Duration() |
109 | { |
110 | delete d; |
111 | } |
112 | |
113 | Duration &Duration::operator=( const Duration &duration ) |
114 | { |
115 | // check for self assignment |
116 | if ( &duration == this ) { |
117 | return *this; |
118 | } |
119 | |
120 | *d = *duration.d; |
121 | return *this; |
122 | } |
123 | |
124 | Duration::operator bool() const |
125 | { |
126 | return d->mDuration; |
127 | } |
128 | |
129 | bool Duration::operator<( const Duration &other ) const |
130 | { |
131 | if ( d->mDaily == other.d->mDaily ) { |
132 | // guard against integer overflow for two daily durations |
133 | return d->mDuration < other.d->mDuration; |
134 | } |
135 | return d->seconds() < other.d->seconds(); |
136 | } |
137 | |
138 | bool Duration::operator==( const Duration &other ) const |
139 | { |
140 | // Note: daily and non-daily durations are always unequal, since a day's |
141 | // duration may differ from 24 hours if it happens to span a daylight saving |
142 | // time change. |
143 | return |
144 | d->mDuration == other.d->mDuration && |
145 | d->mDaily == other.d->mDaily; |
146 | } |
147 | |
148 | Duration &Duration::operator+=( const Duration &other ) |
149 | { |
150 | if ( d->mDaily == other.d->mDaily ) { |
151 | d->mDuration += other.d->mDuration; |
152 | } else if ( d->mDaily ) { |
153 | d->mDuration = d->mDuration * 86400 + other.d->mDuration; |
154 | d->mDaily = false; |
155 | } else { |
156 | d->mDuration += other.d->mDuration + 86400; |
157 | } |
158 | return *this; |
159 | } |
160 | |
161 | Duration Duration::operator-() const |
162 | { |
163 | return Duration( -d->mDuration, ( d->mDaily ? Days : Seconds ) ); |
164 | } |
165 | |
166 | Duration &Duration::operator-=( const Duration &duration ) |
167 | { |
168 | return operator+=( -duration ); |
169 | } |
170 | |
171 | Duration &Duration::operator*=( int value ) |
172 | { |
173 | d->mDuration *= value; |
174 | return *this; |
175 | } |
176 | |
177 | Duration &Duration::operator/=( int value ) |
178 | { |
179 | d->mDuration /= value; |
180 | return *this; |
181 | } |
182 | |
183 | KDateTime Duration::end( const KDateTime &start ) const |
184 | { |
185 | return d->mDaily ? start.addDays( d->mDuration ) |
186 | : start.addSecs( d->mDuration ); |
187 | } |
188 | |
189 | Duration::Type Duration::type() const |
190 | { |
191 | return d->mDaily ? Days : Seconds; |
192 | } |
193 | |
194 | bool Duration::isDaily() const |
195 | { |
196 | return d->mDaily; |
197 | } |
198 | |
199 | int Duration::asSeconds() const |
200 | { |
201 | return d->seconds(); |
202 | } |
203 | |
204 | int Duration::asDays() const |
205 | { |
206 | return d->mDaily ? d->mDuration : d->mDuration / 86400; |
207 | } |
208 | |
209 | int Duration::value() const |
210 | { |
211 | return d->mDuration; |
212 | } |
213 | |