Skip to content

Commit da042bb

Browse files
committedMay 9, 2020
[feature][expressions] New expression function "make_interval"
Allows direct construction of interval values from years/months/weeks/ days/hours/minutes/second values, without having to construct a string representation of the interval first
1 parent ca64c6c commit da042bb

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed
 
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "make_interval",
3+
"type": "function",
4+
"description": "Creates an interval value from year, month, weeks, days, hours, minute and seconds values.",
5+
"arguments": [
6+
{"arg":"years","description":"Number of years (assumes a 365.25 day year length).", "optional": true, "default": "0"},
7+
{"arg":"months","description":"Number of months (assumes a 30 day month length)", "optional": true, "default": "0"},
8+
{"arg":"weeks","description":"Number of weeks", "optional": true, "default": "0"},
9+
{"arg":"days","description":"Number of days", "optional": true, "default": "0"},
10+
{"arg":"hours","description":"Number of hours", "optional": true, "default": "0"},
11+
{"arg":"minutes","description":"Number of minutes", "optional": true, "default": "0"},
12+
{"arg":"seconds","description":"Number of seconds", "optional": true, "default": "0"}
13+
],
14+
"examples": [
15+
{ "expression":"make_interval(hours:=3)", "returns":"3 hour interval"},
16+
{ "expression":"make_interval(days:=2, hours:=3)", "returns":"2 day, 3 hour interval"}
17+
]
18+
}

‎src/core/expression/qgsexpressionfunction.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,19 @@ static QVariant fcnMakeDateTime( const QVariantList &values, const QgsExpression
11571157
return QVariant( QDateTime( date, time ) );
11581158
}
11591159

1160+
static QVariant fcnMakeInterval( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
1161+
{
1162+
const int years = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
1163+
const int months = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
1164+
const int weeks = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
1165+
const int days = QgsExpressionUtils::getIntValue( values.at( 3 ), parent );
1166+
const int hours = QgsExpressionUtils::getIntValue( values.at( 4 ), parent );
1167+
const int minutes = QgsExpressionUtils::getIntValue( values.at( 5 ), parent );
1168+
const double seconds = QgsExpressionUtils::getDoubleValue( values.at( 6 ), parent );
1169+
1170+
return QVariant::fromValue( QgsInterval( years, months, weeks, days, hours, minutes, seconds ) );
1171+
}
1172+
11601173
static QVariant fcnCoalesce( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * )
11611174
{
11621175
for ( const QVariant &value : values )
@@ -5807,6 +5820,14 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
58075820
<< QgsExpressionFunction::Parameter( QStringLiteral( "minute" ) )
58085821
<< QgsExpressionFunction::Parameter( QStringLiteral( "second" ) ),
58095822
fcnMakeDateTime, QStringLiteral( "Date and Time" ) )
5823+
<< new QgsStaticExpressionFunction( QStringLiteral( "make_interval" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "years" ), true, 0 )
5824+
<< QgsExpressionFunction::Parameter( QStringLiteral( "months" ), true, 0 )
5825+
<< QgsExpressionFunction::Parameter( QStringLiteral( "weeks" ), true, 0 )
5826+
<< QgsExpressionFunction::Parameter( QStringLiteral( "days" ), true, 0 )
5827+
<< QgsExpressionFunction::Parameter( QStringLiteral( "hours" ), true, 0 )
5828+
<< QgsExpressionFunction::Parameter( QStringLiteral( "minutes" ), true, 0 )
5829+
<< QgsExpressionFunction::Parameter( QStringLiteral( "seconds" ), true, 0 ),
5830+
fcnMakeInterval, QStringLiteral( "Date and Time" ) )
58105831
<< new QgsStaticExpressionFunction( QStringLiteral( "lower" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), fcnLower, QStringLiteral( "String" ) )
58115832
<< new QgsStaticExpressionFunction( QStringLiteral( "upper" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), fcnUpper, QStringLiteral( "String" ) )
58125833
<< new QgsStaticExpressionFunction( QStringLiteral( "title" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), fcnTitle, QStringLiteral( "String" ) )

‎tests/src/core/testqgsexpression.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,6 +1369,14 @@ class TestQgsExpression: public QObject
13691369
QTest::newRow( "make datetime with ms" ) << "make_datetime(2012,7,8,13,6,28.5)" << false << QVariant( QDateTime( QDate( 2012, 7, 8 ), QTime( 13, 6, 28, 500 ) ) );
13701370
QTest::newRow( "make datetime invalid" ) << "make_datetime(2012,7,8,'a',6,28)" << true << QVariant();
13711371
QTest::newRow( "make datetime invalid 2" ) << "make_datetime(2012,7,8,2012,16,28)" << true << QVariant();
1372+
QTest::newRow( "make interval years" ) << "second(make_interval(years:=2))" << false << QVariant( 63115200.0 );
1373+
QTest::newRow( "make interval months" ) << "second(make_interval(months:=2))" << false << QVariant( 5184000.0 );
1374+
QTest::newRow( "make interval weeks" ) << "second(make_interval(weeks:=2))" << false << QVariant( 1209600.0 );
1375+
QTest::newRow( "make interval days" ) << "second(make_interval(days:=2))" << false << QVariant( 172800.0 );
1376+
QTest::newRow( "make interval hours" ) << "second(make_interval(hours:=2))" << false << QVariant( 7200.0 );
1377+
QTest::newRow( "make interval minutes" ) << "second(make_interval(minutes:=2))" << false << QVariant( 120.0 );
1378+
QTest::newRow( "make interval seconds" ) << "second(make_interval(seconds:=2))" << false << QVariant( 2.0 );
1379+
QTest::newRow( "make interval mixed" ) << "second(make_interval(2,3,4,5,6,7,8))" << false << QVariant( 73764428.0 );
13721380
QTest::newRow( "to date" ) << "todate('2012-06-28')" << false << QVariant( QDate( 2012, 6, 28 ) );
13731381
QTest::newRow( "to interval" ) << "tointerval('1 Year 1 Month 1 Week 1 Hour 1 Minute')" << false << QVariant::fromValue( QgsInterval( 34758060 ) );
13741382
QTest::newRow( "day with date" ) << "day('2012-06-28')" << false << QVariant( 28 );

0 commit comments

Comments
 (0)
Please sign in to comment.