Skip to content

Commit c467e79

Browse files
committedJun 30, 2012
Add expression functions for handling date/time:
- year,month,day,hour,minute,second extraction - new QgsInterval objects - handles time amounts - age() function returns the difference between two datetimes - $now returns the current date and time - support for datetime - interval = new datetime - tointerval, todate, totime functions - tests ;)
1 parent 4b81e36 commit c467e79

File tree

5 files changed

+413
-3
lines changed

5 files changed

+413
-3
lines changed
 

‎python/core/qgsexpression.sip

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
class QgsExpression
32
{
43
%TypeHeaderCode
@@ -304,7 +303,24 @@ public:
304303
virtual void visit( QgsExpression::NodeCondition* n ) = 0;
305304
};
306305

306+
class Interval
307+
{
308+
public:
309+
Interval(int seconds);
310+
~Interval();
311+
int years();
312+
int weeks();
313+
int days();
314+
int hours();
315+
int minutes();
316+
int seconds();
317+
bool isValid();
318+
void setValid(bool valid);
319+
bool operator==(const QgsExpression::Interval& other) const;
320+
static QgsExpression::Interval invalidInterVal();
321+
static QgsExpression::Interval fromString(QString string);
322+
};
323+
307324
/** entry function for the visitor pattern */
308325
void acceptVisitor( QgsExpression::Visitor& v );
309-
310326
};

‎src/core/qgsexpression.cpp

Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <QtDebug>
1919
#include <QDomDocument>
2020
#include <QSettings>
21+
#include <QDate>
22+
#include <QRegExp>
2123

2224
#include <math.h>
2325
#include <limits>
@@ -30,6 +32,79 @@
3032
// from parser
3133
extern QgsExpression::Node* parseExpression( const QString& str, QString& parserErrorMsg );
3234

35+
QgsExpression::Interval::~Interval() {}
36+
37+
QgsExpression::Interval QgsExpression::Interval::invalidInterVal()
38+
{
39+
QgsExpression::Interval inter = QgsExpression::Interval();
40+
inter.setValid( false );
41+
return inter;
42+
}
43+
44+
QgsExpression::Interval QgsExpression::Interval::fromString( QString string )
45+
{
46+
int seconds = 0;
47+
QRegExp rx( "(\\d?\\.?\\d+\\s+[a-z]+)", Qt::CaseInsensitive );
48+
QStringList list;
49+
int pos = 0;
50+
51+
while (( pos = rx.indexIn( string, pos ) ) != -1 )
52+
{
53+
list << rx.cap( 1 );
54+
pos += rx.matchedLength();
55+
}
56+
57+
foreach( QString match, list )
58+
{
59+
QStringList split = match.split( QRegExp( "\\s+" ) );
60+
bool ok;
61+
int value = split.at( 0 ).toInt( &ok );
62+
if ( !ok )
63+
{
64+
continue;
65+
}
66+
67+
if ( match.contains( "day", Qt::CaseInsensitive ) ||
68+
match.contains( QObject::tr("day", "Note: Word is part matched in code"), Qt::CaseInsensitive )||
69+
match.contains( QObject::tr("days", "Note: Word is part matched in code"), Qt::CaseInsensitive) )
70+
seconds += value * QgsExpression::Interval::DAY;
71+
if ( match.contains( "week", Qt::CaseInsensitive ) ||
72+
match.contains( QObject::tr("week", "Note: Word is part matched in code"), Qt::CaseInsensitive ) ||
73+
match.contains( QObject::tr("weeks", "Note: Word is part matched in code"), Qt::CaseInsensitive ) )
74+
seconds += value * QgsExpression::Interval::WEEKS;
75+
if ( match.contains( "month", Qt::CaseInsensitive ) ||
76+
match.contains( QObject::tr("month", "Note: Word is part matched in code"), Qt::CaseInsensitive ) ||
77+
match.contains( QObject::tr("months", "Note: Word is part matched in code"), Qt::CaseInsensitive ) )
78+
seconds += value * QgsExpression::Interval::MONTHS;
79+
if ( match.contains( "year", Qt::CaseInsensitive ) ||
80+
match.contains( QObject::tr("year", "Note: Word is part matched in code"), Qt::CaseInsensitive ) ||
81+
match.contains( QObject::tr("years", "Note: Word is part matched in code"), Qt::CaseInsensitive ) )
82+
seconds += value * QgsExpression::Interval::YEARS;
83+
if ( match.contains( "second", Qt::CaseInsensitive ) ||
84+
match.contains( QObject::tr("second", "Note: Word is part matched in code"), Qt::CaseInsensitive ) ||
85+
match.contains( QObject::tr("seconds", "Note: Word is part matched in code"), Qt::CaseInsensitive ) )
86+
seconds += value;
87+
if ( match.contains( "minute", Qt::CaseInsensitive ) ||
88+
match.contains( QObject::tr("minute", "Note: Word is part matched in code"), Qt::CaseInsensitive ) ||
89+
match.contains( QObject::tr("minutes", "Note: Word is part matched in code"), Qt::CaseInsensitive ) )
90+
seconds += value * QgsExpression::Interval::MINUTE;
91+
if ( match.contains( "hour", Qt::CaseInsensitive ) ||
92+
match.contains( QObject::tr("hour", "Note: Word is part matched in code"), Qt::CaseInsensitive ) ||
93+
match.contains( QObject::tr("hours", "Note: Word is part matched in code"), Qt::CaseInsensitive ) )
94+
seconds += value * QgsExpression::Interval::HOUR;
95+
}
96+
97+
// If we can't parse the string at all then we just return invalid
98+
if ( seconds == 0 )
99+
return QgsExpression::Interval::invalidInterVal();
100+
101+
return QgsExpression::Interval( seconds );
102+
}
103+
104+
bool QgsExpression::Interval::operator==( const QgsExpression::Interval& other ) const
105+
{
106+
return ( mSeconds == other.mSeconds );
107+
}
33108

