Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsinterval.h 3 : : ------------- 4 : : Date : May 2016 5 : : Copyright : (C) 2016 by Nyall Dawson 6 : : Email : nyall dot dawson at gmail dot com 7 : : *************************************************************************** 8 : : * * 9 : : * This program is free software; you can redistribute it and/or modify * 10 : : * it under the terms of the GNU General Public License as published by * 11 : : * the Free Software Foundation; either version 2 of the License, or * 12 : : * (at your option) any later version. * 13 : : * * 14 : : ***************************************************************************/ 15 : : 16 : : #ifndef QGSINTERVAL_H 17 : : #define QGSINTERVAL_H 18 : : 19 : : /*************************************************************************** 20 : : * This class is considered CRITICAL and any change MUST be accompanied with 21 : : * full unit tests in test_qgsinterval.py. 22 : : * See details in QEP #17 23 : : ****************************************************************************/ 24 : : 25 : : #include <QVariant> 26 : : 27 : : #include "qgis_sip.h" 28 : : #include "qgis_core.h" 29 : : #include "qgsunittypes.h" 30 : : #include "qgis.h" 31 : : 32 : : class QString; 33 : : 34 : : /** 35 : : * \ingroup core 36 : : * \class QgsInterval 37 : : * \brief A representation of the interval between two datetime values. 38 : : * \since QGIS 2.16 39 : : */ 40 : : 41 : : class CORE_EXPORT QgsInterval 42 : : { 43 : : public: 44 : : 45 : : // YEAR const value taken from postgres query 46 : : // SELECT EXTRACT(EPOCH FROM interval '1 year') 47 : : //! Seconds per year (average) 48 : : static const int YEARS = 31557600; 49 : : //! Seconds per month, based on 30 day month 50 : : static const int MONTHS = 60 * 60 * 24 * 30; 51 : : //! Seconds per week 52 : : static const int WEEKS = 60 * 60 * 24 * 7; 53 : : //! Seconds per day 54 : : static const int DAY = 60 * 60 * 24; 55 : : //! Seconds per hour 56 : : static const int HOUR = 60 * 60; 57 : : //! Seconds per minute 58 : : static const int MINUTE = 60; 59 : : 60 : : /** 61 : : * Default constructor for QgsInterval. Creates an invalid interval. 62 : : */ 63 : 0 : QgsInterval() = default; 64 : : 65 : : /** 66 : : * Constructor for QgsInterval. 67 : : * \param seconds duration of interval in seconds 68 : : */ 69 : : QgsInterval( double seconds ); 70 : : 71 : : /** 72 : : * Constructor for QgsInterval, using the specified \a duration and \a units. 73 : : */ 74 : : QgsInterval( double duration, QgsUnitTypes::TemporalUnit unit ); 75 : : 76 : : /** 77 : : * Constructor for QgsInterval, using the specified \a years, \a months, 78 : : * \a weeks, \a days, \a hours, \a minutes and \a seconds. 79 : : * 80 : : * \note Month units assumes a 30 day month length. 81 : : * \note Year units assumes a 365.25 day year length. 82 : : * 83 : : * \since QGIS 3.14 84 : : */ 85 : : QgsInterval( double years, double months, double weeks, double days, double hours, double minutes, double seconds ); 86 : : 87 : : /** 88 : : * Returns the interval duration in years (based on an average year length) 89 : : * 90 : : * If the originalUnit() is QgsUnitTypes::TemporalYears then this value 91 : : * will match the exact number of months as returned by originalDuration(), 92 : : * otherwise it will be calculated using the average year length (31557600 seconds). 93 : : * 94 : : * \see setYears() 95 : : */ 96 : : double years() const; 97 : : 98 : : /** 99 : : * Sets the interval duration in years. 100 : : * 101 : : * Replaces the interval size and changes the original interval unit 102 : : * and duration, \see originalDuration() and \see originalUnit(). 103 : : * 104 : : * Changes the original unit to QgsUnitTypes::TemporalYears 105 : : * 106 : : * \param years duration in years (based on average year length) 107 : : * \see years() 108 : : */ 109 : : void setYears( double years ); 110 : : 111 : : /** 112 : : * Returns the interval duration in months (based on a 30 day month). 113 : : * 114 : : * If the originalUnit() is QgsUnitTypes::TemporalMonths then this value 115 : : * will match the exact number of months as returned by originalDuration(), 116 : : * otherwise it will be calculated using the assumption that 117 : : * a month consists of exactly 30 days. 118 : : * 119 : : * \see setMonths() 120 : : */ 121 : : double months() const; 122 : : 123 : : /** 124 : : * Sets the interval duration in months. 125 : : * 126 : : * Replaces the interval size and changes the original interval unit 127 : : * and duration, \see originalDuration() and \see originalUnit(). 128 : : * 129 : : * Changes the original unit to QgsUnitTypes::TemporalMonths 130 : : * 131 : : * \param months duration in months (based on a 30 day month) 132 : : * \see months() 133 : : */ 134 : : void setMonths( double months ); 135 : : 136 : : /** 137 : : * Returns the interval duration in weeks. 138 : : * 139 : : * If the originalUnit() is QgsUnitTypes::TemporalWeeks then this value 140 : : * will match the exact number of weeks as returned by originalDuration(), 141 : : * otherwise it will be calculated using the QgsInterval::WEEKS constant. 142 : : * 143 : : * \see setWeeks() 144 : : */ 145 : : double weeks() const; 146 : : 147 : : /** 148 : : * Sets the interval duration in weeks. 149 : : * 150 : : * Replaces the interval size and changes the original interval unit 151 : : * and duration, \see originalDuration() and \see originalUnit(). 152 : : * 153 : : * Changes the original unit to QgsUnitTypes::TemporalWeeks 154 : : * 155 : : * \param weeks duration in weeks 156 : : * \see weeks() 157 : : */ 158 : : void setWeeks( double weeks ); 159 : : 160 : : /** 161 : : * Returns the interval duration in days. 162 : : * 163 : : * If the originalUnit() is QgsUnitTypes::TemporalDays then this value 164 : : * will match the exact number of days as returned by originalDuration(), 165 : : * otherwise it will be calculated using the QgsInterval::DAY constant. 166 : : * 167 : : * \see setDays() 168 : : */ 169 : : double days() const; 170 : : 171 : : /** 172 : : * Sets the interval duration in days. 173 : : * 174 : : * Replaces the interval size and changes the original interval unit 175 : : * and duration, \see originalDuration() and \see originalUnit(). 176 : : * 177 : : * Changes the original unit to QgsUnitTypes::TemporalDays 178 : : * 179 : : * \param days duration in days 180 : : * \see days() 181 : : */ 182 : : void setDays( double days ); 183 : : 184 : : /** 185 : : * Returns the interval duration in hours. 186 : : * 187 : : * If the originalUnit() is QgsUnitTypes::TemporalHours then this value 188 : : * will match the exact number of hours as returned by originalDuration(), 189 : : * otherwise it will be calculated using the QgsInterval::HOUR constant. 190 : : * 191 : : * \see setHours() 192 : : */ 193 : : double hours() const; 194 : : 195 : : /** 196 : : * Sets the interval duration in hours. 197 : : * 198 : : * Replaces the interval size and changes the original interval unit 199 : : * and duration, \see originalDuration() and \see originalUnit(). 200 : : * 201 : : * The original unit to QgsUnitTypes::TemporalHours 202 : : * 203 : : * \param hours duration in hours 204 : : * \see hours() 205 : : */ 206 : : void setHours( double hours ); 207 : : 208 : : /** 209 : : * Returns the interval duration in minutes. 210 : : * 211 : : * If the originalUnit() is QgsUnitTypes::TemporalMinutes then this value 212 : : * will match the exact number of minutes as returned by originalDuration(), 213 : : * otherwise it will be calculated using the QgsInterval::MINUTE constant. 214 : : * 215 : : * \see setMinutes() 216 : : */ 217 : : double minutes() const; 218 : : 219 : : /** 220 : : * Sets the interval duration in minutes. 221 : : * 222 : : * Replaces the interval size and changes the original interval unit 223 : : * and duration, \see originalDuration() and \see originalUnit(). 224 : : * 225 : : * Changes the original unit to QgsUnitTypes::TemporalMinutes 226 : : * 227 : : * \param minutes duration in minutes 228 : : * \see minutes() 229 : : */ 230 : : void setMinutes( double minutes ); 231 : : 232 : : /** 233 : : * Returns the interval duration in seconds. 234 : : * \see setSeconds() 235 : : */ 236 : 0 : double seconds() const { return mSeconds; } 237 : : 238 : : /** 239 : : * Sets the interval duration in seconds. 240 : : * 241 : : * Replaces the interval size and changes the original interval unit 242 : : * and duration, \see originalDuration() and \see originalUnit(). 243 : : * 244 : : * Changes the original unit to QgsUnitTypes::TemporalSeconds 245 : : * 246 : : * \param seconds duration in seconds 247 : : * \see seconds() 248 : : */ 249 : : void setSeconds( double seconds ); 250 : : 251 : : /** 252 : : * Returns TRUE if the interval is valid. 253 : : * \see setValid() 254 : : */ 255 : 0 : bool isValid() const { return mValid; } 256 : : 257 : : /** 258 : : * Sets whether the interval is valid. 259 : : * \param valid set to TRUE to set the interval as valid. 260 : : * \see isValid() 261 : : */ 262 : : void setValid( bool valid ) { mValid = valid; } 263 : : 264 : : /** 265 : : * Returns the original interval duration. 266 : : * 267 : : * This original interval duration can be updated through calling 268 : : * QgsInterval setter methods. 269 : : * 270 : : * \see originalUnit() for the corresponding unit. 271 : : * 272 : : * If the original interval duration is not available or 273 : : * interval was set with a mix of units, calling originalUnit() 274 : : * will return QgsUnitTypes::TemporalUnknownUnit 275 : : * 276 : : * Returns 0.0 if the original duration was not set. 277 : : * 278 : : * \since 3.18 279 : : */ 280 : 0 : double originalDuration() const { return mOriginalDuration; } 281 : : 282 : : /** 283 : : * Returns the original interval temporal unit. 284 : : * 285 : : * The interval temporal unit can be set through the 286 : : * QgsInterval constructors or through the available setter methods. 287 : : * 288 : : * Returns QgsUnitTypes::TemporalUnknownUnit if unit was not set when creating the 289 : : * QgsInterval instance or interval was set with a mix of units. 290 : : * 291 : : * \see originalDuration() 292 : : * 293 : : * \since 3.18 294 : : */ 295 : 0 : QgsUnitTypes::TemporalUnit originalUnit() const { return mOriginalUnit; } 296 : : 297 : 0 : bool operator==( QgsInterval other ) const 298 : : { 299 : 0 : if ( !mValid && !other.mValid ) 300 : 0 : return true; 301 : 0 : else if ( mValid && other.mValid && ( mOriginalUnit != QgsUnitTypes::TemporalUnknownUnit || other.mOriginalUnit != QgsUnitTypes::TemporalUnknownUnit ) ) 302 : 0 : return mOriginalUnit == other.mOriginalUnit && mOriginalDuration == other.mOriginalDuration; 303 : 0 : else if ( mValid && other.mValid ) 304 : 0 : return qgsDoubleNear( mSeconds, other.mSeconds ); 305 : : else 306 : 0 : return false; 307 : 0 : } 308 : : 309 : : bool operator!=( QgsInterval other ) const 310 : : { 311 : : return !( *this == other ); 312 : : } 313 : : 314 : : /** 315 : : * Converts a string to an interval 316 : : * \param string string to parse 317 : : * \returns interval, or invalid interval if string could not be parsed 318 : : */ 319 : : static QgsInterval fromString( const QString &string ); 320 : : 321 : : //! Allows direct construction of QVariants from intervals. 322 : 0 : operator QVariant() const 323 : : { 324 : 0 : return QVariant::fromValue( *this ); 325 : : } 326 : : 327 : : private: 328 : : 329 : : //! Duration of interval in seconds 330 : 0 : double mSeconds = 0.0; 331 : : 332 : : //! True if interval is valid 333 : 0 : bool mValid = false; 334 : : 335 : : //! Interval duration 336 : 0 : double mOriginalDuration = 0.0; 337 : : 338 : : //! Interval unit 339 : 0 : QgsUnitTypes::TemporalUnit mOriginalUnit = QgsUnitTypes::TemporalUnknownUnit; 340 : : }; 341 : : 342 : 0 : Q_DECLARE_METATYPE( QgsInterval ) 343 : : 344 : : #ifndef SIP_RUN 345 : : 346 : : /** 347 : : * Returns the interval between two datetimes. 348 : : * \param datetime1 start datetime 349 : : * \param datetime2 datetime to subtract, ie subtract datetime2 from datetime1 350 : : * \note not available in Python bindings 351 : : * \since QGIS 2.16 352 : : */ 353 : : QgsInterval CORE_EXPORT operator-( const QDateTime &datetime1, const QDateTime &datetime2 ); 354 : : 355 : : /** 356 : : * Returns the interval between two dates. 357 : : * \param date1 start date 358 : : * \param date2 date to subtract, ie subtract date2 from date1 359 : : * \note not available in Python bindings 360 : : * \since QGIS 2.16 361 : : */ 362 : : QgsInterval CORE_EXPORT operator-( QDate date1, QDate date2 ); 363 : : 364 : : /** 365 : : * Returns the interval between two times. 366 : : * \param time1 start time 367 : : * \param time2 time to subtract, ie subtract time2 from time1 368 : : * \note not available in Python bindings 369 : : * \since QGIS 2.16 370 : : */ 371 : : QgsInterval CORE_EXPORT operator-( QTime time1, QTime time2 ); 372 : : 373 : : /** 374 : : * Adds an interval to a datetime 375 : : * \param start initial datetime 376 : : * \param interval interval to add 377 : : * \note not available in Python bindings 378 : : * \since QGIS 2.16 379 : : */ 380 : : QDateTime CORE_EXPORT operator+( const QDateTime &start, const QgsInterval &interval ); 381 : : 382 : : //! Debug string representation of interval 383 : : QDebug operator<<( QDebug dbg, const QgsInterval &interval ); 384 : : \ 385 : : #endif 386 : : 387 : : #endif // QGSINTERVAL_H