From 272cc272573e351af4d90a6e7dbf476f22c21359 Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 6 Dec 2023 15:10:26 +0200 Subject: [PATCH] tbel fix_bug tbDate parameters date as String with patter + locale --- .../thingsboard/script/api/tbel/TbDate.java | 58 ++++++++++--------- .../script/api/tbel/TbDateTest.java | 31 ++++++++-- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java index 7b950650f3..25feda75f2 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java @@ -54,19 +54,15 @@ public class TbDate implements Serializable, Cloneable { this.instant = Instant.now(); } - public TbDate(String s) { - this.instant = parseInstant(s); - } - - public TbDate(String s, String pattern) { - instant = parseInstant(s, pattern, localeUTC, ZoneId.systemDefault()); - } - - public TbDate(String s, String pattern, String localeStr) { - instant = parseInstant(s, pattern, Locale.forLanguageTag(localeStr), ZoneId.systemDefault()); - } - public TbDate(String s, String pattern, String localeStr, String zoneIdStr) { - instant = parseInstant(s, pattern, Locale.forLanguageTag(localeStr), ZoneId.of(zoneIdStr)); + public TbDate(String s, String... options) { + if (options.length <= 2) { + this.instant = parseInstant(s, options); + } else { + String pattern = options[0]; + String localeStr = options[1]; + String zoneIdStr = options[2]; + instant = parseInstant(s, pattern, Locale.forLanguageTag(localeStr), ZoneId.of(zoneIdStr)); + } } public TbDate(long dateMilliSecond) { @@ -487,22 +483,30 @@ public class TbDate implements Serializable, Cloneable { } } - private static Instant parseInstant(String s) { + private static Instant parseInstant(String s, String... options) { + Locale locale = options.length > 1 ? Locale.forLanguageTag( options[1]) : Locale.getDefault(); + DateTimeFormatter formatter = null; + if (options.length > 0) { + formatter = DateTimeFormatter.ofPattern(options[0], locale); + } else if (s.length() > 0 && Character.isDigit(s.charAt(0))) { + // assuming "2007-12-03T10:15:30.00Z" UTC instant + // assuming "2007-12-03T10:15:30.00" ZoneId.systemDefault() instant + // assuming "2007-12-03T10:15:30.00-04:00" TZ instant + // assuming "2007-12-03T10:15:30.00+04:00" TZ instant + formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME; + } else { + // assuming RFC-1123 value "Tue, 3 Jun 2008 11:05:30 GMT" + // assuming RFC-1123 value "Tue, 3 Jun 2008 11:05:30 GMT-02:00" + // assuming RFC-1123 value "Tue, 3 Jun 2008 11:05:30 -0200" + formatter = DateTimeFormatter.RFC_1123_DATE_TIME; + } try{ - if (s.length() > 0 && Character.isDigit(s.charAt(0))) { - // assuming "2007-12-03T10:15:30.00Z" UTC instant - // assuming "2007-12-03T10:15:30.00" ZoneId.systemDefault() instant - // assuming "2007-12-03T10:15:30.00-04:00" TZ instant - // assuming "2007-12-03T10:15:30.00+04:00" TZ instant - return OffsetDateTime.parse(s).toInstant(); - } - else { - // assuming RFC-1123 value "Tue, 3 Jun 2008 11:05:30 GMT-02:00" - return Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(s)); - } - } catch (final DateTimeParseException ex) { + return Instant.from(formatter.parse(s)); + } catch (Exception ex) { try { - if (s.length() > 0 && Character.isDigit(s.charAt(0))) { + if (options.length > 0) { + return parseInstant(s, options[0], locale, ZoneId.systemDefault()); + } else if (s.length() > 0 && Character.isDigit(s.charAt(0))) { long timeMS = parse(s); if (timeMS != -1) { return Instant.ofEpochMilli(timeMS); diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index 7aa0e2b7ea..2c8c07fb26 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -34,7 +34,6 @@ import java.time.Instant; import java.time.ZoneId; import java.util.ArrayList; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; @@ -351,16 +350,21 @@ class TbDateTest { stringDateTZ = "2023-09-06T01:04:05.00-04:00"; d = new TbDate(stringDateTZ); Assert.assertEquals("2023-09-06T05:04:05Z", d.toISOString()); - stringDateTZ = "2023-09-06T01:04:05.00+04:30:56"; + stringDateTZ = "2023-09-06T01:04:05.00+04:30:56"; d = new TbDate(stringDateTZ); Assert.assertEquals("2023-09-05T20:33:09Z", d.toISOString()); stringDateTZ = "2023-09-06T01:04:05.00-02:00"; d = new TbDate(stringDateTZ); Assert.assertEquals("2023-09-06T03:04:05Z", d.toISOString()); - // Without_TZ + // Without_TZ stringDateTZ = "2023-08-06T04:04:05.123"; d = new TbDate(stringDateTZ); Assert.assertEquals("2023-08-06 04:04:05", d.toLocaleString()); + // With pattern + locale - ok + String pattern = "hh:mm:ss a, EEE M/d/uuuu"; + stringDateTZ = "09:15:30 nachm., So. 10/09/2022"; + d = new TbDate(stringDateTZ, pattern, "de"); + Assert.assertEquals("2022-10-09 21:15:30", d.toLocaleString()); String stringDateRFC_1123 = "Sat, 3 Jun 2023 11:05:30 GMT"; d = new TbDate(stringDateRFC_1123); @@ -379,25 +383,36 @@ class TbDateTest { d = new TbDate(stringDateRFC_1123); Assert.assertEquals("2024-02-29T14:05:30Z", d.toISOString()); + + // failed TZ String expectedMessage = "Cannot parse value"; String finalStringDateZ_error0 = "2023-09-06T01:04:05.00+045"; Exception actual = assertThrows(ConversionException.class, () -> { new TbDate(finalStringDateZ_error0); }); assertTrue(actual.getMessage().contains(expectedMessage)); - + // failed TZ String finalStringDateZ_error1 = "2023-08-06T04:04:05.123+04:00:00:00"; actual = assertThrows(ConversionException.class, () -> { new TbDate(finalStringDateZ_error1); }); assertTrue(actual.getMessage().contains(expectedMessage)); - + // failed TZ String finalStringDateZ_error2 ="2023-08-06T04:04:05.123+4"; actual = assertThrows(ConversionException.class, () -> { new TbDate(finalStringDateZ_error2); }); + assertTrue(actual.getMessage().contains(expectedMessage)); + // The locale does not match the pattern + String finalStringDateZ_error3= "02:15:30 PM, Sun 10/09/2022"; + pattern = "hh:mm:ss a, EEE M/d/uuuu"; + String finalPattern = pattern; + actual = assertThrows(ConversionException.class, () -> { + new TbDate(finalStringDateZ_error3, finalPattern, "de"); + }); assertTrue(actual.getMessage().contains(expectedMessage)); + // failed DayOfWeek String stringDateRFC_1123_error = "Tue, 3 Jun 2023 11:05:30 GMT"; actual = assertThrows(ConversionException.class, () -> { new TbDate(stringDateRFC_1123_error); @@ -482,6 +497,12 @@ class TbDateTest { Assert.assertEquals("2023-09-07 08:04:05", d.toLocaleString()); } + @Test + void Test_DateString_With_Pattern() { + String pattern = "yyyy-MM-dd HH:mm:ss.SSSXXX"; + TbDate d = new TbDate("2023-08-06 04:04:05.000-04:00", pattern); + Assert.assertEquals("2023-08-06T08:04:05Z", d.toISOString()); + } @Test void Test_DateString_With_TZ() { int date = 7;