34109
///////////////////////////////////////////////
35110
// three-value logic
@@ -91,6 +166,26 @@ inline bool isDoubleSafe( const QVariant& v )
91166
return false;
92167
}
93168

169+
inline bool isDateTimeSafe( const QVariant& v )
170+
{
171+
return v.type() == QVariant::DateTime || v.type() == QVariant::Date ||
172+
v.type() == QVariant::Time;
173+
}
174+
175+
inline bool isIntervalSafe( const QVariant& v )
176+
{
177+
if ( v.canConvert<QgsExpression::Interval>() )
178+
{
179+
return true;
180+
}
181+
182+
if ( v.type() == QVariant::String )
183+
{
184+
return QgsExpression::Interval::fromString( v.toString() ).isValid();
185+
}
186+
return false;
187+
}
188+
94189
inline bool isNull( const QVariant& v ) { return v.isNull(); }
95190

96191
///////////////////////////////////////////////
@@ -167,6 +262,65 @@ static int getIntValue( const QVariant& value, QgsExpression* parent )
167262
}
168263
}
169264

265+
static QDateTime getDateTimeValue( const QVariant& value, QgsExpression* parent )
266+
{
267+
QDateTime d = value.toDateTime();
268+
if ( d.isValid() )
269+
{
270+
return d;
271+
}
272+
else
273+
{
274+
parent->setEvalErrorString( QObject::tr( "Cannot convert '%1' to DateTime" ).arg( value.toString() ) );
275+
return QDateTime();
276+
}
277+
}
278+
279+
static QDate getDateValue( const QVariant& value, QgsExpression* parent )
280+
{
281+
QDate d = value.toDate();
282+
if ( d.isValid() )
283+
{
284+
return d;
285+
}
286+
else
287+
{
288+
parent->setEvalErrorString( QObject::tr( "Cannot convert '%1' to Date" ).arg( value.toString() ) );
289+
return QDate();
290+
}
291+
}
292+
293+
static QTime getTimeValue( const QVariant& value, QgsExpression* parent )
294+
{
295+
QTime t = value.toTime();
296+
if ( t.isValid() )
297+
{
298+
return t;
299+
}
300+
else
301+
{
302+
parent->setEvalErrorString( QObject::tr( "Cannot convert '%1' to Time" ).arg( value.toString() ) );
303+
return QTime();
304+
}
305+
}
306+
307+
static QgsExpression::Interval getInterval( const QVariant& value, QgsExpression* parent, bool report_error = false )
308+
{
309+
if ( value.canConvert<QgsExpression::Interval>() )
310+
return value.value<QgsExpression::Interval>();
311+
312+
QgsExpression::Interval inter = QgsExpression::Interval::fromString( value.toString() );
313+
if ( inter.isValid() )
314+
{
315+
return inter;
316+
}
317+
// If we get here then we can't convert so we just error and return invalid.
318+
if ( report_error )
319+
parent->setEvalErrorString( QObject::tr( "Cannot convert '%1' to Interval" ).arg( value.toString() ) );
320+
321+
return QgsExpression::Interval::invalidInterVal();
322+
}
323+
170324

