简体   繁体   中英

How can i know if current time is 5 am in specific time zone

My system time zone is utc. How can I know using java date time api if its 5am in a given timezone?

How can I use zone date time for this?

Is it 5am in singapore now? Is it 5am in india now? Is it 5am in austria now?

Thanks

This is my final logic. After working on the solutions below.

    public class MorningReminderScheduler {

    @Scheduled( cron="0 0/5 * * * *  ")
    public static void main(String args[]){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        for (String zoneId : ZoneId.getAvailableZoneIds()) {
            ZoneId z = ZoneId.of(zoneId);
            // LocalDateTime -> ZonedDateTime
            LocalTime l= LocalTime.now(z);
            if(l.getHour()==5 && l.getMinute()<5){
                System.out.println("its between 5 hour to 5 hour 5 min in  = " + z.getId());
            }
        }
    }
}

You can use the LocalTime class to find the local time in any support time zone. For example:

String zoneId = "Asia/Singapore";
LocalTime timeInSingapore = LocalTime.now(ZoneId.of(zoneId));

To find if it's 5 am in Singapore, you'll probably want to apply some threshold because the time is exactly 5 am for a very short period of time. What you could do is calculate the difference between 5 am and the given moment in time, and if the difference is "small enough" you can claim it's 5 am. For example, this will claim the time is 5am at any time between 4:50 and 5:10:

LocalTime fiveAm = LocalTime.of(5, 0);
long minutesBetween = Math.abs(ChronoUnit.MINUTES.between(fiveAm, timeInSingapore));
if (minutesBetween <= 10) {
    // close enough
    System.out.println("It's 5am in " + zoneId);
}

You can use zoneId of the timezone you want to know the time of. Format the date using a DateFormatter and then verify if it's 5:00 AM. A sample code can be like below:

public static void getCurrentTimeWithTimeZone(){
    System.out.println("-----Current time of a different time zone using LocalTime-----");
    ZoneId zoneId = ZoneId.of("America/Los_Angeles");
    LocalTime localTime=LocalTime.now(zoneId);
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
    String formattedTime=localTime.format(formatter);
    System.out.println("Current time of the day in Los Angeles: " + formattedTime);
    if(formattedTime.equals("05:00:00")
       System.out.println("It is 5 AM in Los Angeles");

}

Assuming you mean 5:00 when you say 5 am ie you are not considering the seconds and nanoseconds, you can compare the hour and minute of time at Singapore with 5 and 0 respectively to evaluate if it is 5 am .

import java.time.LocalTime;
import java.time.OffsetTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        // Singapore has the Zone Offset of UTC +8
        LocalTime nowAtSingapore = OffsetTime.now().withOffsetSameInstant(ZoneOffset.ofHours(8)).toLocalTime();
        System.out.println("Now at Singapore: " + nowAtSingapore);
        System.out.println("Now (HH:mm) at Singapore: " + DateTimeFormatter.ofPattern("HH:mm").format(nowAtSingapore));

        // Check if it is 5:00 at Singapore now
        if (nowAtSingapore.getHour() == 5 && nowAtSingapore.getMinute() == 0) {
            System.out.println("It's 5:00 at Singapore");
        }
    }
}

Output:

Now at Singapore: 05:24:43.217733
Now (HH:mm) at Singapore: 05:24

Note: that the default format of LocalTime.toString() is HH:mm:ss.SSSSSS where SSSSSS denotes nanoseconds. In order to get a string in a custom pattern, we use DateTimeFormatter#ofPattern .

EDIT: For your cron job I suggest you keep track of the last date you sent the text (SMS) message for that time zone. So if it is now past 5 AM on the following day , send the next message (and update the date stored). This will make sure that the message is sent even if the job doesn't happen to run exactly within your 5 minutes tolerance interval. Also it will not be sent twice if the job happens to run twice. Time is tricky in that we never get things to happen exactly at the time specified, so we have to take these possibilities into account.

Original answer

No, it is not 5 AM in India or one of the other time zones you mentioned. The point in time of 5 AM in some time zone lasts 0, so the probability that it is that time is 0.

On many platforms Java can since Java 9 read the time with microsecond precision. So even though it is not exactly 5 AM, it leaves us with a probability of 0.000000001 % that the time read is 5 AM. It's still minute enough to say that it will practically never happen.

So I suggest that you work with some tolerance: If the time is sufficiently close to 5 AM, you regard it as 5 AM. For example:

    final LocalTime time = LocalTime.of(5, 0); // 5 AM
    final Duration tolerance = Duration.ofMillis(600); // 0.6 seconds as an example
    
    ZoneId zone = ZoneId.of("Asia/Kolkata"); // India
    
    LocalTime nowInZone = LocalTime.now(zone);
    if (nowInZone.isBefore(time.minus(tolerance)) || nowInZone.isAfter(time.plus(tolerance))) {
        System.out.println("No, it is not " + time + " in " + zone);
    } else {
        System.out.println("Yes, it is " + nowInZone + " in " + zone);
    }

When I ran the code just now, output was the likely:

No, it is not 05:00 in Asia/Kolkata

Beware that the code only works correctly so long as the tolerance doesn't cross midnight (12 AM). For example, it the time was 0:01 AM and the tolerance was 2 minutes, we'd check whether the time was after 23:59 and before 0:03. No time can be both, so we'd always get No even if the time was within that 4 minutes gap. But for 5 AM and a tolerance less than 5 hours it does work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM