Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed time format assertion failing due to daylight saving time #3459

Open
wants to merge 1 commit into
base: 1.8
Choose a base branch
from

Conversation

hermya
Copy link

@hermya hermya commented Oct 19, 2024

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 #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

@CLAassistant
Copy link

CLAassistant commented Oct 19, 2024

CLA assistant check
All committers have signed the CLA.

@robberphex
Copy link
Collaborator

robberphex commented Oct 20, 2024

With DSTSavings in mind, I think there should be three test cases:

  1. In a time zone that does not observe the DST, the local standard time is returned
  2. If the current time is not in the DST time zone, the returned value must be the same as the local standard time
  3. If the current time is within the DST range, the local wall time, which is inconsistent with the local standard time, is returned

@hermya
Copy link
Author

hermya commented Oct 20, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] EagleEyeCoreUtilsTest.testFormatTime fails due to DST
3 participants