From c93c1ac454ddbff515b9dcaba27fd37b39c45039 Mon Sep 17 00:00:00 2001 From: automike Date: Tue, 7 May 2019 14:31:21 -0700 Subject: [PATCH] [built-in function] - [`$(date|diff|date1|date2|precision)`]: *NEW* function to derive the date-level difference between 2 dates (assume in standard format, `MM/dd/yyyy HH:mm:ss`). Use `precision` to control the return value. Signed-off-by: automike --- .../java/org/nexial/core/variable/Date.java | 46 +++++++++++++++++++ .../core/model/ExecutionContextTest.java | 20 +++++++- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/nexial/core/variable/Date.java b/src/main/java/org/nexial/core/variable/Date.java index 4c893c1aa..22217e864 100755 --- a/src/main/java/org/nexial/core/variable/Date.java +++ b/src/main/java/org/nexial/core/variable/Date.java @@ -36,6 +36,26 @@ public class Date { + enum DatePrecision { + YEAR(1000L * 60 * 60 * 24 * 365), + MONTH(1000L * 60 * 60 * 24 * 30), + WEEK(1000 * 60 * 60 * 24 * 7), + DAY(1000 * 60 * 60 * 24), + HOUR(1000 * 60 * 60), + MINUTE(1000 * 60), + SECOND(1000), + MILLISECOND(1); + + private double timestampDivider; + + DatePrecision(double timestampDivider) { this.timestampDivider = timestampDivider; } + + public String format(long timestamp) { + double diff = Math.abs(timestamp) / timestampDivider; + return diff == (long) diff ? ((long) diff) + "" : diff + ""; + } + } + private abstract class DateTransform { abstract Calendar transform(Calendar c); } @@ -104,6 +124,32 @@ public String addSecond(String date, String seconds) { public String setSecond(String date, int seconds) { return setDate(date, SECOND, seconds); } + /** + * assumed that {@code date1} and {@code date2} are both in the format of MM/dd/yyyy HH:mm:ss. + * {@code precision} should match to one of the predefined value in {@link DatePrecision} + */ + public String diff(String date1, String date2, String precision) { + java.util.Date d1 = parseDate(date1, STD_DATE_FORMAT); + if (d1 == null) { + ConsoleUtils.error("Unable to parse date1 in the standard format " + STD_DATE_FORMAT + ": " + date1); + return null; + } + + java.util.Date d2 = parseDate(date2, STD_DATE_FORMAT); + if (d2 == null) { + ConsoleUtils.error("Unable to parse date2 in the standard format " + STD_DATE_FORMAT + ": " + date2); + return null; + } + + try { + DatePrecision datePrecision = DatePrecision.valueOf(precision); + return datePrecision.format(d1.getTime() - d2.getTime()); + } catch (IllegalArgumentException e) { + ConsoleUtils.error("Unknown precision specified: " + precision); + return null; + } + } + protected java.util.Date parseDate(String date, String format) { if (StringUtils.isBlank(date)) { return null; } if (StringUtils.equals(format, EPOCH)) { return new java.util.Date(NumberUtils.toLong(date)); } diff --git a/src/test/java/org/nexial/core/model/ExecutionContextTest.java b/src/test/java/org/nexial/core/model/ExecutionContextTest.java index 638f33790..97f4987d4 100644 --- a/src/test/java/org/nexial/core/model/ExecutionContextTest.java +++ b/src/test/java/org/nexial/core/model/ExecutionContextTest.java @@ -224,7 +224,7 @@ public void replaceTokens_ignored() { } @Test - public void handleFunction() { + public void handleDateFunctions() { MockExecutionContext subject = initMockContext(); subject.setData("firstDOW", "04/30/2017"); @@ -236,6 +236,24 @@ public void handleFunction() { System.out.println(subject.handleFunction( "$(date|format|$(date|addDay|$(sysdate|firstDOW|MM/dd/yyyy)|1)|MM/dd/yyyy|MM/dd/yy)")); + // diff + subject.setData("date1", "04/30/2017 00:00:15"); + subject.setData("date2", "05/17/2017 21:49:22"); + Assert.assertEquals("17.91", + subject.handleFunction("$(format|number|$(date|diff|${date1}|${date2}|DAY)|###.00)")); + Assert.assertEquals("17.91", + subject.handleFunction("$(format|number|$(date|diff|${date1}|${date2}|DAY)|###.##)")); + Assert.assertEquals("2.6", subject.handleFunction("$(format|number|$(date|diff|${date2}|${date1}|WEEK)|0.#)")); + Assert.assertEquals("1", subject.handleFunction("$(format|number|$(date|diff|${date2}|${date1}|MONTH)|#)")); + Assert.assertEquals("0", subject.handleFunction("$(format|number|$(date|diff|${date2}|${date1}|YEAR)|0)")); + Assert.assertEquals("0430", + subject.handleFunction("$(format|number|$(date|diff|${date1}|${date2}|HOUR)|0000)")); + Assert.assertEquals("25789.1167", + subject.handleFunction("$(format|number|$(date|diff|${date1}|${date2}|MINUTE)|#.####)")); + Assert.assertEquals("1547347", subject.handleFunction("$(date|diff|${date1}|${date2}|SECOND)")); + Assert.assertEquals("1547347000", + subject.handleFunction("$(format|number|$(date|diff|${date1}|${date2}|MILLISECOND)|0000)")); + subject.cleanProject(); }