QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 
24 /***************************************************************************
25  * This class is considered CRITICAL and any change MUST be accompanied with
26  * full unit tests in test_qgsinterval.py.
27  * See details in QEP #17
28  ****************************************************************************/
29 
31  : mSeconds( 0.0 )
32  , mValid( false )
33 {
34 
35 }
36 
38  : mSeconds( seconds )
39  , mValid( true )
40 { }
41 
42 bool QgsInterval::operator==( const QgsInterval& other ) const
43 {
44  if ( !mValid && !other.mValid )
45  return true;
46  else if ( mValid && other.mValid )
47  return qgsDoubleNear( mSeconds, other.mSeconds );
48  else
49  return false;
50 }
51 
53 {
54  int seconds = 0;
55  QRegExp rx( "([-+]?\\d?\\.?\\d+\\s+\\S+)", Qt::CaseInsensitive );
56  QStringList list;
57  int pos = 0;
58 
59  while (( pos = rx.indexIn( string, pos ) ) != -1 )
60  {
61  list << rx.cap( 1 );
62  pos += rx.matchedLength();
63  }
64 
66  map.insert( 1, QStringList() << "second" << "seconds" << QObject::tr( "second|seconds", "list of words separated by | which reference years" ).split( '|' ) );
67  map.insert( 0 + MINUTE, QStringList() << "minute" << "minutes" << QObject::tr( "minute|minutes", "list of words separated by | which reference minutes" ).split( '|' ) );
68  map.insert( 0 + HOUR, QStringList() << "hour" << "hours" << QObject::tr( "hour|hours", "list of words separated by | which reference minutes hours" ).split( '|' ) );
69  map.insert( 0 + DAY, QStringList() << "day" << "days" << QObject::tr( "day|days", "list of words separated by | which reference days" ).split( '|' ) );
70  map.insert( 0 + WEEKS, QStringList() << "week" << "weeks" << QObject::tr( "week|weeks", "wordlist separated by | which reference weeks" ).split( '|' ) );
71  map.insert( 0 + MONTHS, QStringList() << "month" << "months" << QObject::tr( "month|months", "list of words separated by | which reference months" ).split( '|' ) );
72  map.insert( 0 + YEARS, QStringList() << "year" << "years" << QObject::tr( "year|years", "list of words separated by | which reference years" ).split( '|' ) );
73 
74  Q_FOREACH ( const QString& match, list )
75  {
76  QStringList split = match.split( QRegExp( "\\s+" ) );
77  bool ok;
78  double value = split.at( 0 ).toDouble( &ok );
79  if ( !ok )
80  {
81  continue;
82  }
83 
84  bool matched = false;
86  for ( ; it != map.constEnd(); ++it )
87  {
88  int duration = it.key();
89  Q_FOREACH ( const QString& name, it.value() )
90  {
91  if ( match.contains( name, Qt::CaseInsensitive ) )
92  {
93  matched = true;
94  break;
95  }
96  }
97 
98  if ( matched )
99  {
100  seconds += value * duration;
101  break;
102  }
103  }
104  }
105 
106  // If we can't parse the string at all then we just return invalid
107  if ( seconds == 0 )
108  return QgsInterval();
109 
110  return QgsInterval( seconds );
111 }
112 
113 QDebug operator<<( QDebug dbg, const QgsInterval& interval )
114 {
115  if ( !interval.isValid() )
116  dbg.nospace() << "QgsInterval()";
117  else
118  dbg.nospace() << "QgsInterval(" << interval.seconds() << ")";
119  return dbg.maybeSpace();
120 }
121 
122 QgsInterval operator-( const QDateTime& dt1, const QDateTime& dt2 )
123 {
124  qint64 mSeconds = dt2.msecsTo( dt1 );
125  return QgsInterval( mSeconds / 1000.0 );
126 }
127 
128 QDateTime operator+( const QDateTime& start, const QgsInterval& interval )
129 {
130  return start.addMSecs( static_cast<qint64>( interval.seconds() * 1000.0 ) );
131 }
132 
133 QgsInterval operator-( const QDate& date1, const QDate& date2 )
134 {
135  qint64 seconds = static_cast< qint64 >( date2.daysTo( date1 ) ) * 24 * 60 * 60;
136  return QgsInterval( seconds );
137 }
138 
139 QgsInterval operator-( const QTime& time1, const QTime& time2 )
140 {
141  qint64 mSeconds = time2.msecsTo( time1 );
142  return QgsInterval( mSeconds / 1000.0 );
143 }
static const int YEARS
Seconds per year (average)
Definition: qgsinterval.h:41
int daysTo(const QDate &d) const
QString cap(int nth) const
bool isValid() const
Returns true if the interval is valid.
Definition: qgsinterval.h:142
static const int MONTHS
Seconds per month, based on 30 day month.
Definition: qgsinterval.h:43
QgsInterval()
Default constructor for QgsInterval.
Definition: qgsinterval.cpp:30
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
const_iterator constBegin() const
const T & at(int i) const
double seconds() const
Returns the interval duration in seconds.
Definition: qgsinterval.h:131
QDebug & nospace()
static QgsInterval fromString(const QString &string)
Converts a string to an interval.
Definition: qgsinterval.cpp:52
int msecsTo(const QTime &t) const
QString tr(const char *sourceText, const char *disambiguation, int n)
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:353
int matchedLength() const
static const int HOUR
Seconds per hour.
Definition: qgsinterval.h:49
int indexIn(const QString &str, int offset, CaretMode caretMode) const
const Key & key() const
static const int WEEKS
Seconds per week.
Definition: qgsinterval.h:45
const_iterator constEnd() const
const T & value() const
static const int DAY
Seconds per day.
Definition: qgsinterval.h:47
QDebug & maybeSpace()
bool contains(QChar ch, Qt::CaseSensitivity cs) const
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:34
QDateTime operator+(const QDateTime &start, const QgsInterval &interval)
Adds an interval to a datetime.
bool operator==(const QgsInterval &other) const
Definition: qgsinterval.cpp:42
static const int MINUTE
Seconds per minute.
Definition: qgsinterval.h:51
iterator insert(const Key &key, const T &value)
qint64 msecsTo(const QDateTime &other) const
QDateTime addMSecs(qint64 msecs) const