Skip to content

Commit

Permalink
Merge pull request #32551 from rduivenvoorde/from_epoch
Browse files Browse the repository at this point in the history
[FEATURE] Add datetime_from_epoch (MSec from epoch) expression function
  • Loading branch information
m-kuhn committed Nov 22, 2019
2 parents baf3819 + 564f9fb commit 63911c1
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 0 deletions.
7 changes: 7 additions & 0 deletions resources/function_help/json/from_epoch
@@ -0,0 +1,7 @@
{
"name": "datetime_from_epoch",
"type": "function",
"description": "Returns a datetime whose date and time are the number of milliseconds, msecs, that have passed since 1970-01-01T00:00:00.000, Coordinated Universal Time (Qt.UTC), and converted to Qt.LocalTime.",
"arguments": [ {"arg":"int","description":"number (milliseconds)"} ],
"examples": [ { "expression":"datetime_from_epoch(1483225200000)", "returns":"2017-01-01T00:00:00"} ]
}
8 changes: 8 additions & 0 deletions src/core/expression/qgsexpressionfunction.cpp
Expand Up @@ -2012,6 +2012,13 @@ static QVariant fcnEpoch( const QVariantList &values, const QgsExpressionContext
}
}

static QVariant fcnDateTimeFromEpoch( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
{
long long millisecs_since_epoch = QgsExpressionUtils::getIntValue( values.at( 0 ), parent );
// no sense to check for strange values, as Qt behavior is undefined anyway (see docs)
return QVariant( QDateTime::fromMSecsSinceEpoch( millisecs_since_epoch ) );
}

#define ENSURE_GEOM_TYPE(f, g, geomtype) \
if ( !(f).hasGeometry() ) \
return QVariant(); \
Expand Down Expand Up @@ -5354,6 +5361,7 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
<< new QgsStaticExpressionFunction( QStringLiteral( "minute" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "datetime" ) ), fcnMinute, QStringLiteral( "Date and Time" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "second" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "datetime" ) ), fcnSeconds, QStringLiteral( "Date and Time" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "epoch" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "date" ) ), fcnEpoch, QStringLiteral( "Date and Time" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "datetime_from_epoch" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "long" ) ), fcnDateTimeFromEpoch, QStringLiteral( "Date and Time" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "day_of_week" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "date" ) ), fcnDayOfWeek, QStringLiteral( "Date and Time" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "lower" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), fcnLower, QStringLiteral( "String" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "upper" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), fcnUpper, QStringLiteral( "String" ) )
Expand Down
3 changes: 3 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -1293,6 +1293,9 @@ class TestQgsExpression: public QObject
QTest::newRow( "time - time" ) << "to_time('08:30:00') - to_time('05:15:00')" << false << QVariant( QgsInterval( 3 * 60 * 60 + 15 * 60 ) );
QTest::newRow( "epoch" ) << "epoch(to_datetime('2017-01-01T00:00:01+00:00'))" << false << QVariant( 1483228801000LL );
QTest::newRow( "epoch invalid date" ) << "epoch('invalid')" << true << QVariant();
// datetime_from_epoch will always return a local datetime, so here we create some circular magic to create a local datetime during test (so test can be ran in every timezone...)
QTest::newRow( "datetime_from_epoch" ) << "datetime_from_epoch(epoch(to_datetime('2017-01-01T00:00:01')))" << false << QVariant( QDateTime( QDate( 2017, 1, 1 ), QTime( 0, 0, 1 ), Qt::LocalTime ) );
QTest::newRow( "datetime_from_epoch_null" ) << "datetime_from_epoch(NULL)" << false << QVariant( QVariant::Invalid );
QTest::newRow( "date from format" ) << "to_date('June 29, 2019','MMMM d, yyyy')" << false << QVariant( QDate( 2019, 6, 29 ) );
QTest::newRow( "date from format and language" ) << "to_date('29 juin, 2019','d MMMM, yyyy','fr')" << false << QVariant( QDate( 2019, 6, 29 ) );
QTest::newRow( "date from format, wrong string" ) << "to_date('wrong.string.here','yyyy.MM.dd')" << true << QVariant();
Expand Down

0 comments on commit 63911c1

Please sign in to comment.