0

I want to check if my Date value from -

Date d = convertCurrentTimeToSpecificTimeZone("America/Chicago", 2, 30);

falls in the range of 10am to 6 pm.

I found some similar links on StackOverflow similar question and used some of the code from this thread.

All I want to check if the current time from any timezone falls under the range of 10 am to 6 pm. If Yes, print "yes" else print "no".

Currently for below code:

    String string1 = "10:11:13";
    Date time1 = new SimpleDateFormat("HH:mm:ss").parse(string1);
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(time1);
    calendar1.add(Calendar.DATE, 1);
    System.out.println(calendar1.getTime().toString());

It just prints the 10:11 am time of 1970 year. Like this - Fri Jan 02 10:11:13 IST 1970.

But I want to check if today's or any future date time falls in the range of 10 am to 6pm.

Below is the code reference:

public static Date convertCurrentTimeToSpecificTimeZone(String timeZone, int increaseDateBy,
        int increaseMinutesBy) {
    Calendar calendar = Calendar.getInstance();
    TimeZone fromTimeZone = calendar.getTimeZone();
    TimeZone toTimeZone = TimeZone.getTimeZone(timeZone);
    calendar.setTimeZone(fromTimeZone);
    calendar.add(Calendar.MILLISECOND, fromTimeZone.getRawOffset() * -1);
    if (fromTimeZone.inDaylightTime(calendar.getTime())) {
        calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1);
    }
    calendar.add(Calendar.MILLISECOND, toTimeZone.getRawOffset());
    if (toTimeZone.inDaylightTime(calendar.getTime())) {
        calendar.add(Calendar.MILLISECOND, toTimeZone.getDSTSavings());
    }
    increaseCalenderDateBy(calendar, increaseDateBy);
    increaseCalenderMinuteBy(calendar, increaseMinutesBy);
    return calendar.getTime();
}

public static void getTimeBetweenRange() throws ParseException {
    String string1 = "10:11:13";
    Date time1 = new SimpleDateFormat("HH:mm:ss").parse(string1);
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(time1);
    calendar1.add(Calendar.DATE, 1);
    System.out.println(calendar1.getTime().toString());

    String string2 = "18:49:00";
    Date time2 = new SimpleDateFormat("HH:mm:ss").parse(string2);
    Calendar calendar2 = Calendar.getInstance();
    calendar2.setTime(time2);
    calendar2.add(Calendar.DATE, 1);
    System.out.println(calendar2.getTime().toString());

    Date d = convertCurrentTimeToSpecificTimeZone("America/Chicago", 2, 30);
    Calendar calendar3 = Calendar.getInstance();
    calendar3.setTime(d);
    System.out.println(calendar3.getTime().toString());

    Date x = calendar3.getTime();
    if (x.after(calendar1.getTime()) && x.before(calendar2.getTime())) {
        // checkes whether the current time is between 14:49:00 and 20:11:13.
        System.out.println(true);
    } else
        System.out.println(false);
}

So the output for my below code is:

