Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functions DT_DATE_NOW and DT_DATE_TODAY #453

Merged
merged 6 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/references/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ Available through the _ExpressionConfiguration.StandardFunctionsDictionary_ cons
| DT_DATE_NEW(millis) | Returns a new DATE_TIME from the epoch of 1970-01-01T00:00:00Z in milliseconds. |
| DT_DATE_PARSE(value [,zoneId] [,format, ...]) | Converts the given string value to a date time value by using the optional time zone and formats. All formats are used until the first matching format. Without a format, the configured formats are used. Time zone can be NULL, the the configured time zone is used. |
| DT_DATE_FORMAT(value, [,format] [,zoneId]) | Formats the given date-time to a string using the given optional format and time zone. Without a format, the first configured format is used. The zone id defaults to the configured zone id. |
| DT_DATE_NOW() | Produces a new DATE_TIME that represents the current date and time, in the system default time zone. |
oswaldobapvicjr marked this conversation as resolved.
Show resolved Hide resolved
| DT_DATE_TODAY() | Produces a new DATE_TIME that represents the current date, at midnight (00:00), in the system default time zone. |
oswaldobapvicjr marked this conversation as resolved.
Show resolved Hide resolved
| DT_DATE_TO_EPOCH(value) | Converts the given value to epoch timestamp in millisecond. |
| DT_DURATION_NEW(days [,hours, minutes, seconds, nanos]) | Returns a new DURATION value with the given parameters. |
| DT_DURATION_PARSE(value) | Converts the given ISO-8601 duration string representation to a duration value. E.g. "P2DT3H4M" parses 2 days, 3 hours and 4 minutes. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ public class ExpressionConfiguration {
Map.entry("DT_DATE_NEW", new DateTimeNewFunction()),
Map.entry("DT_DATE_PARSE", new DateTimeParseFunction()),
Map.entry("DT_DATE_FORMAT", new DateTimeFormatFunction()),
Map.entry("DT_DATE_NOW", new DateTimeNowFunction()),
Map.entry("DT_DATE_TODAY", new DateTimeTodayFunction()),
Map.entry("DT_DATE_TO_EPOCH", new DateTimeToEpochFunction()),
Map.entry("DT_DURATION_NEW", new DurationNewFunction()),
Map.entry("DT_DURATION_FROM_MILLIS", new DurationFromMillisFunction()),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
Copyright 2012-2024 Udo Klimaschewski

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.ezylang.evalex.functions.datetime;

import com.ezylang.evalex.Expression;
import com.ezylang.evalex.data.EvaluationValue;
import com.ezylang.evalex.functions.AbstractFunction;
import com.ezylang.evalex.parser.Token;
import java.time.Instant;

/**
* Produces a new DATE_TIME that represents the current date and time.
*
* <p>It is useful to calculate a value based on the current date and time. For example, if you know
* the start DATE_TIME of a running process, you might use the following expression to find the
* DURATION that represents the process age:
*
* <blockquote>
*
* {@code DT_DATE_NOW() - startDateTime}
*
* </blockquote>
*
* @author oswaldobapvicjr
*/
public class DateTimeNowFunction extends AbstractFunction {
@Override
public EvaluationValue evaluate(
Expression expression, Token functionToken, EvaluationValue... parameterValues) {
return expression.convertValue(Instant.now());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Copyright 2012-2024 Udo Klimaschewski

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.ezylang.evalex.functions.datetime;

import com.ezylang.evalex.Expression;
import com.ezylang.evalex.data.EvaluationValue;
import com.ezylang.evalex.functions.AbstractFunction;
import com.ezylang.evalex.parser.Token;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;

/**
* Produces a new DATE_TIME that represents the current date, at midnight (00:00), in the system
* default time-zone.
*
* <p>It is useful for DATE_TIME comparison, when the current time must not be considered. For
* example, in the expression:
*
* <blockquote>
*
* {@code IF(expiryDate > DT_DATE_TODAY(), "expired", "valid")}
*
* </blockquote>
*
* @author oswaldobapvicjr
*/
public class DateTimeTodayFunction extends AbstractFunction {
@Override
public EvaluationValue evaluate(
Expression expression, Token functionToken, EvaluationValue... parameterValues) {
Instant today = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant();
return expression.convertValue(today);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,27 @@
import com.ezylang.evalex.config.ExpressionConfiguration;
import com.ezylang.evalex.config.TestConfigurationProvider;
import com.ezylang.evalex.parser.ParseException;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.TimeZone;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;

class DateTimeFunctionsTest extends BaseEvaluationTest {

private static final ZoneId DEFAULT_ZONE_ID = ZoneId.of("Europe/Berlin");

static {
// Let the default time-zone be set programmatically to standardize
// tests dependent on the default time-zone
TimeZone.setDefault(TimeZone.getTimeZone(DEFAULT_ZONE_ID));
oswaldobapvicjr marked this conversation as resolved.
Show resolved Hide resolved
}

private static final ExpressionConfiguration DateTimeTestConfiguration =
TestConfigurationProvider.StandardConfigurationWithAdditionalTestOperators.toBuilder()
.zoneId(ZoneId.of("Europe/Berlin"))
.zoneId(DEFAULT_ZONE_ID)
.build();

@ParameterizedTest
Expand Down Expand Up @@ -231,6 +241,24 @@ void testDateTimeToEpoch(String expression, String expectedResult)
assertExpressionHasExpectedResult(expression, expectedResult);
}

@ParameterizedTest
oswaldobapvicjr marked this conversation as resolved.
Show resolved Hide resolved
@CsvSource(
delimiter = '|',
value = {
"DT_DATE_NOW() > DT_DATE_TODAY() | true",
"DT_DATE_NOW() > (DT_DATE_TODAY() + DT_DURATION_PARSE(\"P1D\")) | false"
})
void testDateTimeNow(String expression, String expectedResult)
throws EvaluationException, ParseException {
assertExpressionHasExpectedResult(expression, expectedResult);
}

@Test
void testDateTimeToday() throws EvaluationException, ParseException {
String expected = LocalDate.now().atStartOfDay(DEFAULT_ZONE_ID).toInstant().toString();
assertExpressionHasExpectedResult("DT_DATE_TODAY()", expected, DateTimeTestConfiguration);
}

@ParameterizedTest
@CsvSource(
delimiter = '|',
Expand Down
Loading