171325
// this handles also NULL values
172326
static TVL getTVLValue( const QVariant& value, QgsExpression* parent )
@@ -270,6 +424,12 @@ static QVariant fcnToString( const QVariantList& values, QgsFeature* , QgsExpres
270424
{
271425
return QVariant( getStringValue( values.at( 0 ), parent ) );
272426
}
427+
428+
static QVariant fcnToDateTime( const QVariantList& values, QgsFeature* , QgsExpression* parent )
429+
{
430+
return QVariant( getDateTimeValue( values.at( 0 ), parent ) );
431+
}
432+
273433
static QVariant fcnCoalesce( const QVariantList& values, QgsFeature* , QgsExpression* )
274434
{
275435
foreach( const QVariant &value, values )
@@ -344,6 +504,140 @@ static QVariant fcnConcat( const QVariantList& values, QgsFeature* , QgsExpressi
344504
return concat;
345505
}
346506

507+
static QVariant fcnNow( const QVariantList&, QgsFeature* , QgsExpression * )
508+
{
509+
return QVariant( QDateTime::currentDateTime() );
510+
}
511+
512+
static QVariant fcnToDate( const QVariantList& values, QgsFeature* , QgsExpression * parent )
513+
{
514+
return QVariant( getDateValue( values.at( 0 ), parent ) );
515+
}
516+
517+
static QVariant fcnToTime( const QVariantList& values, QgsFeature* , QgsExpression * parent )
518+
{
519+
return QVariant( getTimeValue( values.at( 0 ), parent ) );
520+
}
521+
522+
static QVariant fcnToInterval( const QVariantList& values, QgsFeature* , QgsExpression * parent )
523+
{
524+
return QVariant::fromValue( getInterval( values.at( 0 ), parent ) );
525+
}
526+
527+
static QVariant fcnAge( const QVariantList& values, QgsFeature* , QgsExpression *parent )
528+
{
529+
QDateTime d1 = getDateTimeValue( values.at( 0 ), parent );
530+
QDateTime d2 = getDateTimeValue( values.at( 1 ), parent );
531+
int seconds = d2.secsTo( d1 );
532+
return QVariant::fromValue( QgsExpression::Interval( seconds ) );
533+
}
534+
535+
static QVariant fcnDay( const QVariantList& values, QgsFeature* , QgsExpression *parent )
536+
{
537+
QVariant value = values.at( 0 );
538+
QgsExpression::Interval inter = getInterval( value, parent, false );
539+
if ( inter.isValid() )
540+
{
541+
return QVariant( inter.days() );
542+
}
543+
else
544+
{
545+
QDateTime d1 = getDateTimeValue( value, parent );
546+
return QVariant( d1.date().day() );
547+
}
548+
}
549+
550+
static QVariant fcnYear( const QVariantList& values, QgsFeature* , QgsExpression *parent )
551+
{
552+
QVariant value = values.at( 0 );
553+
QgsExpression::Interval inter = getInterval( value, parent, false );
554+
if ( inter.isValid() )
555+
{
556+
return QVariant( inter.years() );
557+
}
558+
else
559+
{
560+
QDateTime d1 = getDateTimeValue( value, parent );
561+
return QVariant( d1.date().year() );
562+
}
563+
}
564+
565+
static QVariant fcnMonth( const QVariantList& values, QgsFeature* , QgsExpression *parent )
566+
{
567+
QVariant value = values.at( 0 );
568+
QgsExpression::Interval inter = getInterval( value, parent, false );
569+
if ( inter.isValid() )
570+
{
571+
return QVariant( inter.months() );
572+
}
573+
else
574+
{
575+
QDateTime d1 = getDateTimeValue( value, parent );
576+
return QVariant( d1.date().month() );
577+
}
578+
}
579+
580+
static QVariant fcnWeek( const QVariantList& values, QgsFeature* , QgsExpression *parent )
581+
{
582+
QVariant value = values.at( 0 );
583+
QgsExpression::Interval inter = getInterval( value, parent, false );
584+
if ( inter.isValid() )
585+
{
586+
return QVariant( inter.weeks() );
587+
}
588+
else
589+
{
590+
QDateTime d1 = getDateTimeValue( value, parent );
591+
return QVariant( d1.date().weekNumber() );
592+
}
593+
}
594+
595+
static QVariant fcnHour( const QVariantList& values, QgsFeature* , QgsExpression *parent )
596+
{
597+
QVariant value = values.at( 0 );
598+
QgsExpression::Interval inter = getInterval( value, parent, false );
599+
if ( inter.isValid() )
600+
{
601+
return QVariant( inter.hours() );
602+
}
603+
else
604+
{
605+
QDateTime d1 = getDateTimeValue( value, parent );
606+
return QVariant( d1.time().hour() );
607+
}
608+
}
609+
610+
static QVariant fcnMinute( const QVariantList& values, QgsFeature* , QgsExpression *parent )
611+
{
612+
QVariant value = values.at( 0 );
613+
QgsExpression::Interval inter = getInterval( value, parent, false );
614+
if ( inter.isValid() )
615+
{
616+
return QVariant( inter.minutes() );
617+
}
618+
else
619+
{
620+
QDateTime d1 = getDateTimeValue( value, parent );
621+
return QVariant( d1.time().minute() );
622+
}
623+
}
624+
625+
static QVariant fcnSeconds( const QVariantList& values, QgsFeature* , QgsExpression *parent )
626+
{
627+
QVariant value = values.at( 0 );
628+
QgsExpression::Interval inter = getInterval( value, parent, false );
629+
if ( inter.isValid() )
630+
{
631+
return QVariant( inter.seconds() );
632+
}
633+
else
634+
{
635+
QDateTime d1 = getDateTimeValue( value, parent );
636+
return QVariant( d1.time().second() );
637+
}
638+
}
639+
640+
347641
#define ENSURE_GEOM_TYPE(f, g, geomtype) if (!f) return QVariant(); \
348642
QgsGeometry* g = f->geometry(); \
349643
if (!g || g->type() != geomtype) return QVariant();
@@ -450,7 +744,21 @@ const QList<QgsExpression::FunctionDef> &QgsExpression::BuiltinFunctions()
450744
<< FunctionDef( "toint", 1, fcnToInt, QObject::tr( "Conversions" ) )
451745
<< FunctionDef( "toreal", 1, fcnToReal, QObject::tr( "Conversions" ) )
452746
<< FunctionDef( "tostring", 1, fcnToString, QObject::tr( "Conversions" ) )
747+
<< FunctionDef( "todatetime", 1, fcnToDateTime, QObject::tr( "Conversions" ) )
748+
<< FunctionDef( "todate", 1, fcnToDate, QObject::tr( "Conversions" ) )
749+
<< FunctionDef( "totime", 1, fcnToTime, QObject::tr( "Conversions" ) )
750+
<< FunctionDef( "tointerval", 1, fcnToInterval, QObject::tr( "Conversions" ) )
453751
<< FunctionDef( "coalesce", -1, fcnCoalesce, QObject::tr( "Conversions" ) )
752+
// date/time
753+
<< FunctionDef( "$now", 0, fcnNow, QObject::tr( "Date/Time" ) )
754+
<< FunctionDef( "age", 2, fcnAge, QObject::tr( "Date/Time" ) )
755+
<< FunctionDef( "year", 1, fcnYear, QObject::tr( "Date/Time" ) )
756+
<< FunctionDef( "month", 1, fcnMonth, QObject::tr( "Date/Time" ) )
757+
<< FunctionDef( "week", 1, fcnWeek, QObject::tr( "Date/Time" ) )
758+
<< FunctionDef( "day", 1, fcnDay, QObject::tr( "Date/Time" ) )
759+
<< FunctionDef( "hour", 1, fcnHour, QObject::tr( "Date/Time" ) )
760+
<< FunctionDef( "minute", 1, fcnMinute, QObject::tr( "Date/Time" ) )
761+
<< FunctionDef( "second", 1, fcnSeconds, QObject::tr( "Date/Time" ) )
454762
// string manipulation
455763
<< FunctionDef( "lower", 1, fcnLower, QObject::tr( "String" ) )
456764
<< FunctionDef( "upper", 1, fcnUpper, QObject::tr( "String" ) )
@@ -905,6 +1213,17 @@ QVariant QgsExpression::NodeBinaryOperator::eval( QgsExpression* parent, QgsFeat
9051213
if ( mOp == boDiv && iR == 0 ) return QVariant(); // silently handle division by zero and return NULL
9061214
return QVariant( computeInt( iL, iR ) );
9071215
}
1216+
else if ( isDateTimeSafe( vL ) && isIntervalSafe( vR ) )
1217+
{
1218+
QDateTime dL = getDateTimeValue( vL, parent ); ENSURE_NO_EVAL_ERROR;
1219+
QgsExpression::Interval iL = getInterval( vR, parent ); ENSURE_NO_EVAL_ERROR;
1220+
if ( mOp == boDiv || mOp == boMul || mOp == boMod )
1221+
{
1222+
parent->setEvalErrorString( QObject::tr("Can't preform /, *, or % on DateTime and Interval") );
1223+
return QVariant();
1224+
}
1225+
return QVariant( computeDateTimeFromInterval( dL, &iL ) );
1226+
}
9081227
else
9091228
{
9101229
// general floating point arithmetic
@@ -1068,6 +1387,16 @@ int QgsExpression::NodeBinaryOperator::computeInt( int x, int y )
10681387
}
10691388
}
10701389

1390+
QDateTime QgsExpression::NodeBinaryOperator::computeDateTimeFromInterval( QDateTime d, QgsExpression::Interval *i )
1391+
{
1392+
switch ( mOp )
1393+
{
1394+
case boPlus: return d.addSecs( i->seconds() );
1395+
case boMinus: return d.addSecs( -i->seconds() );
1396+
default: Q_ASSERT( false ); return QDateTime();
1397+
}
1398+
}
1399+
10711400
double QgsExpression::NodeBinaryOperator::computeDouble( double x, double y )
10721401
{
10731402
switch ( mOp )

‎src/core/qgsexpression.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#ifndef QGSEXPRESSION_H
1717
#define QGSEXPRESSION_H
1818

19+
#include <QMetaType>
1920
#include <QStringList>
2021
#include <QVariant>
2122
#include <QList>
@@ -256,6 +257,36 @@ class CORE_EXPORT QgsExpression
256257
QList<Node*> mList;
257258
};
258259

260+
class CORE_EXPORT Interval
261+
{
262+
// YEAR const value taken from postgres query
263+
// SELECT EXTRACT(EPOCH FROM interval '1 year')
264+
static const double YEARS = ( 31557600 );
265+
static const double MONTHS = ( 60 * 60 * 24 * 30 );
266+
static const double WEEKS = ( 60 * 60 * 24 * 7 );
267+
static const double DAY = ( 60 * 60 * 24 );
268+
static const double HOUR = ( 60 * 60 );
269+
static const double MINUTE = ( 60 );
270+
public:
271+
Interval( double seconds = 0 ) { mSeconds = seconds; }
272+
~Interval();
273+
double years() { return mSeconds / YEARS;}
274+
double months() { return mSeconds / MONTHS; }
275+
double weeks() { return mSeconds / WEEKS;}
276+
double days() { return mSeconds / DAY;}
277+
double hours() { return mSeconds / HOUR;}
278+
double minutes() { return mSeconds / MINUTE;}
279+
bool isValid() { return mValid; }
280+
void setValid( bool valid ) { mValid = valid; }
281+
double seconds() { return mSeconds; }
282+
bool operator==( const QgsExpression::Interval& other ) const;
283+
static QgsExpression::Interval invalidInterVal();
284+
static QgsExpression::Interval fromString( QString string );
285+
private:
286+
double mSeconds;
287+
bool mValid;
288+
};
289+
259290
class CORE_EXPORT NodeUnaryOperator : public Node
260291
{
261292
public:
@@ -306,6 +337,7 @@ class CORE_EXPORT QgsExpression
306337
bool compare( double diff );
307338
int computeInt( int x, int y );
308339
double computeDouble( double x, double y );
340+
QDateTime computeDateTimeFromInterval( QDateTime d, QgsExpression::Interval *i );
309341

310342
BinaryOperator mOp;
311343
Node* mOpLeft;
@@ -483,4 +515,6 @@ class CORE_EXPORT QgsExpression
483515
QgsDistanceArea* mCalc;
484516
};
485517

518+
Q_DECLARE_METATYPE( QgsExpression::Interval )
519+
486520
#endif // QGSEXPRESSION_H

‎src/core/qgsexpressionparser.yy

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ expression:
165165
exp_error("Function is not known");
166166
YYERROR;
167167
}
168-
if ( QgsExpression::BuiltinFunctions()[fnIndex].mParams != -1 && QgsExpression::BuiltinFunctions()[fnIndex].mParams != $3->count() )
168+
if ( QgsExpression::BuiltinFunctions()[fnIndex].mParams != -1
169+
&& QgsExpression::BuiltinFunctions()[fnIndex].mParams != $3->count() )
169170
{
170171
exp_error("Function is called with wrong number of arguments");
171172
YYERROR;

‎tests/src/core/testqgsexpression.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,18 @@ class TestQgsExpression: public QObject
270270
QTest::newRow( "condition else" ) << "case when 1=0 then 'bad' else 678 end" << false << QVariant( 678 );
271271
QTest::newRow( "condition null" ) << "case when length(123)=0 then 111 end" << false << QVariant();
272272
QTest::newRow( "condition 2 when" ) << "case when 2>3 then 23 when 3>2 then 32 else 0 end" << false << QVariant( 32 );
273+
274+
// Datetime functions
275+
QTest::newRow( "to date" ) << "todate('2012-06-28')" << false << QVariant( QDate( 2012, 06, 28 ) );
276+
QTest::newRow( "to interval" ) << "tointerval('1 Year 1 Month 1 Week 1 Hour 1 Minute')" << false << QVariant::fromValue( QgsExpression::Interval( 34758060 ) );
277+
QTest::newRow( "day with date" ) << "day('2012-06-28')" << false << QVariant( 28 );
278+
QTest::newRow( "day with interval" ) << "day(tointerval('28 days'))" << false << QVariant( 28.0 );
279+
QTest::newRow( "month with date" ) << "month('2012-06-28')" << false << QVariant( 6 );
280+
QTest::newRow( "month with interval" ) << "month(tointerval('2 months'))" << false << QVariant( 2.0 );
281+
QTest::newRow( "year with date" ) << "year('2012-06-28')" << false << QVariant( 2012 );
282+
QTest::newRow( "year with interval" ) << "year(tointerval('2 years'))" << false << QVariant( 2.0 );
283+
QTest::newRow( "age" ) << "age('2012-06-30','2012-06-28')" << false << QVariant::fromValue( QgsExpression::Interval( 172800 ) );
284+
QTest::newRow( "negative age" ) << "age('2012-06-28','2012-06-30')" << false << QVariant::fromValue( QgsExpression::Interval( -172800 ) );
273285
}
274286