Fri Jan 02 10:11:13 IST 1970
Fri Jan 02 18:49:00 IST 1970
Fri Jan 31 03:15:07 IST 2020
kalpesh
  • 63
  • 1
  • 7
  • 1
    I recommend you don’t use any of the classes `Date`, `SimpleDateFormat`, `Calendar` and `TimeZone`. They are all poorly designed and long outdated. Instead use `ZonedDateTime`, ZoneId` and `DateTimeFormatter`, all from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Jan 29 '20 at 17:22
  • It’s not clear, sorry. Should `10:11:13` (the start and end times) be understood in America/Chicago time zone? Or your or the user’s own time zone? Or…? – Ole V.V. Jan 29 '20 at 17:23
  • @Ole V.V. - Yes, 10:11:13 (the start and end times) to be understood in America/Chicago time zone. – kalpesh Jan 30 '20 at 10:09

3 Answers3

2

It’s not very clear. For this answer I am assuming that all of your times are to be understood in America/Chicago time zone. Please revert if this was not what you intended.

java.time

    ZoneId zone = ZoneId.of("America/Chicago");

    ZonedDateTime zdt = ZonedDateTime.now(zone).plusDays(2).plusMinutes(30);

    LocalTime rangeStart = LocalTime.parse("10:11:13");
    LocalTime rangeEnd = LocalTime.parse("18:49:00");

    LocalTime time = zdt.toLocalTime();
    if (!time.isBefore(rangeStart) && time.isBefore(rangeEnd)) {
        System.out.println("Yes");
    } else {
        System.out.println("No");
    }

When I ran this code snippet just now (at 11:30 Chicago time), the output was:

Yes

I am using java.time, the modern Java date and time API, and recommend that you do the same. It’s so much nicer to work with than the old, outdated and poorly designed classes Date, SimpleDateFormat, Calendar and TimeZone.

A LocalTime is a time of day from 00:00 (inclusive) to 24:00 (exclusive). By comparing LocalTimeobjects we are ignoring the date and have no trouble with irrelevant dates in 1970 or some other time in history.

Edit:

Also is it possible to get the date and time of rangeStart and rangeEnd in order to verify for which particular day and time we are checking the conditions?

No, that would not make sense. Since a LocalTime is a time of day without date, there is no way to get a date out of it. But you can print the ZonedDateTime and verify its date part. And to assure yourself that the code is correct, write some unit tests.

Link: Oracle tutorial: Date Time explaining how to use java.time.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Yes, all the times should be in the America/Chicago time zone. However, timezone can be changed if required. Let me try out your code, will let you know if it satisfies the requirement. Thanks buddy. – kalpesh Jan 30 '20 at 10:08
  • Great, sounds like I had a lucky strike. You can just change the time zone in the first code line to use a different one. – Ole V.V. Jan 30 '20 at 10:14
  • Thank you Ole V.V.! I guess it worked as expected. Also is it possible to get the date and time of rangeStart and rangeEnd in order to verify for which particular day and time we are checking the conditions? – kalpesh Jan 30 '20 at 10:23
  • No, you can’t, see my edit. You need to trust that it’s correct. :-) – Ole V.V. Feb 01 '20 at 14:49
1

All I want to check if the current time from any timezone falls under the range of 10 am to 6 pm. If Yes, print "yes" else print "no".

For this, the following code will do the job.

LocalTime lt = LocalTime.now();
if( lt.isAfter( LocalTime.of( 10, 0 ) ) && lt.isBefore( LocalTime.of( 18, 0 ) ) ) System.out.println( "Yes" );
else System.out.println( "No" );

Since you have Date instances with you, you can convert them into LocalTime instances as shown below and use the same mechanism of comparison.

Date d = new Date(); //Change this to your way of creating the Date instance
LocalTime lt = LocalDateTime.ofEpochSecond( d.getTime(), 0, ZoneOffset.ofHours( 0 ) ).toLocalTime();

Hope this helps.

Sree Kumar
  • 2,012
  • 12
  • 9
  • Thank you @Sree Kumar. But when I run this line of code : LocalTime lt = LocalDateTime.ofEpochSecond( d.getTime(), 0, null ).toLocalTime(); It gives me null pointer exception. – kalpesh Jan 30 '20 at 10:13
  • @kalpesh Sorry, my mistake. I have edited the code now. Can you check? I have included a default ```ZoneOffset``` of 0, instead of ```null```. – Sree Kumar Jan 30 '20 at 11:50
1

A simple approach might be to parse your time Strings to instances of LocalTime and compare them. You have to decide if the start and end time are inclusive or not...

Support some formattings because you might have to pass Strings with AM/PM or without:

public static boolean isInTimeSlot(String time, String timeSlotStart, String timeSlotEnd) {
    // create a formatter that supports different formats for the String arguments
    DateTimeFormatter parserDtf = DateTimeFormatter.ofPattern("[hh:mm:ss a][HH:mm:ss][h a]");
    // parse each argument to a LocalTime
    LocalTime timeOfDay = LocalTime.parse(time, parserDtf);
    LocalTime fromTime = LocalTime.parse(timeSlotStart, parserDtf);
    LocalTime toTime = LocalTime.parse(timeSlotEnd, parserDtf);
    // and return if the given time is in the time slot (including start and end time)
    return timeOfDay.equals(fromTime) || timeOfDay.equals(toTime)
            || (timeOfDay.isAfter(fromTime) && timeOfDay.isBefore(toTime));
}

If you run it in a main like this

public static void main(String[] args) {
    // provide some sample times
    String[] times = { "10:31:17", "09:59:59", "6 PM", "4 AM", "06:00:01 PM" };
    // provide a time slot
    String from = "10 AM";
    String to = "6 PM";

    // check the method for each time string
    for (String time : times) {
        if (isInTimeSlot(time, from, to)) {
            System.out.println(time + " is in the time slot at or between "
                                + from + " and " + to);
        } else {
            System.err.println(time + " is not in the time slot at or between " 
                                + from + " and " + to);
        }
    }
}

the output will be

10:31:17 is in the time slot at or between 10 AM and 6 PM
09:59:59 is not in the time slot at or between 10 AM and 6 PM
6 PM is in the time slot at or between 10 AM and 6 PM
4 AM is not in the time slot at or between 10 AM and 6 PM
06:00:01 PM is not in the time slot at or between 10 AM and 6 PM
deHaar
  • 17,687
  • 10
  • 38
  • 51
  • when you pass the timings like this: String[] times = { "10:31:17", "09:59:59", "6 PM", "4 AM", "06:00:01 PM" }; Java will consider 10:31:17 as the time of default Date -1 Jan 1970 and same for other timings. But i need timings based on timezone and as reference from today's date. – kalpesh Jan 30 '20 at 10:10
  • Yes, this solution doesn't handle the zones itself, but you could easily extend the method to take a `ZoneId` or a `ZoneOffset` and use `ZonedDateTime` or `OffsetDateTime`. See the answer given by @OleV.V. – deHaar Jan 30 '20 at 10:20