Search code examples
javaalgorithmtimezonejava-timeepoch

How to find end of the day using epoch time and zone in Java


I have the epoch time of an event, as eventTime in seconds and the zone (location of the event) as userZone. I need to check if an event is eligible. An event is only eligible if it happens before the end of the day considering the zone of the user. Since epoch time is in UTC it needs to be converted to the zone time and then in that zone find the beginning and end of the day. There is a library in Java ZonedDateTime.

What I need to implement is:

   - Get eventTime in epoch (UTC) => getEventTime(event)
   - Get the userZone (for example CDT or EST) => getUserZone(user)
   - Convert eventTime to the local time of the user  => getEventInLocalTime(eventTime, userZone)
   - Get end of the day time for userZone => getEndOfToday(userZone)
   - if (0 <= eventLocalTime <= endOfToday) return True

Has anyone used ZonedDateTime to help with this logic? I implemented some logic but not sure about it as the object returned for ZonedDateTime for the end of the day is not clear to me. Basically, what I am trying to reach is if two users in two different time zones trigger an event at the same epoch time the user with an earlier time zone will be eligible for less amount of time, obviously.


Solution

  • Original answer

    You can get the start of the next day so that any time before that will be counted as the end of today.

    Demo:

    class Main {
        public static void main(String[] args) {
            // A sample epoch
            long epoch = 1693773531L;
    
            // Note: Change the timezone as per your requirement
            ZoneId userZone = ZoneId.of("America/New_York");
    
            ZonedDateTime zdtGiven = Instant.ofEpochSecond(epoch).atZone(userZone);
    
            // Today
            LocalDate today = LocalDate.now(userZone);
    
            // Get start of today
            ZonedDateTime startOfToday = today.atStartOfDay(userZone);
    
            // Get start of the next day
            ZonedDateTime startOfNextDay = today.plusDays(1).atStartOfDay(userZone);
    
            if (zdtGiven.isAfter(startOfToday) && zdtGiven.isBefore(startOfNextDay))
                // Do this e.g.
                System.out.println("Before");
        }
    }
    

    Output:

    Before
    

    Online Demo

    Learn about the modern date-time API from Trail: Date Time

    Update:

    The expression, zdtGiven.isAfter(startOfToday) && zdtGiven.isBefore(startOfNextDay) can be reduced to zdtGiven.toLocalDate().isEqual(today). This update also covers some more scenarios.

    Demo:

    class Main {
        public static void main(String[] args) {
            // A sample epoch
            long epoch = 1693832142L;
    
            // Note: change the timezone as per your requirement
            ZoneId userZone = ZoneId.of("America/New_York");
    
            // ZonedDateTime at the given epoch
            ZonedDateTime zdtGiven = Instant.ofEpochSecond(epoch).atZone(userZone);
    
            // LocalDate at the given epoch
            LocalDate localDateGiven = zdtGiven.toLocalDate();
    
            // Today
            LocalDate today = LocalDate.now(userZone);
    
            // Get start of today
            ZonedDateTime startOfToday = today.atStartOfDay(userZone);
    
            // Get start of the next day
            ZonedDateTime startOfNextDay = today.plusDays(1).atStartOfDay(userZone);
    
            // Current ZonedDateTime
            ZonedDateTime zdtNow = ZonedDateTime.now(userZone);
    
            // Anything happening before a given time e.g. 10 am today
            if (zdtGiven.isAfter(startOfToday) && zdtGiven.isBefore(zdtNow.with(LocalTime.of(10, 0))))
                // Do this e.g.
                System.out.println("Before 10 am today");
    
            // Alternatively
            if (localDateGiven.isEqual(today) && zdtGiven.isBefore(zdtNow.with(LocalTime.of(10, 0))))
                // Do this e.g.
                System.out.println("Before 10 am today");
    
            // Anything happening after a given time e.g. 10 am today
            if (zdtGiven.isAfter(zdtNow.with(LocalTime.of(10, 0))) && zdtGiven.isBefore(startOfNextDay))
                // Do this e.g.
                System.out.println("After 10 am today");
    
            // Alternatively
            if (zdtGiven.isAfter(zdtNow.with(LocalTime.of(10, 0))) && localDateGiven.isEqual(today))
                // Do this e.g.
                System.out.println("After 10 am today");
    
            // Anything happening today
            if (localDateGiven.isEqual(today))
                // Do this e.g.
                System.out.println("Today");
        }
    }
    

    Output:

    Before 10 am today
    Before 10 am today
    Today
    

    Online Demo