Sentinel
Sentinel copied to clipboard
Fixed time format assertion failing due to daylight saving time
Describe what this PR does / why we need it
PR intends to fix the test EagleEyeCoreUtilsTest.testFormatTime.
Does this pull request fix one issue?
Fixes https://github.com/alibaba/Sentinel/issues/3458
Describe how you did it
Used TimeZone.getDefault().getDSTSavings()
Describe how to verify it
Reran the test-case, now passing successfully
Special notes for reviews
With DSTSavings in mind, I think there should be three test cases:
- In a time zone that does not observe the DST, the local standard time is returned
- If the current time is not in the DST time zone, the returned value must be the same as the local standard time
- If the current time is within the DST range, the local wall time, which is inconsistent with the local standard time, is returned
The latest commit contains TimeZone.getOffset() method. According to this, getOffset() should cater to DST, based on the zone and date.
I tried it with sample code for different zones and times as follows:
import java.sql.Date;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.stream.Collectors;
public class Main {
public static DateTimeFormatter getFormatterByZone(String zoneId) {
return DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")
.withZone(ZoneId.of(zoneId));
}
public static void printZoneInformation(String zoneId) {
var tz = TimeZone.getTimeZone(zoneId);
System.out.println("Time zone: " + tz.getDisplayName() + ", RawOffset: " + tz.getRawOffset() + ", DST: " + tz.observesDaylightTime() + ", DSTSavings: " + tz.getDSTSavings());
}
public static long getOffsetForZone(String zoneId, long epoch) {
return TimeZone.getTimeZone(zoneId).getOffset(epoch);
}
public static void main(String[] args) {
// SAPST -> (UTC-05:00) Bogota, Lima, Quito No DST
// IST -> (UTC+05:30) India Standard Time No DST
// CDT -> (UTC-05:00) Central Daylight Time DST
long epochNotInDST = 1729382400000l;
long epochInDST = 1732060800000l;
// 1729382400000l -> 10/20/2024 00:00:00.000 Date not in DST
// 1732060800000l -> 11/20/2024 00:00:00.000 Date in DST
System.out.println("\nDate in DST: ");
printZoneInformation("Etc/GMT+0");
System.out.println(getFormatterByZone("Etc/GMT+0").format(Instant.ofEpochMilli(epochInDST - getOffsetForZone("Etc/GMT+0", epochInDST))));
printZoneInformation("America/Bogota");
System.out.println(getFormatterByZone("America/Bogota").format(Instant.ofEpochMilli(epochInDST - getOffsetForZone("America/Bogota", epochInDST))));
printZoneInformation("Asia/Kolkata");
System.out.println(getFormatterByZone("Asia/Kolkata").format(Instant.ofEpochMilli(epochInDST - getOffsetForZone("Asia/Kolkata", epochInDST))));
printZoneInformation("America/Chicago");
System.out.println(getFormatterByZone("America/Chicago").format(Instant.ofEpochMilli(epochInDST - getOffsetForZone("America/Chicago", epochInDST))));
System.out.println("\nDate not in DST: ");
printZoneInformation("Etc/GMT+0");
System.out.println(getFormatterByZone("Etc/GMT+0").format(Instant.ofEpochMilli(epochNotInDST - getOffsetForZone("Etc/GMT+0", epochNotInDST))));
printZoneInformation("America/Bogota");
System.out.println(getFormatterByZone("America/Bogota").format(Instant.ofEpochMilli(epochNotInDST - getOffsetForZone("America/Bogota", epochNotInDST))));
printZoneInformation("Asia/Kolkata");
System.out.println(getFormatterByZone("Asia/Kolkata").format(Instant.ofEpochMilli(epochNotInDST - getOffsetForZone("Asia/Kolkata", epochNotInDST))));
printZoneInformation("America/Chicago");
System.out.println(getFormatterByZone("America/Chicago").format(Instant.ofEpochMilli(epochNotInDST - getOffsetForZone("America/Chicago", epochNotInDST))));
}
}
And got the output:
Date in DST:
Time zone: Greenwich Mean Time, RawOffset: 0, DST: false, DSTSavings: 0
2024-11-20 00:00:00.000
Time zone: Colombia Standard Time, RawOffset: -18000000, DST: false, DSTSavings: 0
2024-11-20 00:00:00.000
Time zone: India Standard Time, RawOffset: 19800000, DST: false, DSTSavings: 0
2024-11-20 00:00:00.000
Time zone: Central Standard Time, RawOffset: -21600000, DST: true, DSTSavings: 3600000
2024-11-20 00:00:00.000
Date not in DST:
Time zone: Greenwich Mean Time, RawOffset: 0, DST: false, DSTSavings: 0
2024-10-20 00:00:00.000
Time zone: Colombia Standard Time, RawOffset: -18000000, DST: false, DSTSavings: 0
2024-10-20 00:00:00.000
Time zone: India Standard Time, RawOffset: 19800000, DST: false, DSTSavings: 0
2024-10-20 00:00:00.000
Time zone: Central Standard Time, RawOffset: -21600000, DST: true, DSTSavings: 3600000
2024-10-20 00:00:00.000