QGIS API Documentation  3.2.0-Bonn (bc43194)
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 
30 QgsInterval::QgsInterval( double seconds )
31  : mSeconds( seconds )
32  , mValid( true )
33 { }
34 
36 {
37  if ( !mValid && !other.mValid )
38  return true;
39  else if ( mValid && other.mValid )
40  return qgsDoubleNear( mSeconds, other.mSeconds );
41  else
42  return false;
43 }
44 
45 QgsInterval QgsInterval::fromString( const QString &string )
46 {
47  double seconds = 0;
48  QRegExp rx( "([-+]?\\d*\\.?\\d+\\s+\\S+)", Qt::CaseInsensitive );
49  QStringList list;
50  int pos = 0;
51 
52  while ( ( pos = rx.indexIn( string, pos ) ) != -1 )
53  {
54  list << rx.cap( 1 );
55  pos += rx.matchedLength();
56  }
57 
58  QMap<int, QStringList> map;
59  map.insert( 1, QStringList() << QStringLiteral( "second" ) << QStringLiteral( "seconds" ) << QObject::tr( "second|seconds", "list of words separated by | which reference years" ).split( '|' ) );
60  map.insert( 0 + MINUTE, QStringList() << QStringLiteral( "minute" ) << QStringLiteral( "minutes" ) << QObject::tr( "minute|minutes", "list of words separated by | which reference minutes" ).split( '|' ) );
61  map.insert( 0 + HOUR, QStringList() << QStringLiteral( "hour" ) << QStringLiteral( "hours" ) << QObject::tr( "hour|hours", "list of words separated by | which reference minutes hours" ).split( '|' ) );
62  map.insert( 0 + DAY, QStringList() << QStringLiteral( "day" ) << QStringLiteral( "days" ) << QObject::tr( "day|days", "list of words separated by | which reference days" ).split( '|' ) );
63  map.insert( 0 + WEEKS, QStringList() << QStringLiteral( "week" ) << QStringLiteral( "weeks" ) << QObject::tr( "week|weeks", "wordlist separated by | which reference weeks" ).split( '|' ) );
64  map.insert( 0 + MONTHS, QStringList() << QStringLiteral( "month" ) << QStringLiteral( "months" ) << QObject::tr( "month|months", "list of words separated by | which reference months" ).split( '|' ) );
65  map.insert( 0 + YEARS, QStringList() << QStringLiteral( "year" ) << QStringLiteral( "years" ) << QObject::tr( "year|years", "list of words separated by | which reference years" ).split( '|' ) );
66 
67  Q_FOREACH ( const QString &match, list )
68  {
69  QStringList split = match.split( QRegExp( "\\s+" ) );
70  bool ok;
71  double value = split.at( 0 ).toDouble( &ok );
72  if ( !ok )
73  {
74  continue;
75  }
76 
77  bool matched = false;
78  QMap<int, QStringList>::const_iterator it = map.constBegin();
79  for ( ; it != map.constEnd(); ++it )
80  {
81  int duration = it.key();
82  Q_FOREACH ( const QString &name, it.value() )
83  {
84  if ( match.contains( name, Qt::CaseInsensitive ) )
85  {
86  matched = true;
87  break;
88  }
89  }
90 
91  if ( matched )
92  {
93  seconds += value * duration;
94  break;
95  }
96  }
97  }
98 
99  // If we can't parse the string at all then we just return invalid
100  if ( seconds == 0 )
101  return QgsInterval();
102 
103  return QgsInterval( seconds );
104 }
105 
106 QDebug operator<<( QDebug dbg, const QgsInterval &interval )
107 {
108  if ( !interval.isValid() )
109  dbg.nospace() << "QgsInterval()";
110  else
111  dbg.nospace() << "QgsInterval(" << interval.seconds() << ")";
112  return dbg.maybeSpace();
113 }
114 
115 QgsInterval operator-( const QDateTime &dt1, const QDateTime &dt2 )
116 {
117  qint64 mSeconds = dt2.msecsTo( dt1 );
118  return QgsInterval( mSeconds / 1000.0 );
119 }
120 
121 QDateTime operator+( const QDateTime &start, QgsInterval interval )
122 {
123  return start.addMSecs( static_cast<qint64>( interval.seconds() * 1000.0 ) );
124 }
125 
126 QgsInterval operator-( QDate date1, QDate date2 )
127 {
128  qint64 seconds = static_cast< qint64 >( date2.daysTo( date1 ) ) * 24 * 60 * 60;
129  return QgsInterval( seconds );
130 }
131 
132 QgsInterval operator-( QTime time1, QTime time2 )
133 {
134  qint64 mSeconds = time2.msecsTo( time1 );
135  return QgsInterval( mSeconds / 1000.0 );
136 }
static const int YEARS
Seconds per year (average)
Definition: qgsinterval.h:46
bool operator==(QgsInterval other) const
Definition: qgsinterval.cpp:35
bool isValid() const
Returns true if the interval is valid.
Definition: qgsinterval.h:164
static const int MONTHS
Seconds per month, based on 30 day month.
Definition: qgsinterval.h:48
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:251
double seconds() const
Returns the interval duration in seconds.
Definition: qgsinterval.h:151
static QgsInterval fromString(const QString &string)
Converts a string to an interval.
Definition: qgsinterval.cpp:45
static const int HOUR
Seconds per hour.
Definition: qgsinterval.h:54
static const int WEEKS
Seconds per week.
Definition: qgsinterval.h:50
QDateTime operator+(const QDateTime &start, QgsInterval interval)
static const int DAY
Seconds per day.
Definition: qgsinterval.h:52
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:39
static const int MINUTE
Seconds per minute.
Definition: qgsinterval.h:56
QgsInterval()=default
Default constructor for QgsInterval.