QGIS API Documentation  3.17.0-Master (a035f434f4)
qgsinterval.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsinterval.cpp
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 #include "qgsinterval.h"
17 #include "qgis.h"
18 #include <QString>
19 #include <QStringList>
20 #include <QMap>
21 #include <QObject>
22 #include <QDebug>
23 #include <QDateTime>
24 
25 /***************************************************************************
26  * This class is considered CRITICAL and any change MUST be accompanied with
27  * full unit tests in test_qgsinterval.py.
28  * See details in QEP #17
29  ****************************************************************************/
30 
31 QgsInterval::QgsInterval( double seconds )
32  : mSeconds( seconds )
33  , mValid( true )
34 { }
35 
37  : mSeconds( duration * QgsUnitTypes::fromUnitToUnitFactor( unit, QgsUnitTypes::TemporalSeconds ) )
38  , mValid( true )
39 {
40 
41 }
42 
43 QgsInterval::QgsInterval( double years, double months, double weeks, double days, double hours, double minutes, double seconds )
44  : mSeconds( years * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::TemporalYears, QgsUnitTypes::TemporalSeconds )
45  + months * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::TemporalMonths, QgsUnitTypes::TemporalSeconds )
46  + weeks * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::TemporalWeeks, QgsUnitTypes::TemporalSeconds )
47  + days * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::TemporalDays, QgsUnitTypes::TemporalSeconds )
48  + hours * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::TemporalHours, QgsUnitTypes::TemporalSeconds )
49  + minutes * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::TemporalMinutes, QgsUnitTypes::TemporalSeconds )
50  + seconds )
51  , mValid( true )
52 {
53 
54 }
55 
57 {
58  if ( !mValid && !other.mValid )
59  return true;
60  else if ( mValid && other.mValid )
61  return qgsDoubleNear( mSeconds, other.mSeconds );
62  else
63  return false;
64 }
65 
66 QgsInterval QgsInterval::fromString( const QString &string )
67 {
68  double seconds = 0;
69  QRegExp rx( "([-+]?\\d*\\.?\\d+\\s+\\S+)", Qt::CaseInsensitive );
70  QStringList list;
71  int pos = 0;
72 
73  while ( ( pos = rx.indexIn( string, pos ) ) != -1 )
74  {
75  list << rx.cap( 1 );
76  pos += rx.matchedLength();
77  }
78 
79  QMap<int, QStringList> map;
80  map.insert( 1, QStringList() << QStringLiteral( "second" ) << QStringLiteral( "seconds" ) << QObject::tr( "second|seconds", "list of words separated by | which reference years" ).split( '|' ) );
81  map.insert( 0 + MINUTE, QStringList() << QStringLiteral( "minute" ) << QStringLiteral( "minutes" ) << QObject::tr( "minute|minutes", "list of words separated by | which reference minutes" ).split( '|' ) );
82  map.insert( 0 + HOUR, QStringList() << QStringLiteral( "hour" ) << QStringLiteral( "hours" ) << QObject::tr( "hour|hours", "list of words separated by | which reference minutes hours" ).split( '|' ) );
83  map.insert( 0 + DAY, QStringList() << QStringLiteral( "day" ) << QStringLiteral( "days" ) << QObject::tr( "day|days", "list of words separated by | which reference days" ).split( '|' ) );
84  map.insert( 0 + WEEKS, QStringList() << QStringLiteral( "week" ) << QStringLiteral( "weeks" ) << QObject::tr( "week|weeks", "wordlist separated by | which reference weeks" ).split( '|' ) );
85  map.insert( 0 + MONTHS, QStringList() << QStringLiteral( "month" ) << QStringLiteral( "months" ) << QObject::tr( "month|months", "list of words separated by | which reference months" ).split( '|' ) );
86  map.insert( 0 + YEARS, QStringList() << QStringLiteral( "year" ) << QStringLiteral( "years" ) << QObject::tr( "year|years", "list of words separated by | which reference years" ).split( '|' ) );
87 
88  const auto constList = list;
89  for ( const QString &match : constList )
90  {
91  QStringList split = match.split( QRegExp( "\\s+" ) );
92  bool ok;
93  double value = split.at( 0 ).toDouble( &ok );
94  if ( !ok )
95  {
96  continue;
97  }
98 
99  bool matched = false;
100  QMap<int, QStringList>::const_iterator it = map.constBegin();
101  for ( ; it != map.constEnd(); ++it )
102  {
103  int duration = it.key();
104  const auto constValue = it.value();
105  for ( const QString &name : constValue )
106  {
107  if ( match.contains( name, Qt::CaseInsensitive ) )
108  {
109  matched = true;
110  break;
111  }
112  }
113 
114  if ( matched )
115  {
116  seconds += value * duration;
117  break;
118  }
119  }
120  }
121 
122  // If we can't parse the string at all then we just return invalid
123  if ( seconds == 0 )
124  return QgsInterval();
125 
126  return QgsInterval( seconds );
127 }
128 
129 QDebug operator<<( QDebug dbg, const QgsInterval &interval )
130 {
131  if ( !interval.isValid() )
132  dbg.nospace() << "QgsInterval()";
133  else
134  dbg.nospace() << "QgsInterval(" << interval.seconds() << ")";
135  return dbg.maybeSpace();
136 }
137 
138 QgsInterval operator-( const QDateTime &dt1, const QDateTime &dt2 )
139 {
140  qint64 mSeconds = dt2.msecsTo( dt1 );
141  return QgsInterval( mSeconds / 1000.0 );
142 }
143 
144 QDateTime operator+( const QDateTime &start, const QgsInterval &interval )
145 {
146  return start.addMSecs( static_cast<qint64>( interval.seconds() * 1000.0 ) );
147 }
148 
149 QgsInterval operator-( QDate date1, QDate date2 )
150 {
151  qint64 seconds = static_cast< qint64 >( date2.daysTo( date1 ) ) * 24 * 60 * 60;
152  return QgsInterval( seconds );
153 }
154 
155 QgsInterval operator-( QTime time1, QTime time2 )
156 {
157  qint64 mSeconds = time2.msecsTo( time1 );
158  return QgsInterval( mSeconds / 1000.0 );
159 }
static const int YEARS
Seconds per year (average)
Definition: qgsinterval.h:47
bool operator==(QgsInterval other) const
Definition: qgsinterval.cpp:56
bool isValid() const
Returns true if the interval is valid.
Definition: qgsinterval.h:181
double months() const
Returns the interval duration in months (based on a 30 day month).
Definition: qgsinterval.h:103
static const int MONTHS
Seconds per month, based on 30 day month.
Definition: qgsinterval.h:49
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:316
Helper functions for various unit types.
Definition: qgsunittypes.h:38
double seconds() const
Returns the interval duration in seconds.
Definition: qgsinterval.h:168
static QgsInterval fromString(const QString &string)
Converts a string to an interval.
Definition: qgsinterval.cpp:66
static const int HOUR
Seconds per hour.
Definition: qgsinterval.h:55
static const int WEEKS
Seconds per week.
Definition: qgsinterval.h:51
static const int DAY
Seconds per day.
Definition: qgsinterval.h:53
double weeks() const
Returns the interval duration in weeks.
Definition: qgsinterval.h:116
QgsInterval operator-(const QDateTime &dt1, const QDateTime &dt2)
Returns the interval between two datetimes.
QDebug operator<<(QDebug dbg, const QgsInterval &interval)
Debug string representation of interval.
A representation of the interval between two datetime values.
Definition: qgsinterval.h:40
QDateTime operator+(const QDateTime &start, const QgsInterval &interval)
Adds an interval to a datetime.
double days() const
Returns the interval duration in days.
Definition: qgsinterval.h:129
static const int MINUTE
Seconds per minute.
Definition: qgsinterval.h:57
double years() const
Returns the interval duration in years (based on an average year length)
Definition: qgsinterval.h:90
double minutes() const
Returns the interval duration in minutes.
Definition: qgsinterval.h:155
double hours() const
Returns the interval duration in hours.
Definition: qgsinterval.h:142
TemporalUnit
Temporal units.
Definition: qgsunittypes.h:149
QgsInterval()=default
Default constructor for QgsInterval.