diff --git a/alerter/src/main/java/org/apache/hertzbeat/alert/dto/GeneralCloudAlertReport.java b/alerter/src/main/java/org/apache/hertzbeat/alert/dto/GeneralCloudAlertReport.java index cc81d886126..8d71953759d 100644 --- a/alerter/src/main/java/org/apache/hertzbeat/alert/dto/GeneralCloudAlertReport.java +++ b/alerter/src/main/java/org/apache/hertzbeat/alert/dto/GeneralCloudAlertReport.java @@ -17,6 +17,7 @@ package org.apache.hertzbeat.alert.dto; +import java.util.Optional; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -54,10 +55,18 @@ public void refreshAlertTime() { if (StringUtils.isNotBlank(alertDateTime)) { Long timeStamp = null; if (StringUtils.isNotBlank(dateTimeFormat)) { - timeStamp = DateUtil.getTimeStampFromFormat(alertDateTime, dateTimeFormat); + Optional tsf = DateUtil.getTimeStampFromFormat(alertDateTime, dateTimeFormat); + boolean present = tsf.isPresent(); + if (present) { + timeStamp = tsf.get(); + } } if (timeStamp == null) { - timeStamp = DateUtil.getTimeStampFromSomeFormats(alertDateTime); + Optional tsf = DateUtil.getTimeStampFromSomeFormats(alertDateTime); + boolean present = tsf.isPresent(); + if (present) { + timeStamp = tsf.get(); + } } if (timeStamp != null) { setAlertTime(timeStamp); diff --git a/alerter/src/main/java/org/apache/hertzbeat/alert/dto/TenCloudAlertReport.java b/alerter/src/main/java/org/apache/hertzbeat/alert/dto/TenCloudAlertReport.java index 93f81ba36cc..6ea51c1b047 100644 --- a/alerter/src/main/java/org/apache/hertzbeat/alert/dto/TenCloudAlertReport.java +++ b/alerter/src/main/java/org/apache/hertzbeat/alert/dto/TenCloudAlertReport.java @@ -132,7 +132,9 @@ public Integer getAlertDuration() { @Override public long getAlertTime() { - return DateUtil.getTimeStampFromFormat(getFirstOccurTime(), "yyyy-MM-dd HH:mm:ss"); + + return DateUtil.getTimeStampFromFormat(getFirstOccurTime(), "yyyy-MM-dd HH:mm:ss") + .orElse(0L); } @Override diff --git a/alerter/src/main/java/org/apache/hertzbeat/alert/util/AlertTemplateUtil.java b/alerter/src/main/java/org/apache/hertzbeat/alert/util/AlertTemplateUtil.java index 1efb010d5bb..8ae100b4850 100644 --- a/alerter/src/main/java/org/apache/hertzbeat/alert/util/AlertTemplateUtil.java +++ b/alerter/src/main/java/org/apache/hertzbeat/alert/util/AlertTemplateUtil.java @@ -26,7 +26,10 @@ * Alarm template keyword matching replacement engine tool */ @Slf4j -public class AlertTemplateUtil { +public final class AlertTemplateUtil { + + private AlertTemplateUtil() { + } /** * Match the variable ${key} diff --git a/alerter/src/main/java/org/apache/hertzbeat/alert/util/DateUtil.java b/alerter/src/main/java/org/apache/hertzbeat/alert/util/DateUtil.java index cba3c753074..55b0104eb9e 100644 --- a/alerter/src/main/java/org/apache/hertzbeat/alert/util/DateUtil.java +++ b/alerter/src/main/java/org/apache/hertzbeat/alert/util/DateUtil.java @@ -17,17 +17,24 @@ package org.apache.hertzbeat.alert.util; -import java.text.ParseException; -import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.util.Optional; import lombok.extern.slf4j.Slf4j; /** * date time common util */ @Slf4j -public class DateUtil { +public final class DateUtil { + + private DateUtil() { + } private static final String[] DATE_FORMATS = { + "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd HH:mm:ss" }; @@ -35,31 +42,42 @@ public class DateUtil { /** * convert date to timestamp * @param date date + * @return timestamp */ - public static Long getTimeStampFromSomeFormats(String date) { - SimpleDateFormat sdf; + public static Optional getTimeStampFromSomeFormats(String date) { for (String dateFormat : DATE_FORMATS) { try { - sdf = new SimpleDateFormat(dateFormat); - return sdf.parse(date).getTime(); - } catch (ParseException e) { - log.error(e.getMessage()); + DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder() + .appendPattern(dateFormat) + // enable string conversion in strict mode. + .parseStrict() + .toFormatter(); + LocalDateTime time = LocalDateTime.parse(date, dateTimeFormatter); + return Optional.of(time.toInstant(ZoneOffset.UTC).toEpochMilli()); + } catch (Exception e) { + log.warn("Error parsing date '{}' with format '{}': {}", + date, dateFormat, e.getMessage()); } } - return null; + + log.error("Error parsing date '{}', no corresponding date format", date); + return Optional.empty(); } /** * convert format data to timestamp */ - public static Long getTimeStampFromFormat(String date, String format) { - SimpleDateFormat sdf = new SimpleDateFormat(format); + public static Optional getTimeStampFromFormat(String date, String format) { try { - return sdf.parse(date).getTime(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); + LocalDateTime dateTime = LocalDateTime.parse(date, formatter); + return Optional.of(dateTime.toInstant(java.time.ZoneOffset.UTC).toEpochMilli()); } catch (Exception e) { - log.error(e.getMessage()); + log.error("Error parsing date '{}' with format '{}': {}", + date, format, e.getMessage()); } - return null; + + return Optional.empty(); } } diff --git a/alerter/src/test/java/org/apache/hertzbeat/alert/util/DateUtilTest.java b/alerter/src/test/java/org/apache/hertzbeat/alert/util/DateUtilTest.java new file mode 100644 index 00000000000..df4cff23728 --- /dev/null +++ b/alerter/src/test/java/org/apache/hertzbeat/alert/util/DateUtilTest.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.hertzbeat.alert.util; + +import org.junit.jupiter.api.Test; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Test case for {@link DateUtil} + */ +class DateUtilTest { + + @Test + void getTimeStampFromSomeFormats() { + String date = "2024-05-13"; + Optional actualTimestamp = DateUtil.getTimeStampFromSomeFormats(date); + assertFalse(actualTimestamp.isPresent()); + + date = "2024-05-13T12:34:56.789Z"; + actualTimestamp = DateUtil.getTimeStampFromSomeFormats(date); + assertTrue(actualTimestamp.isPresent()); + assertEquals(1715603696789L, actualTimestamp.get()); + + date = "2023-02-22T07:27:15.404000000Z"; + actualTimestamp = DateUtil.getTimeStampFromSomeFormats(date); + assertTrue(actualTimestamp.isPresent()); + assertEquals(1677050835404L, actualTimestamp.get()); + } + + @Test + void getTimeStampFromFormat() { + String date = "2024-05-13 10:30:00"; + String format = "yyyy-MM-dd HH:mm:ss"; + Optional actualTimestamp = DateUtil.getTimeStampFromFormat(date, format); + assertTrue(actualTimestamp.isPresent()); + assertEquals(1715596200000L, actualTimestamp.get()); + + date = "2024-05-13"; + format = "yyyy-MM-dd HH:mm:ss.SSS"; + actualTimestamp = DateUtil.getTimeStampFromFormat(date, format); + assertFalse(actualTimestamp.isPresent()); + } +}