File indexing completed on 2024-05-05 12:10:39
0001 /* 0002 This file is part of the kcalcore library. 0003 0004 SPDX-FileCopyrightText: 2001 Cornelius Schumacher <schumacher@kde.org> 0005 SPDX-FileCopyrightText: 2007 David Jarvie <djarvie@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 /** 0010 @file 0011 This file is part of the API for handling calendar data and 0012 defines the Duration class. 0013 0014 @brief 0015 Represents a span of time measured in seconds. 0016 0017 @author Cornelius Schumacher \<schumacher@kde.org\> 0018 @author David Jarvie \<djarvie@kde.org\> 0019 */ 0020 #include "duration.h" 0021 0022 #include <QDateTime> 0023 #include <QTimeZone> 0024 0025 using namespace KCalendarCore; 0026 0027 /** 0028 Private class that helps to provide binary compatibility between releases. 0029 @internal 0030 */ 0031 //@cond PRIVATE 0032 class Q_DECL_HIDDEN KCalendarCore::Duration::Private 0033 { 0034 public: 0035 int seconds() const 0036 { 0037 return mDaily ? mDuration * 86400 : mDuration; 0038 } 0039 int mDuration; // number of seconds or days in the duration 0040 bool mDaily = false; // specified in terms of days rather than seconds 0041 }; 0042 //@endcond 0043 0044 Duration::Duration() 0045 : d(new KCalendarCore::Duration::Private()) 0046 { 0047 } 0048 0049 Duration::Duration(const QDateTime &start, const QDateTime &end) 0050 : d(new KCalendarCore::Duration::Private()) 0051 { 0052 if (start.time() == end.time() && start.timeZone() == end.timeZone()) { 0053 d->mDuration = start.daysTo(end); 0054 d->mDaily = true; 0055 } else { 0056 d->mDuration = start.secsTo(end); 0057 d->mDaily = false; 0058 } 0059 } 0060 0061 Duration::Duration(const QDateTime &start, const QDateTime &end, Type type) 0062 : d(new KCalendarCore::Duration::Private()) 0063 { 0064 if (type == Days) { 0065 QDateTime endSt(end.toTimeZone(start.timeZone())); 0066 d->mDuration = start.daysTo(endSt); 0067 if (d->mDuration) { 0068 // Round down to whole number of days if necessary 0069 if (start < endSt) { 0070 if (endSt.time() < start.time()) { 0071 --d->mDuration; 0072 } 0073 } else { 0074 if (endSt.time() > start.time()) { 0075 ++d->mDuration; 0076 } 0077 } 0078 } 0079 d->mDaily = true; 0080 } else { 0081 d->mDuration = start.secsTo(end); 0082 d->mDaily = false; 0083 } 0084 } 0085 0086 Duration::Duration(int duration, Type type) 0087 : d(new KCalendarCore::Duration::Private()) 0088 { 0089 d->mDuration = duration; 0090 d->mDaily = (type == Days); 0091 } 0092 0093 Duration::Duration(const Duration &duration) 0094 : d(new KCalendarCore::Duration::Private(*duration.d)) 0095 { 0096 } 0097 0098 Duration::~Duration() 0099 { 0100 delete d; 0101 } 0102 0103 Duration &Duration::operator=(const Duration &duration) 0104 { 0105 // check for self assignment 0106 if (&duration == this) { 0107 return *this; 0108 } 0109 0110 *d = *duration.d; 0111 return *this; 0112 } 0113 0114 Duration::operator bool() const 0115 { 0116 return d->mDuration; 0117 } 0118 0119 bool Duration::operator<(const Duration &other) const 0120 { 0121 if (d->mDaily == other.d->mDaily) { 0122 // guard against integer overflow for two daily durations 0123 return d->mDuration < other.d->mDuration; 0124 } 0125 return d->seconds() < other.d->seconds(); 0126 } 0127 0128 bool Duration::operator==(const Duration &other) const 0129 { 0130 // Note: daily and non-daily durations are always unequal, since a day's 0131 // duration may differ from 24 hours if it happens to span a daylight saving 0132 // time change. 0133 return d->mDuration == other.d->mDuration && d->mDaily == other.d->mDaily; 0134 } 0135 0136 Duration &Duration::operator+=(const Duration &other) 0137 { 0138 if (d->mDaily == other.d->mDaily) { 0139 d->mDuration += other.d->mDuration; 0140 } else if (d->mDaily) { 0141 d->mDuration = d->mDuration * 86400 + other.d->mDuration; 0142 d->mDaily = false; 0143 } else { 0144 d->mDuration += other.d->mDuration + 86400; 0145 } 0146 return *this; 0147 } 0148 0149 Duration Duration::operator-() const 0150 { 0151 return Duration(-d->mDuration, (d->mDaily ? Days : Seconds)); 0152 } 0153 0154 Duration &Duration::operator-=(const Duration &duration) 0155 { 0156 return operator+=(-duration); 0157 } 0158 0159 Duration &Duration::operator*=(int value) 0160 { 0161 d->mDuration *= value; 0162 return *this; 0163 } 0164 0165 Duration &Duration::operator/=(int value) 0166 { 0167 d->mDuration /= value; 0168 return *this; 0169 } 0170 0171 QDateTime Duration::end(const QDateTime &start) const 0172 { 0173 return d->mDaily ? start.addDays(d->mDuration) : start.addSecs(d->mDuration); 0174 } 0175 0176 Duration::Type Duration::type() const 0177 { 0178 return d->mDaily ? Days : Seconds; 0179 } 0180 0181 bool Duration::isDaily() const 0182 { 0183 return d->mDaily; 0184 } 0185 0186 int Duration::asSeconds() const 0187 { 0188 return d->seconds(); 0189 } 0190 0191 int Duration::asDays() const 0192 { 0193 return d->mDaily ? d->mDuration : d->mDuration / 86400; 0194 } 0195 0196 int Duration::value() const 0197 { 0198 return d->mDuration; 0199 } 0200 0201 bool Duration::isNull() const 0202 { 0203 return d->mDuration == 0; 0204 } 0205 0206 QDataStream &KCalendarCore::operator<<(QDataStream &out, const KCalendarCore::Duration &duration) 0207 { 0208 out << duration.d->mDuration << duration.d->mDaily; 0209 return out; 0210 } 0211 0212 QDataStream &KCalendarCore::operator>>(QDataStream &in, KCalendarCore::Duration &duration) 0213 { 0214 in >> duration.d->mDuration >> duration.d->mDaily; 0215 return in; 0216 }