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