275287
void evaluation()
@@ -280,6 +292,8 @@ class TestQgsExpression: public QObject
280292

281293
QgsExpression exp( string );
282294
QCOMPARE( exp.hasParserError(), false );
295+
if ( exp.hasParserError() )
296+
qDebug() << exp.parserErrorString();
283297

284298
QVariant res = exp.evaluate();
285299
if ( exp.hasEvalError() )
@@ -305,6 +319,22 @@ class TestQgsExpression: public QObject
305319
case QVariant::String:
306320
QCOMPARE( res.toString(), result.toString() );
307321
break;
322+
case QVariant::Date:
323+
QCOMPARE( res.toDate(), result.toDate() );
324+
break;
325+
case QVariant::DateTime:
326+
QCOMPARE( res.toDateTime(), result.toDateTime() );
327+
break;
328+
case QVariant::Time:
329+
QCOMPARE( res.toTime(), result.toTime() );
330+
break;
331+
case QVariant::UserType:
332+
{
333+
QgsExpression::Interval inter = res.value<QgsExpression::Interval>();
334+
QgsExpression::Interval gotinter = result.value<QgsExpression::Interval>();
335+
QCOMPARE( inter.seconds(), gotinter.seconds() );
336+
break;
337+
}
308338
default:
309339
Q_ASSERT( false ); // should never happen
310340
}

0 commit comments

Comments
 (0)
Please sign in to comment.