Copilot commented on code in PR #3962:
URL: https://github.com/apache/hertzbeat/pull/3962#discussion_r2694893946


##########
hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/StatusPageServiceImpl.java:
##########
@@ -215,50 +240,88 @@ private StatusPageHistory 
combineOneDayStatusPageHistory(List<StatusPageHistory>
 
     @Override
     public ComponentStatus queryComponentStatus(long id) {
-        StatusPageComponent component = 
statusPageComponentDao.findById(id).orElseThrow(() -> new 
IllegalArgumentException("component not found"));
+        StatusPageComponent component = statusPageComponentDao.findById(id)
+            .orElseThrow(() -> new IllegalArgumentException("component not 
found"));
+
         ComponentStatus componentStatus = new ComponentStatus();
         componentStatus.setInfo(component);
         List<StatusPageHistory> histories = new LinkedList<>();
-        // query today status
-        LocalDateTime nowTime = LocalDateTime.now();
-        LocalDateTime todayStartTime = 
nowTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
-        ZoneOffset zoneOffset = 
ZoneId.systemDefault().getRules().getOffset(Instant.now());
-        long nowTimestamp = nowTime.toInstant(zoneOffset).toEpochMilli();
-        long todayStartTimestamp = 
todayStartTime.toInstant(zoneOffset).toEpochMilli();
-        List<StatusPageHistory> todayStatusPageHistoryList = 
statusPageHistoryDao
-                
.findStatusPageHistoriesByComponentIdAndTimestampBetween(component.getId(), 
todayStartTimestamp, nowTimestamp);
-        StatusPageHistory todayStatus = 
combineOneDayStatusPageHistory(todayStatusPageHistoryList, component, 
nowTimestamp);
+
+        ZoneId zoneId = ZoneId.systemDefault();
+
+        Instant now = Instant.now();
+        long nowTimestamp = now.toEpochMilli();
+
+        long todayStartTimestamp = now
+            .atZone(zoneId)
+            .toLocalDate()
+            .atStartOfDay(zoneId)
+            .toInstant()
+            .toEpochMilli();
+
+        // Today
+        List<StatusPageHistory> todayStatusPageHistoryList =
+            
statusPageHistoryDao.findStatusPageHistoriesByComponentIdAndTimestampBetween(
+                component.getId(), todayStartTimestamp, nowTimestamp);
+
+        StatusPageHistory todayStatus =
+            combineOneDayStatusPageHistory(todayStatusPageHistoryList, 
component, nowTimestamp);
+
         histories.add(todayStatus);
-        // query 30d component status history
-        LocalDateTime preTime = todayStartTime.minusDays(HISTORY_SPAN_DAYS);
-        long preTimestamp = preTime.toInstant(zoneOffset).toEpochMilli();
-        List<StatusPageHistory> history = statusPageHistoryDao
-                
.findStatusPageHistoriesByComponentIdAndTimestampBetween(component.getId(), 
preTimestamp, todayStartTimestamp);
+
+        // Previous 29 days

Review Comment:
   The comment states "Previous 29 days" but the constant HISTORY_SPAN_DAYS is 
29, which means when querying history, it goes back 29 days from today's start. 
This creates a total of 30 days of history (today + 29 previous days). The 
comment should be "Previous HISTORY_SPAN_DAYS days" or updated to accurately 
reflect that it fetches 29 days of historical data excluding today.
   ```suggestion
           // Previous HISTORY_SPAN_DAYS days (excluding today)
   ```



##########
hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/StatusPageServiceImpl.java:
##########
@@ -131,45 +130,71 @@ public List<ComponentStatus> queryComponentsStatus() {
             componentStatus.setInfo(component);
             List<StatusPageHistory> histories = new LinkedList<>();
             // query today status
-            LocalDateTime nowTime = LocalDateTime.now();
-            LocalDateTime todayStartTime = 
nowTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
-            ZoneOffset zoneOffset = 
ZoneId.systemDefault().getRules().getOffset(Instant.now());
-            long nowTimestamp = nowTime.toInstant(zoneOffset).toEpochMilli();
-            long todayStartTimestamp = 
todayStartTime.toInstant(zoneOffset).toEpochMilli();
+            ZoneId zoneId = ZoneId.systemDefault();
+
+            Instant now = Instant.now();
+            long nowTimestamp = now.toEpochMilli();
+
+            long todayStartTimestamp = now
+                .atZone(zoneId)
+                .toLocalDate()
+                .atStartOfDay(zoneId)
+                .toInstant()
+                .toEpochMilli();
+
             List<StatusPageHistory> todayStatusPageHistoryList = 
statusPageHistoryDao
                     
.findStatusPageHistoriesByComponentIdAndTimestampBetween(component.getId(), 
todayStartTimestamp, nowTimestamp);
             StatusPageHistory todayStatus = 
combineOneDayStatusPageHistory(todayStatusPageHistoryList, component, 
nowTimestamp);
             histories.add(todayStatus);
             // query 30d component status history
-            LocalDateTime preTime = 
todayStartTime.minusDays(HISTORY_SPAN_DAYS);
-            long preTimestamp = preTime.toInstant(zoneOffset).toEpochMilli();
+            long preTimestamp = now
+                .atZone(zoneId)
+                .toLocalDate()
+                .minusDays(HISTORY_SPAN_DAYS)
+                .atStartOfDay(zoneId)
+                .toInstant()
+                .toEpochMilli();
+
+

Review Comment:
   There are two consecutive blank lines here. Consider removing one to 
maintain consistent spacing throughout the codebase.
   ```suggestion
   
   ```



##########
hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/StatusPageServiceImpl.java:
##########
@@ -215,50 +240,88 @@ private StatusPageHistory 
combineOneDayStatusPageHistory(List<StatusPageHistory>
 
     @Override
     public ComponentStatus queryComponentStatus(long id) {
-        StatusPageComponent component = 
statusPageComponentDao.findById(id).orElseThrow(() -> new 
IllegalArgumentException("component not found"));
+        StatusPageComponent component = statusPageComponentDao.findById(id)
+            .orElseThrow(() -> new IllegalArgumentException("component not 
found"));
+
         ComponentStatus componentStatus = new ComponentStatus();
         componentStatus.setInfo(component);
         List<StatusPageHistory> histories = new LinkedList<>();
-        // query today status
-        LocalDateTime nowTime = LocalDateTime.now();
-        LocalDateTime todayStartTime = 
nowTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
-        ZoneOffset zoneOffset = 
ZoneId.systemDefault().getRules().getOffset(Instant.now());
-        long nowTimestamp = nowTime.toInstant(zoneOffset).toEpochMilli();
-        long todayStartTimestamp = 
todayStartTime.toInstant(zoneOffset).toEpochMilli();
-        List<StatusPageHistory> todayStatusPageHistoryList = 
statusPageHistoryDao
-                
.findStatusPageHistoriesByComponentIdAndTimestampBetween(component.getId(), 
todayStartTimestamp, nowTimestamp);
-        StatusPageHistory todayStatus = 
combineOneDayStatusPageHistory(todayStatusPageHistoryList, component, 
nowTimestamp);
+
+        ZoneId zoneId = ZoneId.systemDefault();
+
+        Instant now = Instant.now();
+        long nowTimestamp = now.toEpochMilli();
+
+        long todayStartTimestamp = now
+            .atZone(zoneId)
+            .toLocalDate()
+            .atStartOfDay(zoneId)
+            .toInstant()
+            .toEpochMilli();
+
+        // Today
+        List<StatusPageHistory> todayStatusPageHistoryList =
+            
statusPageHistoryDao.findStatusPageHistoriesByComponentIdAndTimestampBetween(
+                component.getId(), todayStartTimestamp, nowTimestamp);
+
+        StatusPageHistory todayStatus =
+            combineOneDayStatusPageHistory(todayStatusPageHistoryList, 
component, nowTimestamp);
+
         histories.add(todayStatus);
-        // query 30d component status history
-        LocalDateTime preTime = todayStartTime.minusDays(HISTORY_SPAN_DAYS);
-        long preTimestamp = preTime.toInstant(zoneOffset).toEpochMilli();
-        List<StatusPageHistory> history = statusPageHistoryDao
-                
.findStatusPageHistoriesByComponentIdAndTimestampBetween(component.getId(), 
preTimestamp, todayStartTimestamp);
+
+        // Previous 29 days
+        long preTimestamp = now
+            .atZone(zoneId)
+            .toLocalDate()
+            .minusDays(HISTORY_SPAN_DAYS)
+            .atStartOfDay(zoneId)
+            .toInstant()
+            .toEpochMilli();
+
+
+        List<StatusPageHistory> history =
+            
statusPageHistoryDao.findStatusPageHistoriesByComponentIdAndTimestampBetween(
+                component.getId(), preTimestamp, todayStartTimestamp);
+
         LinkedList<StatusPageHistory> historyList = new LinkedList<>(history);
-        historyList.sort((o1, o2) -> (int) (o1.getTimestamp() - 
o2.getTimestamp()));
-        LocalDateTime endTime = todayStartTime.minusSeconds(1);
-        LocalDateTime startTime = 
endTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
-        for (int index = 0; index < HISTORY_SPAN_DAYS; index++) {
-            long startTimestamp = 
startTime.toInstant(zoneOffset).toEpochMilli();
-            long endTimestamp = endTime.toInstant(zoneOffset).toEpochMilli();
-            List<StatusPageHistory> thisDayHistory = 
historyList.stream().filter(item ->
-                            item.getTimestamp() >= startTimestamp && 
item.getTimestamp() <= endTimestamp)
-                    .collect(Collectors.toList());
+        historyList.sort((o1, o2) -> Long.compare(o1.getTimestamp(), 
o2.getTimestamp()));
+
+        ZonedDateTime end = Instant.ofEpochMilli(todayStartTimestamp)
+            .atZone(zoneId)
+            .minusSeconds(1);   // yesterday 23:59:59 local time
+
+        for (int i = 0; i < HISTORY_SPAN_DAYS; i++) {
+            long endTimestamp = end.toInstant().toEpochMilli();
+
+            long startTimestamp = end.toLocalDate()
+                .atStartOfDay(zoneId)
+                .toInstant()
+                .toEpochMilli();
+
+            List<StatusPageHistory> thisDayHistory = historyList.stream()
+                .filter(h -> h.getTimestamp() >= startTimestamp && 
h.getTimestamp() <= endTimestamp)
+                .collect(Collectors.toList());
+
             if (thisDayHistory.isEmpty()) {
-                StatusPageHistory statusPageHistory = 
StatusPageHistory.builder().timestamp(endTimestamp)
-                        
.componentId(component.getId()).state(CommonConstants.STATUS_PAGE_COMPONENT_STATE_UNKNOWN).build();
-                histories.add(statusPageHistory);
+                histories.add(StatusPageHistory.builder()
+                    .timestamp(endTimestamp)
+                    .componentId(component.getId())
+                    .state(CommonConstants.STATUS_PAGE_COMPONENT_STATE_UNKNOWN)
+                    .build());
             } else if (thisDayHistory.size() == 1) {
                 histories.add(thisDayHistory.get(0));
             } else {
-                StatusPageHistory statusPageHistory = 
combineOneDayStatusPageHistory(thisDayHistory, component, endTimestamp);
-                histories.add(statusPageHistory);
+                StatusPageHistory merged =
+                    combineOneDayStatusPageHistory(thisDayHistory, component, 
endTimestamp);
+                histories.add(merged);
                 statusPageHistoryDao.deleteAll(thisDayHistory);
-                statusPageHistoryDao.save(statusPageHistory);
+                statusPageHistoryDao.save(merged);
             }
-            startTime = startTime.minusDays(1);
-            endTime = endTime.minusDays(1);
+
+            end = end.minusDays(1);
         }
+
+

Review Comment:
   There are two consecutive blank lines here. Consider removing one to 
maintain consistent spacing throughout the codebase.
   ```suggestion
   
   ```



##########
hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/StatusPageServiceImpl.java:
##########
@@ -215,50 +240,88 @@ private StatusPageHistory 
combineOneDayStatusPageHistory(List<StatusPageHistory>
 
     @Override
     public ComponentStatus queryComponentStatus(long id) {
-        StatusPageComponent component = 
statusPageComponentDao.findById(id).orElseThrow(() -> new 
IllegalArgumentException("component not found"));
+        StatusPageComponent component = statusPageComponentDao.findById(id)
+            .orElseThrow(() -> new IllegalArgumentException("component not 
found"));
+
         ComponentStatus componentStatus = new ComponentStatus();
         componentStatus.setInfo(component);
         List<StatusPageHistory> histories = new LinkedList<>();
-        // query today status
-        LocalDateTime nowTime = LocalDateTime.now();
-        LocalDateTime todayStartTime = 
nowTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
-        ZoneOffset zoneOffset = 
ZoneId.systemDefault().getRules().getOffset(Instant.now());
-        long nowTimestamp = nowTime.toInstant(zoneOffset).toEpochMilli();
-        long todayStartTimestamp = 
todayStartTime.toInstant(zoneOffset).toEpochMilli();
-        List<StatusPageHistory> todayStatusPageHistoryList = 
statusPageHistoryDao
-                
.findStatusPageHistoriesByComponentIdAndTimestampBetween(component.getId(), 
todayStartTimestamp, nowTimestamp);
-        StatusPageHistory todayStatus = 
combineOneDayStatusPageHistory(todayStatusPageHistoryList, component, 
nowTimestamp);
+
+        ZoneId zoneId = ZoneId.systemDefault();
+
+        Instant now = Instant.now();
+        long nowTimestamp = now.toEpochMilli();
+
+        long todayStartTimestamp = now
+            .atZone(zoneId)
+            .toLocalDate()
+            .atStartOfDay(zoneId)
+            .toInstant()
+            .toEpochMilli();
+
+        // Today
+        List<StatusPageHistory> todayStatusPageHistoryList =
+            
statusPageHistoryDao.findStatusPageHistoriesByComponentIdAndTimestampBetween(
+                component.getId(), todayStartTimestamp, nowTimestamp);
+
+        StatusPageHistory todayStatus =
+            combineOneDayStatusPageHistory(todayStatusPageHistoryList, 
component, nowTimestamp);
+
         histories.add(todayStatus);
-        // query 30d component status history
-        LocalDateTime preTime = todayStartTime.minusDays(HISTORY_SPAN_DAYS);
-        long preTimestamp = preTime.toInstant(zoneOffset).toEpochMilli();
-        List<StatusPageHistory> history = statusPageHistoryDao
-                
.findStatusPageHistoriesByComponentIdAndTimestampBetween(component.getId(), 
preTimestamp, todayStartTimestamp);
+
+        // Previous 29 days
+        long preTimestamp = now
+            .atZone(zoneId)
+            .toLocalDate()
+            .minusDays(HISTORY_SPAN_DAYS)
+            .atStartOfDay(zoneId)
+            .toInstant()
+            .toEpochMilli();
+
+

Review Comment:
   There are two consecutive blank lines here. Consider removing one to 
maintain consistent spacing throughout the codebase.
   ```suggestion
   
   ```



##########
hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/StatusPageServiceImpl.java:
##########
@@ -131,45 +130,71 @@ public List<ComponentStatus> queryComponentsStatus() {
             componentStatus.setInfo(component);
             List<StatusPageHistory> histories = new LinkedList<>();
             // query today status
-            LocalDateTime nowTime = LocalDateTime.now();
-            LocalDateTime todayStartTime = 
nowTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
-            ZoneOffset zoneOffset = 
ZoneId.systemDefault().getRules().getOffset(Instant.now());
-            long nowTimestamp = nowTime.toInstant(zoneOffset).toEpochMilli();
-            long todayStartTimestamp = 
todayStartTime.toInstant(zoneOffset).toEpochMilli();
+            ZoneId zoneId = ZoneId.systemDefault();
+
+            Instant now = Instant.now();
+            long nowTimestamp = now.toEpochMilli();
+
+            long todayStartTimestamp = now
+                .atZone(zoneId)
+                .toLocalDate()
+                .atStartOfDay(zoneId)
+                .toInstant()
+                .toEpochMilli();
+
             List<StatusPageHistory> todayStatusPageHistoryList = 
statusPageHistoryDao
                     
.findStatusPageHistoriesByComponentIdAndTimestampBetween(component.getId(), 
todayStartTimestamp, nowTimestamp);
             StatusPageHistory todayStatus = 
combineOneDayStatusPageHistory(todayStatusPageHistoryList, component, 
nowTimestamp);
             histories.add(todayStatus);
             // query 30d component status history
-            LocalDateTime preTime = 
todayStartTime.minusDays(HISTORY_SPAN_DAYS);
-            long preTimestamp = preTime.toInstant(zoneOffset).toEpochMilli();
+            long preTimestamp = now
+                .atZone(zoneId)
+                .toLocalDate()
+                .minusDays(HISTORY_SPAN_DAYS)
+                .atStartOfDay(zoneId)
+                .toInstant()
+                .toEpochMilli();
+
+
             List<StatusPageHistory> history = statusPageHistoryDao
                     
.findStatusPageHistoriesByComponentIdAndTimestampBetween(component.getId(), 
preTimestamp, todayStartTimestamp);
             LinkedList<StatusPageHistory> historyList = new 
LinkedList<>(history);
-            historyList.sort((o1, o2) -> (int) (o1.getTimestamp() - 
o2.getTimestamp()));
-            LocalDateTime endTime = todayStartTime.minusSeconds(1);
-            LocalDateTime startTime = 
endTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
-            for (int index = 0; index < HISTORY_SPAN_DAYS; index++) {
-                long startTimestamp = 
startTime.toInstant(zoneOffset).toEpochMilli();
-                long endTimestamp = 
endTime.toInstant(zoneOffset).toEpochMilli();
-                List<StatusPageHistory> thisDayHistory = 
historyList.stream().filter(item ->
-                                item.getTimestamp() >= startTimestamp && 
item.getTimestamp() <= endTimestamp)
-                        .collect(Collectors.toList());
+            historyList.sort((o1, o2) -> Long.compare(o1.getTimestamp(), 
o2.getTimestamp()));
+            ZonedDateTime end = Instant.ofEpochMilli(todayStartTimestamp)
+                .atZone(zoneId)
+                .minusSeconds(1);   // yesterday 23:59:59 local time
+
+            for (int i = 0; i < HISTORY_SPAN_DAYS; i++) {
+                long endTimestamp = end.toInstant().toEpochMilli();
+
+                long startTimestamp = end.toLocalDate()
+                    .atStartOfDay(zoneId)
+                    .toInstant()
+                    .toEpochMilli();
+
+                List<StatusPageHistory> thisDayHistory = historyList.stream()
+                    .filter(h -> h.getTimestamp() >= startTimestamp && 
h.getTimestamp() <= endTimestamp)
+                    .collect(Collectors.toList());
+
                 if (thisDayHistory.isEmpty()) {
-                    StatusPageHistory statusPageHistory = 
StatusPageHistory.builder().timestamp(endTimestamp)
-                            
.componentId(component.getId()).state(CommonConstants.STATUS_PAGE_COMPONENT_STATE_UNKNOWN).build();
-                    histories.add(statusPageHistory);
+                    histories.add(StatusPageHistory.builder()
+                        .timestamp(endTimestamp)
+                        .componentId(component.getId())
+                        
.state(CommonConstants.STATUS_PAGE_COMPONENT_STATE_UNKNOWN)
+                        .build());
                 } else if (thisDayHistory.size() == 1) {
                     histories.add(thisDayHistory.get(0));
                 } else {
-                    StatusPageHistory statusPageHistory = 
combineOneDayStatusPageHistory(thisDayHistory, component, endTimestamp);
-                    histories.add(statusPageHistory);
+                    StatusPageHistory merged =
+                        combineOneDayStatusPageHistory(thisDayHistory, 
component, endTimestamp);
+                    histories.add(merged);
                     statusPageHistoryDao.deleteAll(thisDayHistory);
-                    statusPageHistoryDao.save(statusPageHistory);
+                    statusPageHistoryDao.save(merged);
                 }
-                startTime = startTime.minusDays(1);
-                endTime = endTime.minusDays(1);
+
+                end = end.minusDays(1);
             }

Review Comment:
   The date calculation logic in queryComponentsStatus has been significantly 
refactored to fix midnight race conditions and DST issues, but there are no 
unit tests covering this critical logic. Consider adding tests that verify the 
date calculations work correctly, especially for edge cases like midnight 
boundaries, DST transitions, and the 29-day history window calculation.



##########
hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/StatusPageServiceImpl.java:
##########
@@ -215,50 +240,88 @@ private StatusPageHistory 
combineOneDayStatusPageHistory(List<StatusPageHistory>
 
     @Override
     public ComponentStatus queryComponentStatus(long id) {
-        StatusPageComponent component = 
statusPageComponentDao.findById(id).orElseThrow(() -> new 
IllegalArgumentException("component not found"));
+        StatusPageComponent component = statusPageComponentDao.findById(id)
+            .orElseThrow(() -> new IllegalArgumentException("component not 
found"));
+
         ComponentStatus componentStatus = new ComponentStatus();
         componentStatus.setInfo(component);
         List<StatusPageHistory> histories = new LinkedList<>();
-        // query today status
-        LocalDateTime nowTime = LocalDateTime.now();
-        LocalDateTime todayStartTime = 
nowTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
-        ZoneOffset zoneOffset = 
ZoneId.systemDefault().getRules().getOffset(Instant.now());
-        long nowTimestamp = nowTime.toInstant(zoneOffset).toEpochMilli();
-        long todayStartTimestamp = 
todayStartTime.toInstant(zoneOffset).toEpochMilli();
-        List<StatusPageHistory> todayStatusPageHistoryList = 
statusPageHistoryDao
-                
.findStatusPageHistoriesByComponentIdAndTimestampBetween(component.getId(), 
todayStartTimestamp, nowTimestamp);
-        StatusPageHistory todayStatus = 
combineOneDayStatusPageHistory(todayStatusPageHistoryList, component, 
nowTimestamp);
+
+        ZoneId zoneId = ZoneId.systemDefault();
+
+        Instant now = Instant.now();
+        long nowTimestamp = now.toEpochMilli();
+
+        long todayStartTimestamp = now
+            .atZone(zoneId)
+            .toLocalDate()
+            .atStartOfDay(zoneId)
+            .toInstant()
+            .toEpochMilli();
+
+        // Today
+        List<StatusPageHistory> todayStatusPageHistoryList =
+            
statusPageHistoryDao.findStatusPageHistoriesByComponentIdAndTimestampBetween(
+                component.getId(), todayStartTimestamp, nowTimestamp);
+
+        StatusPageHistory todayStatus =
+            combineOneDayStatusPageHistory(todayStatusPageHistoryList, 
component, nowTimestamp);
+
         histories.add(todayStatus);
-        // query 30d component status history
-        LocalDateTime preTime = todayStartTime.minusDays(HISTORY_SPAN_DAYS);
-        long preTimestamp = preTime.toInstant(zoneOffset).toEpochMilli();
-        List<StatusPageHistory> history = statusPageHistoryDao
-                
.findStatusPageHistoriesByComponentIdAndTimestampBetween(component.getId(), 
preTimestamp, todayStartTimestamp);
+
+        // Previous 29 days
+        long preTimestamp = now
+            .atZone(zoneId)
+            .toLocalDate()
+            .minusDays(HISTORY_SPAN_DAYS)
+            .atStartOfDay(zoneId)
+            .toInstant()
+            .toEpochMilli();
+
+
+        List<StatusPageHistory> history =
+            
statusPageHistoryDao.findStatusPageHistoriesByComponentIdAndTimestampBetween(
+                component.getId(), preTimestamp, todayStartTimestamp);
+
         LinkedList<StatusPageHistory> historyList = new LinkedList<>(history);
-        historyList.sort((o1, o2) -> (int) (o1.getTimestamp() - 
o2.getTimestamp()));
-        LocalDateTime endTime = todayStartTime.minusSeconds(1);
-        LocalDateTime startTime = 
endTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
-        for (int index = 0; index < HISTORY_SPAN_DAYS; index++) {
-            long startTimestamp = 
startTime.toInstant(zoneOffset).toEpochMilli();
-            long endTimestamp = endTime.toInstant(zoneOffset).toEpochMilli();
-            List<StatusPageHistory> thisDayHistory = 
historyList.stream().filter(item ->
-                            item.getTimestamp() >= startTimestamp && 
item.getTimestamp() <= endTimestamp)
-                    .collect(Collectors.toList());
+        historyList.sort((o1, o2) -> Long.compare(o1.getTimestamp(), 
o2.getTimestamp()));
+
+        ZonedDateTime end = Instant.ofEpochMilli(todayStartTimestamp)
+            .atZone(zoneId)
+            .minusSeconds(1);   // yesterday 23:59:59 local time
+
+        for (int i = 0; i < HISTORY_SPAN_DAYS; i++) {
+            long endTimestamp = end.toInstant().toEpochMilli();
+
+            long startTimestamp = end.toLocalDate()
+                .atStartOfDay(zoneId)
+                .toInstant()
+                .toEpochMilli();
+
+            List<StatusPageHistory> thisDayHistory = historyList.stream()
+                .filter(h -> h.getTimestamp() >= startTimestamp && 
h.getTimestamp() <= endTimestamp)
+                .collect(Collectors.toList());
+
             if (thisDayHistory.isEmpty()) {
-                StatusPageHistory statusPageHistory = 
StatusPageHistory.builder().timestamp(endTimestamp)
-                        
.componentId(component.getId()).state(CommonConstants.STATUS_PAGE_COMPONENT_STATE_UNKNOWN).build();
-                histories.add(statusPageHistory);
+                histories.add(StatusPageHistory.builder()
+                    .timestamp(endTimestamp)
+                    .componentId(component.getId())
+                    .state(CommonConstants.STATUS_PAGE_COMPONENT_STATE_UNKNOWN)
+                    .build());
             } else if (thisDayHistory.size() == 1) {
                 histories.add(thisDayHistory.get(0));
             } else {
-                StatusPageHistory statusPageHistory = 
combineOneDayStatusPageHistory(thisDayHistory, component, endTimestamp);
-                histories.add(statusPageHistory);
+                StatusPageHistory merged =
+                    combineOneDayStatusPageHistory(thisDayHistory, component, 
endTimestamp);
+                histories.add(merged);
                 statusPageHistoryDao.deleteAll(thisDayHistory);
-                statusPageHistoryDao.save(statusPageHistory);
+                statusPageHistoryDao.save(merged);
             }
-            startTime = startTime.minusDays(1);
-            endTime = endTime.minusDays(1);
+
+            end = end.minusDays(1);
         }

Review Comment:
   The date calculation logic in queryComponentStatus has been significantly 
refactored to fix midnight race conditions and DST issues, but there are no 
unit tests covering this critical logic. Consider adding tests that verify the 
date calculations work correctly, especially for edge cases like midnight 
boundaries, DST transitions, and the 29-day history window calculation.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to