71

I have timespans:

String time1 = 01:00:00

String time2 = 05:00:00

I want to check if time1 and time2 both lies between 20:11:13 and 14:49:00.

Actually, 01:00:00 is greater than 20:11:13 and less than 14:49:00 considering 20:11:13 is always less than 14:49:00. This is given prerequisite.

So what I want is, 20:11:13 < 01:00:00 < 14:49:00.

So I need something like that:

 public void getTimeSpans()
{
    boolean firstTime = false, secondTime = false;
    
    if(time1 > "20:11:13" && time1 < "14:49:00")
    {
       firstTime = true;
    }
    
    if(time2 > "20:11:13" && time2 < "14:49:00")
    {
       secondTime = true;
    }
 }

I know that this code does not give correct result as I am comparing the string objects.

How to do that as they are the timespans but not the strings to compare?

Community
  • 1
  • 1
sjain
  • 23,126
  • 28
  • 107
  • 185
  • 4
    How can this ever be true without considering a date? If a time is greater than 20:11:13, if cannot possibly be less than 14:49:00. – jalynn2 Jul 17 '13 at 10:59
  • @jalynn2 - Sorry for not being clear. Actually, `01:00:00` is greater than `20:11:13` and less than `14:49:00` considering `20:11:13` is always less than `14:49:00`. This is given prerequisite. – sjain Jul 17 '13 at 11:04
  • 2
    If you are giving the format HH:MM:SS, then `01:00:00` is not greater then `20:11:13` on the same day, and `20:11:13` is never less than `14:49:00`. If you are trying to determine if the time is between `20:11:13` on one day and `14:49:00` on the next day, then you will need to introduce a date into your comparisons. – jalynn2 Jul 17 '13 at 11:35
  • Isn't it possible without considering the dates because `20:11:13` is always less than `14:49:00` ? – sjain Jul 17 '13 at 11:55
  • 4
    20 > 14, is it not? so `20:11:13` is greater than `14:49:00`. "11 minutes before 3 in the afternoon" is not later than "11 minutes after 8 in the evening" on the same day. What am I missing? – jalynn2 Jul 17 '13 at 11:57
  • I think I get it... if the compare is 20h to 21h then 21:30 fails.. if its 20h 19:59 then all times would pass.. – MollyCat Jul 17 '13 at 12:28
  • my answer is so much easier. and I suspect it runs heaps faster. I don't mean to be cocky, but take a look. – MollyCat Jul 17 '13 at 12:52
  • You should reduce 20 by 24 first: 20-24 = -4, then it will be the correct comparison: -4 < 1 < 14 or -4 < 5 < 14 – Harun Mar 22 '22 at 03:38

32 Answers32

69

You can use the Calendar class in order to check.

For example:

try {
    String string1 = "20:11:13";
    Date time1 = new SimpleDateFormat("HH:mm:ss").parse(string1);
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(time1);
    calendar1.add(Calendar.DATE, 1);


    String string2 = "14:49:00";
    Date time2 = new SimpleDateFormat("HH:mm:ss").parse(string2);
    Calendar calendar2 = Calendar.getInstance();
    calendar2.setTime(time2);
    calendar2.add(Calendar.DATE, 1);

    String someRandomTime = "01:00:00";
    Date d = new SimpleDateFormat("HH:mm:ss").parse(someRandomTime);
    Calendar calendar3 = Calendar.getInstance();
    calendar3.setTime(d);
    calendar3.add(Calendar.DATE, 1);

    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);
    }
} catch (ParseException e) {
    e.printStackTrace();
}
AtifSayings
  • 756
  • 14
  • 23
Konstantin Yovkov
  • 62,134
  • 8
  • 100
  • 147
  • Wonderful. I will try and let you know. – sjain Jul 17 '13 at 11:07
  • Your code checks if the current time is between `20:11:13` and `14:49:00`. What I want is to check if `01:00:00` is between `20:11:13` and `14:49:00`. – sjain Jul 17 '13 at 11:35
  • Actually, `01:00:00` is greater than `20:11:13` and less than `14:49:00` considering `20:11:13` is always less than `14:49:00`. This is given prerequisite. So what I want is, `20:11:13 < 01:00:00 < 14:49:00`. Your code is considering the same day and so not working. – sjain Jul 17 '13 at 11:49
  • 2
    Then you will have to mark somewhere that those times are not in the same day ! – Konstantin Yovkov Jul 17 '13 at 11:50
  • 1
    Unless the time you are checking is `23:00:00`. You need to have a date associated, or you need to check that the time is between `20:11:13` and `24:00:00` or between `00:00:00` and `14:49:00` – jalynn2 Jul 17 '13 at 12:01
  • Ok that's working fine. But one question is: Can't we check that if time is less than 00:00:00, only then do `calendar2.add(Calendar.DATE, 1);` else not ? – sjain Jul 17 '13 at 12:09
  • 1
    I did that remaining comparison too using `Date currentTime = new SimpleDateFormat("HH:mm:ss").parse("00:00:00"); Calendar calendar = Calendar.getInstance(); calendar.setTime(currentTime); calendar.add(Calendar.DATE, 1);`. Let me check out complete. – sjain Jul 17 '13 at 12:31
  • What s the purpose of these lines "calendar2.add(Calendar.DATE, 1);" and " calendar3.add(Calendar.DATE, 1); " ? – ABI Feb 23 '16 at 10:22
  • 3
    This probably gives the wrong answer if someRandomTime lies between string1 and "00:00:00". Please correct me if I'm wrong. – Narayan Acharya Jul 28 '16 at 19:28
  • 1
    What if I want to compare two time stamp of format `MM/dd/yyyy HH:mm:ss` – Maveňツ Feb 23 '17 at 06:12
  • 2
    its showing 11:44 is inbetween 19:28 to 23:59 ... any solution for that. – Gundu Bandgar Sep 10 '17 at 09:26
  • FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Apr 17 '18 at 18:39
  • why are there 4 dates, can you explain? I get that 1st date is associated with start time, second with the end time, third with some random time that we want to check, but why is there a 4th date which you say `checkes whether the current time..` I want to check time that is manually passed as param. is it checking current time of the day, or will it check manually passed timeString? – ansh sachdeva Aug 19 '19 at 19:58
  • It only works for same-day intervals. Will not work in interval like 11:00 PM to 08:00 AM – Dharmik Thakkar Apr 28 '20 at 12:04
  • It doesn't work for 6:00 PM to 8:00 AM and current time is 5:00 AM – donmj May 18 '21 at 16:47
  • Then just change the second time to (Calendar.DATE, 2) – Abhinav Raja Aug 06 '22 at 00:46
57

tl;dr

20:11:13 < 01:00:00 < 14:49:00

LocalTime target = LocalTime.parse( "01:00:00" ) ;
Boolean targetInZone = ( 
    target.isAfter( LocalTime.parse( "20:11:13" ) ) 
    && 
    target.isBefore( LocalTime.parse( "14:49:00" ) ) 
) ; 

java.time.LocalTime

The java.time classes include LocalTime to represent a time-of-day only without a date and without a time zone.

So what I want is, 20:11:13 < 01:00:00 < 14:49:00.

First we define the boundaries. Your input strings happen to comply with standard ISO 8601 formats. The java.time classes use ISO 8601 formats by default, so no need to specify a formatting pattern.

LocalTime start = LocalTime.parse( "20:11:13" );
LocalTime stop = LocalTime.parse( "14:49:00" );

And define our test case, the target 01:00:00.

LocalTime target = LocalTime.parse( "01:00:00" );

Now we are set up to compare these LocalTime objects. We want to see if the target is after the later time but before the earlier time. That means middle of the night in this case, between approximately 8 PM and 3 AM the next morning.

Boolean isTargetAfterStartAndBeforeStop = ( target.isAfter( start ) && target.isBefore( stop ) ) ;

That test can be more simply stated as “not between 3 AM and 8 PM”. We could then generalize to any pair of LocalTime objects where we test for between if the start comes before the stop with a 24-hour clock, and not between if start comes after the stop (as in the case of this Question).

Further more, spans of time are usually handled with the Half-Open approach where the beginning is inclusive while the ending is exclusive. So a "between" comparison, strictly speaking, would be “is the target equal to or later than start AND the target is before stop”, or more simply, “is target not before start AND before stop”.

Boolean isBetweenStartAndStopStrictlySpeaking = 
    ( ( ! target.isBefore( start ) && target.isBefore( stop ) ) ;

If the start is after the stop, within a 24-hour clock, then assume we want the logic suggested in the Question (is after 8 PM but before 3 AM).

if( start.isAfter( stop ) ) {
    return ! isBetweenStartAndStopStrictlySpeaking ;
} else {
    return isBetweenStartAndStopStrictlySpeaking ;
}

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • This doesn't work for the target time 18:00 and the start is 21:00 and stop is 03:00. In this case target is not before start but target is also not before stop. So isBetweenStartAndStopStrctlySpeaking is false. Since start is after stop, we negate it which equates to saying 18:00 is between 21:00 and 03:00 which is false. – thisisananth Feb 27 '19 at 19:10
  • 1
    @thisisananth You have flipped the logic of the Question. The Question specifically asks if a target is ***after* the later time** and ***before* the earlier time**: *So what I want is, 20:11:13 < 01:00:00 < 14:49:00.*. So in your example, 18:00 (6 PM) is *not* between 21:00 and 03:00 whereas 1 AM *is* between 9 PM and 3 AM. Whichever logic is dictated by your business logic, flip the Boolean logic of my code. But you cannot have *both* 1 AM and 6 PM being between mid-evening and mid-morning times -- there would be not point in asking the question of “is between”. – Basil Bourque Feb 27 '19 at 20:15
24

The answer given by @kocko works in only same day.
If start time "23:00:00" and end "02:00:00"[next day] and current time is "01:30:00" then result will false...
I modified the @kocko's answer to work perfectly

public static boolean isTimeBetweenTwoTime(String initialTime, String finalTime, 
    String currentTime) throws ParseException {

    String reg = "^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";
    if (initialTime.matches(reg) && finalTime.matches(reg) && 
        currentTime.matches(reg)) 
    {
        boolean valid = false;
        //Start Time
        //all times are from java.util.Date
        Date inTime = new SimpleDateFormat("HH:mm:ss").parse(initialTime);
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(inTime);

        //Current Time
        Date checkTime = new SimpleDateFormat("HH:mm:ss").parse(currentTime);
        Calendar calendar3 = Calendar.getInstance();
        calendar3.setTime(checkTime);

        //End Time
        Date finTime = new SimpleDateFormat("HH:mm:ss").parse(finalTime);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(finTime);

        if (finalTime.compareTo(initialTime) < 0) 
        {
            calendar2.add(Calendar.DATE, 1);
            calendar3.add(Calendar.DATE, 1);
        }

        java.util.Date actualTime = calendar3.getTime();
        if ((actualTime.after(calendar1.getTime()) || 
             actualTime.compareTo(calendar1.getTime()) == 0) && 
             actualTime.before(calendar2.getTime())) 
        {
            valid = true;
            return valid;
        } else {
            throw new IllegalArgumentException("Not a valid time, expecting 
            HH:MM:SS format");
        }
    }
}

Output

"07:00:00" - "17:30:00" - "15:30:00" [current] - true
"17:00:00" - "21:30:00" - "16:30:00" [current] - false
"23:00:00" - "04:00:00" - "02:00:00" [current] - true
"00:30:00" - "06:00:00" - "06:00:00" [current] - false 

(I have included lower limit value to [upper limit value-1])

ZooMagic
  • 616
  • 7
  • 15
Surendra Jnawali
  • 3,190
  • 5
  • 28
  • 44
  • 1
    this is the best answer @Surendra Jnawali – lacas Jan 22 '15 at 12:19
  • 1
    This also fails if current time is 23:40:00 i.e greater than start time and less than equals to 23:59:59. – Jitender Dev Jan 29 '15 at 05:59
  • @David, Sorry I didn't get you. Can you please provide current, start and end time in unsatisfied result. So that if any problem I will fix.... – Surendra Jnawali Jan 29 '15 at 12:58
  • 2
    @SurendraJnawali Sure , Pls try this "23:00:00" - "06:00:00" - "23:40:00" [current] - false . I have also posted an answer updating your answer. All credit goes to you ofcourse. – Jitender Dev Jan 29 '15 at 18:21
  • how to check if two times pass the time? example: let us say you worked between 21:00:00 to 06:00:00. then want the system to calculate how many hours night work you have worked and the "night-work" is between 23:00:00 to 06:00:00 – TheCrazyProfessor Jan 08 '18 at 08:14
  • 1
    THIS DOES NOT WORK CORRECTLY! The corrected one from Jitender Dev does – misterti Aug 21 '19 at 08:11
  • **Update:** The terrible classes `Date` and `Calendar` classes were supplanted years ago by the modern *java.time* classes defined in JSR 310. – Basil Bourque Feb 13 '21 at 17:32
22

Modified @Surendra Jnawali' code. It fails

if current time is 23:40:00 i.e greater than start time and less than equals to 23:59:59.

All credit goes to the real owner

This is how it should be :This works perfect

public static boolean isTimeBetweenTwoTime(String argStartTime,
            String argEndTime, String argCurrentTime) throws ParseException {
        String reg = "^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";
        //
        if (argStartTime.matches(reg) && argEndTime.matches(reg)
                && argCurrentTime.matches(reg)) {
            boolean valid = false;
            // Start Time
            java.util.Date startTime = new SimpleDateFormat("HH:mm:ss")
                    .parse(argStartTime);
            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(startTime);

            // Current Time
            java.util.Date currentTime = new SimpleDateFormat("HH:mm:ss")
                    .parse(argCurrentTime);
            Calendar currentCalendar = Calendar.getInstance();
            currentCalendar.setTime(currentTime);

            // End Time
            java.util.Date endTime = new SimpleDateFormat("HH:mm:ss")
                    .parse(argEndTime);
            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(endTime);

            //
            if (currentTime.compareTo(endTime) < 0) {

                currentCalendar.add(Calendar.DATE, 1);
                currentTime = currentCalendar.getTime();

            }

            if (startTime.compareTo(endTime) < 0) {

                startCalendar.add(Calendar.DATE, 1);
                startTime = startCalendar.getTime();

            }
            //
            if (currentTime.before(startTime)) {

                System.out.println(" Time is Lesser ");

                valid = false;
            } else {

                if (currentTime.after(endTime)) {
                    endCalendar.add(Calendar.DATE, 1);
                    endTime = endCalendar.getTime();

                }

                System.out.println("Comparing , Start Time /n " + startTime);
                System.out.println("Comparing , End Time /n " + endTime);
                System.out
                        .println("Comparing , Current Time /n " + currentTime);

                if (currentTime.before(endTime)) {
                    System.out.println("RESULT, Time lies b/w");
                    valid = true;
                } else {
                    valid = false;
                    System.out.println("RESULT, Time does not lies b/w");
                }

            }
            return valid;

        } else {
            throw new IllegalArgumentException(
                    "Not a valid time, expecting HH:MM:SS format");
        }

    }

RESULT

Comparing , Start Time /n    Thu Jan 01 23:00:00 IST 1970
Comparing , End Time /n      Fri Jan 02 02:00:00 IST 1970
Comparing , Current Time /n  Fri Jan 02 01:50:00 IST 1970
RESULT, Time lies b/w
Jitender Dev
  • 6,907
  • 2
  • 24
  • 35
16

There are lots of answers here but I want to provide a new one which is similar with Basil Bourque's answer but with a full code example. So please see the method below:

private static void checkTime(String startTime, String endTime, String checkTime) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss", Locale.US);
    LocalTime startLocalTime = LocalTime.parse(startTime, formatter);
    LocalTime endLocalTime = LocalTime.parse(endTime, formatter);
    LocalTime checkLocalTime = LocalTime.parse(checkTime, formatter);

    boolean isInBetween = false;
    if (endLocalTime.isAfter(startLocalTime)) {
      if (startLocalTime.isBefore(checkLocalTime) && endLocalTime.isAfter(checkLocalTime)) {
          isInBetween = true;
      }
    } else if (checkLocalTime.isAfter(startLocalTime) || checkLocalTime.isBefore(endLocalTime)) {
        isInBetween = true;
    }

    if (isInBetween) {
        System.out.println("Is in between!");
    } else {
        System.out.println("Is not in between!");
    }
}

Either if you are calling this method using:

checkTime("20:11:13", "14:49:00", "01:00:00");

Or using:

checkTime("20:11:13", "14:49:00", "05:00:00");

The result will be:

Is in between!
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
15
 Calendar now = Calendar.getInstance();

 int hour = now.get(Calendar.HOUR_OF_DAY); // Get hour in 24 hour format
 int minute = now.get(Calendar.MINUTE);

 Date date = parseDate(hour + ":" + minute);
 Date dateCompareOne = parseDate("08:00");
 Date dateCompareTwo = parseDate("20:00");

 if (dateCompareOne.before( date ) && dateCompareTwo.after(date)) {
    //your logic
 }

 private Date parseDate(String date) {

    final String inputFormat = "HH:mm";
    SimpleDateFormat inputParser = new SimpleDateFormat(inputFormat, Locale.US);
    try {
         return inputParser.parse(date);
    } catch (java.text.ParseException e) {
         return new Date(0);
    }
 }

Further more, to be more precise, If you compare a time between an interval more than 00:00 to 24:00 of that day, you need to parse the day too.

kalan nawarathne
  • 1,944
  • 27
  • 26
  • 1
    The is one of the best and robust answers ever given. I would recommend every one to try this. Earlier I used Calendar object to check current time with after and before methods. The results were confusing, sometimes it was right and some times it was wrong. For example: 7:00 am is not after 7:00 am but using calendar object it was giving the status as true and some times false. – krisDrOid Apr 19 '18 at 19:36
  • These terrible date-time classes were supplanted years ago by the *java.time* classes with the adoption of JSR 310. – Basil Bourque Apr 10 '19 at 17:07
5

Following method checks whether 'validateTime' is between 'startTime' & 'endTime' or not while considering possibility that 'endTime' can be a next day. To use it properly parse your dates in "HH:mm" formant.

 public static final boolean isBetweenValidTime(Date startTime, Date endTime, Date validateTime)
 {
        boolean validTimeFlag = false;

        if(endTime.compareTo(startTime) <= 0)
        {
            if(validateTime.compareTo(endTime) < 0 || validateTime.compareTo(startTime) >= 0)
            {
                 validTimeFlag = true;
            }
        }
        else if(validateTime.compareTo(endTime) < 0 && validateTime.compareTo(startTime) >= 0)
        {
             validTimeFlag = true;  
        }

        return validTimeFlag;
 }
aniketKumkar
  • 51
  • 1
  • 4
4

After reading a few replies, I feel the writing is too complicated. Try my code

 public static boolean compare(String system_time, String currentTime, String endtimes) {
    try {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");

        Date startime = simpleDateFormat.parse("19:25:00");
        Date endtime = simpleDateFormat.parse("20:30:00");

        //current time
        Date current_time = simpleDateFormat.parse("20:00:00");

    if (current_time.after(startime) && current_time.before(endtime)) {
            System.out.println("Yes");
            return true;
      }
    else if (current_time.after(startime) && current_time.after(endtime)) {
         return true; //overlap condition check
      }
     else {
            System.out.println("No");
            return false;
        }
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return false;
 } 
Omer
  • 534
  • 7
  • 19
Fomovet
  • 313
  • 1
  • 5
  • 15
3

Java 8 - LocalDateTime

What about this?

final LocalDateTime now = LocalDateTime.now();
final LocalDateTime minRange = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), 22, 30); //Today, 10:30pm
LocalDateTime maxRange = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), 6, 30); //Tomorrow, 6:30am
maxRange = maxRange.plusDays(1); //Ensures that you don't run into an exception if minRange is the last day in the month.
if (now.isAfter(minRange) && now.isBefore(maxRange)) {
    //Action
}
codepleb
  • 10,086
  • 14
  • 69
  • 111
3

Using LocalTime would simply ignore the Date value:

public class TimeIntervalChecker {

static final LocalTime time1 = LocalTime.parse( "20:11:13"  ) ;
static final LocalTime time2 = LocalTime.parse( "14:49:00" ) ;

    public static void main(String[] args) throws java.lang.Exception {

        LocalTime nowUtcTime = LocalTime.now(Clock.systemUTC());

        if (nowUtcTime.isAfter(time1) && nowUtcTime.isBefore(time2)){
              System.out.println(nowUtcTime+" is after: "+ time1+" and before: "+ time2);
        } 

}
kmarabet
  • 1,087
  • 3
  • 14
  • 31
  • (a) Looks a lot like [my Answer](http://stackoverflow.com/a/39712175/642706). I do not see any added-value. (b) No need to pass [`Clock.systemUTC()`](https://docs.oracle.com/javase/8/docs/api/java/time/Clock.html#systemUTC--) as that is the default when no argument is passed. Simply use: [`Instant.now()`](https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html#now--). – Basil Bourque Apr 11 '17 at 03:32
  • Yes maybe looks like yours, but less verbose and to the point if we just want to **Check if a given time lies between two times regardless of date**. The **Clock.systemUTC()** is used to use UTC timezone for current date otherwise a local timezone is used by default. – kmarabet Apr 11 '17 at 06:38
  • 1
    You are incorrect about the need for passing Clock. The doc explicitly says UTC is the default and that you need pass a clock only for testing with false/altered clocks. You are confusing `Instant.now` with the other classes’ `.now` methods which do indeed use the JVM’s current default time zone if omitted. – Basil Bourque Apr 11 '17 at 08:17
2

As with the help of @kocko, the complete working code is as below:

try{
Date time11 = new SimpleDateFormat("HH:mm:ss").parse("20:11:13");
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(time11);

Date time22 = new SimpleDateFormat("HH:mm:ss").parse("14:49:00");
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(time22);

Date currentTime = new SimpleDateFormat("HH:mm:ss").parse("00:00:00");
Calendar startingCalendar = Calendar.getInstance();
startingCalendar.setTime(currentTime);
startingCalendar.add(Calendar.DATE, 1);



//let's say we have to check about 01:00:00
String someRandomTime = time1;
Date d = new SimpleDateFormat("HH:mm:ss").parse(someRandomTime);
Calendar calendar3 = Calendar.getInstance();
calendar3.setTime(d);

if(startingCalendar.getTime().after(calendar1.getTime()))
{
calendar2.add(Calendar.DATE, 1);

    calendar3.add(Calendar.DATE, 1);
}

Date x = calendar3.getTime();

if (x.after(calendar1.getTime()) && x.before(calendar2.getTime())) 
{
System.out.println("Time is in between..");
}
else
{
System.out.println("Time is not in between..");
}

} catch (ParseException e) 
{
e.printStackTrace();
}
sjain
  • 23,126
  • 28
  • 107
  • 185
2

Sounds to me that your problem is an OR situation... You want to check if time1 > 20:11:13 OR time1 < 14:49:00.

There will never be a time greater to 20:11:13 that exceeds your range through the other end (14:49:00) and viceversa. Think of it as if you are checking that a time is NOT between a properly ordered couple of timestamps.

coya
  • 264
  • 2
  • 15
1

The Actual working function will be as follows

public static boolean isTimeBetweenTwoTime(Date startTime, Date stopTime, Date currentTime) {
    //Start Time
    Calendar StartTime = Calendar.getInstance();
    StartTime.setTime(startTime);
    //Current Time
    Calendar CurrentTime = Calendar.getInstance();
    CurrentTime.setTime(currentTime);
    //Stop Time
    Calendar StopTime = Calendar.getInstance();
    StopTime.setTime(stopTime);

    if (stopTime.compareTo(startTime) < 0) {
        if (CurrentTime.compareTo(StopTime) < 0) {
            CurrentTime.add(Calendar.DATE, 1);
        }
        StopTime.add(Calendar.DATE, 1);
    }
    return CurrentTime.compareTo(StartTime) >= 0 && CurrentTime.compareTo(StopTime) < 0;
}
1

In your case the starting time (20:11:13) is larger than the ending time (14:49:00). It is a reasonable assumption that you could solve the problem by adding a day on the ending time or subtracting a day from the starting time. if you do so, you will be trapped because you do not know on which day the testing time is.

You can avoid this trap by checking whether your testing time is between the ending time and starting time. If true, then result is "not in between"; else result is "well in between".

Here is the function in JAVA I have been using. It works so far for me. Good luck.

boolean IsTimeInBetween(Calendar startC, Calendar endC, Calendar testC){
    // assume year, month and day of month are all equal.
    startC.set(1,1,1);
    endC.set(1,1,1);
    testC.set(1,1,1);

    if (endC.compareTo(startC) > 0) {
        if ((testC.compareTo(startC)>=0) && (testC.compareTo(endC)<=0)) {
            return true;
        }else {
            return false;
        }
    }else if  (endC.compareTo(startC) < 0) {
        if ((testC.compareTo(endC) >= 0) && (testC.compareTo(startC) <= 0)) {
            return false;
        } else {
            return true;
        }
    } else{ // when endC.compareTo(startC)==0, I return a ture value. Change it if you have different application. 
        return true;
    }
}

To create a Calender instance you can use:

Calendar startC = Calendar.getInstance();
startC.set(Calendar.HOUR_OF_DAY, 20);
startC.set(Calendar.MINUTE,11);
startC.set(Calendar.SECOND,13);
Diiiiii
  • 209
  • 3
  • 8
1

In the code snipet below, it is being verified that if the current time (can be any) exists between start and end time or not:

        Calendar startTimeCal = Calendar.getInstance();
        startTimeCal.setTime(startTime);

        int startTimeHour = startTimeCal.get(Calendar.HOUR_OF_DAY);

        if (startTimeHour == 0){
            startTimeHour = 24;
        }

        int startTimeMinutes = startTimeCal.get(Calendar.MINUTE);

        Calendar curTimeCal = Calendar.getInstance();
        curTimeCal.setTime(currentTime);

        int curTimeHour = curTimeCal.get(Calendar.HOUR_OF_DAY);
        int curTimeMinutes = curTimeCal.get(Calendar.MINUTE);

        Calendar endTimeCal = Calendar.getInstance();
        endTimeCal.setTime(endTime);

        int endTimeHour = endTimeCal.get(Calendar.HOUR_OF_DAY);

        if (endTimeHour == 0) {
            endTimeHour = 24;
        }

        int endTimeMinutes = endTimeCal.get(Calendar.MINUTE);

        if (((curTimeHour > startTimeHour) || (curTimeHour == startTimeHour && curTimeMinutes >= startTimeMinutes)) &&
                ((curTimeHour < endTimeHour) || (curTimeHour == endTimeHour && curTimeMinutes <= endTimeHour))) {
          //time exists between start and end time
        } else {
              //time doesn't exist between start and end time
        }
Bilal Ahmed Yaseen
  • 2,506
  • 2
  • 23
  • 48
1

As many people noticed, it's not a date problem, it's a logic problem. Let's assume a day is splitted in two intervals: one lies between 20:11:13 and 14:49:00, while the other lies between 14:49:00 and 20:11:13 (which interval the extremes belong is up to you). If you want to check if a certain time is included in the 20:11:13/14:49:00 one, the one you're interested of, just check if it's included in the other one, 14:49:00/20:11:13, which is much easier because the natural order of the numbers, and then negate the result.

1

I did it this way:

LocalTime time = LocalTime.now();
if (time.isAfter(LocalTime.of(02, 00)) && (time.isBefore(LocalTime.of(04, 00))))
{
    log.info("Checking after 2AM, before 4AM!");                    
}

Edit:

String time1 = "01:00:00";  
String time2 = "15:00:00";  
LocalTime time = LocalTime.parse(time2);  
if ((time.isAfter(LocalTime.of(20,11,13))) || (time.isBefore(LocalTime.of(14,49,0))))  
{  
    System.out.println("true");  
}  
else  
{  
    System.out.println("false");  
}    
JasonH
  • 589
  • 9
  • 18
  • 1
    How does this Answer provide value over the existing Answers using `LocalTime`? – Basil Bourque Oct 18 '18 at 23:46
  • 2
    Nice demonstration of the use of `LocalTime`, but doesn’t really seem to answer the question as asked. Also avoid prefixed zeros: They work for `00`, `02` and `04`, but not for `08` and `09`. – Ole V.V. Oct 19 '18 at 09:54
  • Apologies - Y'all are correct @BasilBourque I will edit the answer. – JasonH Oct 19 '18 at 16:40
  • Still using octal literals. And still looks like a duplicate of existing Answers. – Basil Bourque Oct 19 '18 at 16:52
  • 1
    Dude, I appreciate the feedback, but this is why I dislike Stack sometimes: those are not octals, and nobody else here is using `LocalTime.of` – JasonH Oct 19 '18 at 20:09
  • LocalTime.parse <- this is only for API 26+ – ghita Feb 25 '19 at 11:48
  • 1
    @ghita For earlier Android, see the *ThreeTenABP* project that adapts the *ThreeTen-Backport* project. – Basil Bourque Apr 10 '19 at 17:14
  • 1
    @JasonH You are incorrect: An integer literal beginning with a zero such as `02` represents an [octal](https://en.m.wikipedia.org/wiki/Octal) (base-8) number. See [section 3.10.1 of the *Java Language Specification*](https://docs.oracle.com/javase/specs/jls/se12/html/jls-3.html#jls-3.10.1). – Basil Bourque Apr 10 '19 at 17:27
1

Here is a solution that uses the new Java 8 classes, is compact, requires no regular expressions or manual arithmetic operations. My solution is coded for inclusive startTime and exclusive endTime, but can easily be modified for your needs.

private boolean isTimeBetween(String timeToTest, String startTime, String endTime) {

    LocalTime timeToTestDt = LocalTime.parse(timeToTest, DateTimeFormatter.ISO_LOCAL_TIME);
    LocalTime startTimeDt = LocalTime.parse(startTime, DateTimeFormatter.ISO_LOCAL_TIME);
    LocalTime endTimeDt = LocalTime.parse(endTime, DateTimeFormatter.ISO_LOCAL_TIME);

    if(startTime.equals(endTime)) {
        return false;
    }
    else if(startTimeDt.isBefore(endTimeDt)) {  // Period does not cross the day boundary
        return (timeToTest.equals(startTime) || timeToTestDt.isAfter(startTimeDt)) 
                && timeToTestDt.isBefore(endTimeDt);
    } else {  // Time period spans two days, e.g. 23:00 to 2:00
        return (!((timeToTestDt.isAfter(endTimeDt) || timeToTest.equals(endTime)) 
                && timeToTestDt.isBefore(startTimeDt)));
    }
}

// getTimeSpans() from the original question would then look like this
public void getTimeSpans()
{
    boolean firstTime = isTimeBetween("01:00:00", "20:11:13", "14:49:00");
    boolean secondTime = isTimeBetween("05:00:00", "20:11:13", "14:49:00");
 }
Dmitry B.
  • 11
  • 2
1

Simple solution for all gaps:

    public boolean isNowTimeBetween(String startTime, String endTime) {
        LocalTime start = LocalTime.parse(startTime);//"22:00"
        LocalTime end = LocalTime.parse(endTime);//"10:00"
        LocalTime now = LocalTime.now();

        if (start.isBefore(end))
            return now.isAfter(start) && now.isBefore(end);

        return now.isBefore(start)
                ? now.isBefore(start) && now.isBefore(end)
                : now.isAfter(start) && now.isAfter(end);
}
Ilya
  • 31
  • 6
  • It’s good to use `LocalTime`, I agree. I don’t find your logic that simple and easy to follow, and it can certainly be still simpler. – Ole V.V. Jun 16 '20 at 19:35
1

I've implemented it in kotlin, and it's works as expected:

fun isInBetween(startTime: String, endTime: String, checkTime: String, timeFormat: String = "HH:mm:ss"): Boolean {

    val calendar1 = Calendar.getInstance().apply {
        time = SimpleDateFormat(timeFormat, Locale.ENGLISH).parse(startTime)!!
        add(Calendar.DATE, 1)
    }

    val calendar2 = Calendar.getInstance().apply {
        time = SimpleDateFormat(timeFormat, Locale.ENGLISH).parse(endTime)!!
        add(Calendar.DATE, 1)
    }

    val calendar3 = Calendar.getInstance().apply {
        time = SimpleDateFormat(timeFormat, Locale.ENGLISH).parse(checkTime)!!
        add(Calendar.DATE, 1)
    }

    if(calendar1.time > calendar2.time) {
        calendar2.add(Calendar.DATE, 2)
        calendar3.add(Calendar.DATE, 2)
    }

    val x = calendar3.time

    return (x.after(calendar1.time) && x.before(calendar2.time))
}

And it's result as followings:

Log.d("TAG", "08:00, 22:00, 13:40: ${isInBetween("08:00", "22:00", "13:40")}") // true
Log.d("TAG", "22:00, 08:00, 13:40: ${isInBetween("22:00", "08:00", "13:40")}") // false
Log.d("TAG", "22:00, 08:00, 05:40: ${isInBetween("22:00", "08:00", "05:40")}") // true
Log.d("TAG", "22:00, 08:00, 10:40: ${isInBetween("22:00", "08:00", "10:40")}") // false
Log.d("TAG", "22:00, 22:00, 22:10: ${isInBetween("22:00", "22:00", "22:10")}") // false
protanvir993
  • 2,759
  • 1
  • 20
  • 17
1

In my situation, I'm not interested at all in date times. So this is my solution which works solely on hours as integers:

boolean isInTimeRange(int startingHour, int endingHour, int hourOfDayToCheck) {
    if (endingHour > startingHour) {
        return hourOfDayToCheck >= startingHour && hourOfDayToCheck < endingHour;
    } else {
        return hourOfDayToCheck >= startingHour || hourOfDayToCheck < endingHour;
    }
}
1
LocalTime now = LocalTime.now();
LocalTime startTime = LocalTime.parse("23:00:00");
LocalTime endTime = LocalTime.parse("05:00:00");

        if (startTime.isAfter(endTime)) {
             return !(now.isAfter(endTime) && now.isBefore(startTime));

        } else {
            return (now.isAfter(startTime) && now.isBefore(endTime));
        }
NS404
  • 11
  • 2
1

The below solution should help in cases where StartTime is from the Previous Day, and EndTime is from the next day, and you want to check something in between.

    boolean isInBetween = false;
    if (endLocalTime.isAfter(startLocalTime)) {
        if (!startLocalTime.isAfter(checkLocalTime) && endLocalTime.isAfter(checkLocalTime)) {
            isInBetween = true;
        }
    } else if (checkLocalTime.isAfter(startLocalTime) || !checkLocalTime.isAfter(endLocalTime)) {
        isInBetween = true;
    }

    return isInBetween;

}
vaibs222
  • 21
  • 2
0

strip colons from the $time, $to and $from strings, convert to int and then use the following condition to check if the time is between from and to. Example is in php, but shouldn't matter.

if(($to < $from && ($time >= $from || $time <= $to)) ||
    ($time >= $from && $time <= $to)) {
    return true;
}
Fre Akus
  • 107
  • 2
0

Logically if you do the following you should always be ok granted we use military time...

if start time is greater than end time add 24 to end time else use times as is

compare current time to be inbetween start and end time.

0

Based on the ideas and solutions of most authors here, I'd like to share my refined solution with a presumably cleaner code:

    /**
 * Checks if some date is within a time window given by start and end dates
 *
 * @param checkDate - date to check if its hours and minutes is between the startDate and endDate
 * @param startDate - startDate of the time window
 * @param endDate - endDate of the time window
 * @return - returns true if hours and minutes of checkDate is between startDate and endDate
 */
public static boolean isDateBetweenStartAndEndHoursAndMinutes(Date checkDate, Date startDate, Date endDate) {
    if (startDate == null || endDate == null)
        return false;

    LocalDateTime checkLdt = LocalDateTime.ofInstant(Instant.ofEpochMilli(checkDate.getTime()), ZoneId.systemDefault());
    LocalDateTime startLdt = LocalDateTime.ofInstant(Instant.ofEpochMilli(startDate.getTime()), ZoneId.systemDefault());
    LocalDateTime endLdt = LocalDateTime.ofInstant(Instant.ofEpochMilli(endDate.getTime()), ZoneId.systemDefault());

    // Table of situations:
    // Input dates: start (a), end (b), check (c)
    // Interpretations:
    // t(x) = time of point x on timeline; v(x) = nominal value of x

    // Situation A - crossing midnight:
    // c INSIDE
    //      1) t(a) < t(c) < t(b) | v(b) < v(a) < v(c) // e.g. a=22:00, b=03:00, c=23:00 (before midnight)
    //      2) t(a) < t(c) < t(b) | v(c) < v(b) < v(a) // e.g. a=22:00, b=03:00, c=01:00 (after midnight)
    // c OUTSIDE
    //      3) t(c) < t(a) < t(b) | v(b) < v(c) < v(a) // e.g. a=22:00, b=03:00, c=21:00
    //      4) t(a) < t(b) < t(c) | v(b) < v(c) < v(a) // e.g. a=22:00, b=03:00, c=04:00

    //                              ^--- v(b) < v(a) always when shift spans around midnight!

    // Situation B - after/before midnight:
    // c INSIDE
    //      1) t(a) = t(c) < t(b) | v(a) = v(c) < v(b) // e.g. a=06:00, b=14:00, c=06:00
    //      2) t(a) < t(c) < t(b) | v(a) < v(c) < v(b) // e.g. a=06:00, b=14:00, c=08:00
    // c OUTSIDE
    //      3) t(c) < t(a) < t(b) | v(c) < v(a) < v(b) // e.g. a=06:00, b=14:00, c=05:00
    //      4) t(a) < t(b) = t(c) | v(a) < v(b) = v(c) // e.g. a=06:00, b=14:00, c=14:00
    //      5) t(a) < t(b) < t(c) | v(a) < v(b) < v(c) // e.g. a=06:00, b=14:00, c=15:00

    //                              ^--- v(a) < v(b) if shift starts after midnight and ends before midnight!

    // Check for situation A - crossing midnight?
    boolean crossingMidnight = endLdt.isBefore(startLdt);

    if (crossingMidnight) {
        // A.1
        if ((startLdt.isBefore(checkLdt) || startLdt.isEqual(checkLdt))  // t(a) < t(c)
                && checkLdt.isBefore(endLdt.plusDays(1))) // t(c) < t(b+1D)
            return true;

        // A.2
        if (startLdt.isBefore(checkLdt.plusDays(1))   // t(a) < t(c+1D)
                && checkLdt.isBefore(endLdt)) // t(c) < t(b)
            return true;

        // A.3
        if (startLdt.isBefore(endLdt.plusDays(1))   // t(a) < t(b+1D)
                && checkLdt.isBefore(startLdt)) // t(c) < t(a)
            return false;

        // A.4
        if (startLdt.isBefore(endLdt.plusDays(1))   // t(a) < t(b+1D)
                && checkLdt.isAfter(endLdt)) // t(b) < t(c)
            return false;
    } else {
        // B.1 + B.2
        if ((startLdt.isEqual(checkLdt) || startLdt.isBefore(checkLdt))  // t(a) = t(c) || t(a) < t(c)
                && checkLdt.isBefore(endLdt)) // t(c) < t(b)
            return true;
    }

    return false;
}

For the sake of completeness I've added the conditions of A.3 and A.4, but in productive code you can leave it out.

Now you can simply create your start and end dates, as well as your time you want to check and call this static method. The code would go then as follows:

Date check = new SimpleDateFormat("HH:mm:ss").parse("01:00:00");
Date start = new SimpleDateFormat("HH:mm:ss").parse("20:11:13");
Date end = new SimpleDateFormat("HH:mm:ss").parse("14:49:00");

if (isDateBetweenStartAndEndHoursAndMinutes(check, start, end)) {
    Print("checkDate is within start and End date!"); // adjust this true condition to your needs
}

For the TDD aspect I've added unit tests for the scenarios A and B as given above. Please feel free to check it out and report back if you find any errors or spots for optimization.

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

class LogiqDateUtilsTest  {

    private LocalDateTime startShiftSituationALdt = LocalDateTime.of(0, 1, 1, 22, 0);
    private Date startOfShiftSituationA = Date.from(startShiftSituationALdt.atZone(ZoneId.systemDefault()).toInstant());

    private LocalDateTime endShiftSituationALdt = LocalDateTime.of(0, 1, 1, 3, 0);
    private Date endOfShiftSituationA = Date.from(endShiftSituationALdt.atZone(ZoneId.systemDefault()).toInstant());

    private LocalDateTime startShiftSituationBLdt = LocalDateTime.of(0, 1, 1, 6, 0);
    private Date startOfShiftSituationB = Date.from(startShiftSituationBLdt.atZone(ZoneId.systemDefault()).toInstant());

    private LocalDateTime endShiftSituationBLdt = LocalDateTime.of(0, 1, 1, 14, 0);
    private Date endOfShiftSituationB = Date.from(endShiftSituationBLdt.atZone(ZoneId.systemDefault()).toInstant());

    @Test
    void testSituationA1() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 23, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertTrue(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationA, endOfShiftSituationA));
    }

    @Test
    void testSituationA2() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 1, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertTrue(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationA, endOfShiftSituationA));
    }

    @Test
    void testSituationA3() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 21, 1);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertFalse(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationA, endOfShiftSituationA));
    }

    @Test
    void testSituationA4() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 4, 1);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertFalse(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationA, endOfShiftSituationA));
    }

    @Test
    void testSituationB1() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 6, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertTrue(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationB, endOfShiftSituationB));
    }

    @Test
    void testSituationB2() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 8, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertTrue(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationB, endOfShiftSituationB));
    }

    @Test
    void testSituationB3() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 5, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertFalse(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationB, endOfShiftSituationB));
    }

    @Test
    void testSituationB4() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 14, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertFalse(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationB, endOfShiftSituationB));
    }

    @Test
    void testSituationB5() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 15, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertFalse(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationB, endOfShiftSituationB));
    }
}

Cheers!

ShadowGames
  • 1,110
  • 1
  • 10
  • 15
0
/**
 * @param initialTime - in format HH:mm:ss
 * @param finalTime   - in format HH:mm:ss
 * @param timeToCheck - in format HH:mm:ss
 * @return initialTime <= timeToCheck < finalTime
 * @throws IllegalArgumentException if passed date with wrong format
 */
public static boolean isTimeBetweenTwoTime(String initialTime, String finalTime, String timeToCheck) throws IllegalArgumentException {
    String reg = "^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";
    if (initialTime.matches(reg) && finalTime.matches(reg) && timeToCheck.matches(reg)) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
        Date inTime = parseDate(dateFormat, initialTime);
        Date finTime = parseDate(dateFormat, finalTime);
        Date checkedTime = parseDate(dateFormat, timeToCheck);

        if (finalTime.compareTo(initialTime) < 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(finTime);
            calendar.add(Calendar.DAY_OF_YEAR, 1);
            finTime = calendar.getTime();
            if (timeToCheck.compareTo(initialTime) < 0) {
                calendar.setTime(checkedTime);
                calendar.add(Calendar.DAY_OF_YEAR, 1);
                checkedTime = calendar.getTime();
            }
        }

        return (checkedTime.after(inTime) || checkedTime.compareTo(inTime) == 0) && checkedTime.before(finTime);
    } else {
        throw new IllegalArgumentException("Not a valid time, expecting HH:MM:SS format");
    }
}

/**
 * @param initialTime - in format HH:mm:ss
 * @param finalTime   - in format HH:mm:ss
 * @return initialTime <= now < finalTime
 * @throws IllegalArgumentException if passed date with wrong format
 */
public static boolean isNowBetweenTwoTime(String initialTime, String finalTime) throws IllegalArgumentException {
    return isTimeBetweenTwoTime(initialTime, finalTime,
            String.valueOf(DateFormat.format("HH:mm:ss", new Date()))
    );
}

private static Date parseDate(SimpleDateFormat dateFormat, String data) {
    try {
        return dateFormat.parse(data);
    } catch (ParseException e) {
        throw new IllegalArgumentException("Not a valid time");
    }
}
Taras Yurkiv
  • 126
  • 4
  • Please don’t teach the young ones to use the long outdated and notoriously troublesome `SimpleDateFormat` class. At least not as the first option. And not without any reservation. Today we have so much better in [`java.time`, the modern Java date and time API,](https://docs.oracle.com/javase/tutorial/datetime/) and its `DateTimeFormatter`. Also what is the point when for example the answer by BasilBourque obtains it in just 6 simple and short lines? – Ole V.V. May 01 '20 at 15:19
0

This worked for me:

fun timeBetweenInterval(
    openTime: String,
    closeTime: String
): Boolean {
    try {
        val dateFormat = SimpleDateFormat(TIME_FORMAT)
        val afterCalendar = Calendar.getInstance().apply {
            time = dateFormat.parse(openTime)
            add(Calendar.DATE, 1)
        }
        val beforeCalendar = Calendar.getInstance().apply {
            time = dateFormat.parse(closeTime)
            add(Calendar.DATE, 1)
        }

        val current = Calendar.getInstance().apply {
            val localTime = dateFormat.format(timeInMillis)
            time = dateFormat.parse(localTime)
            add(Calendar.DATE, 1)
        }
        return current.time.after(afterCalendar.time) && current.time.before(beforeCalendar.time)
    } catch (e: ParseException) {
        e.printStackTrace()
        return false
    }
}
Steffen Moritz
  • 7,277
  • 11
  • 36
  • 55
0

Based on Konstantin_Yovkov answer I would like to share my implementation which checks if current time will be in between given START and END time.

This implementation assumes that if given END time is 'before' the START time, then END must be meant to be tomorrow:

public static boolean currentTimeInBetween(String start, String end)
        throws ParseException {
    // start = "15:25";
    java.util.Date starttime = new SimpleDateFormat("HH:mm").parse(start);
    Calendar startcal = Calendar.getInstance();
    startcal.setTime(starttime);

    // end = "14:00";
    java.util.Date endtime = new SimpleDateFormat("HH:mm").parse(end);
    Calendar endcal = Calendar.getInstance();
    endcal.setTime(endtime);

    DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
    java.util.Date currenttime = dateFormat
            .parse(dateFormat.format(new java.util.Date()));
    Calendar currentcal = Calendar.getInstance();
    currentcal.setTime(currenttime);

    // If endTime < startTime, assume that endTime is 'tomorrow'
    if (startcal.after(endcal)) {
        endcal.add(Calendar.DATE, 1);
    }

    //            System.out.println("START" + " System Date: " + startcal.getTime());
    //            System.out.println("END" + " System Date: " + endcal.getTime());
    //            System.out.println("Current" + " System Date: " + currentcal.getTime());

    java.util.Date current = currentcal.getTime();
    if (current.after(startcal.getTime())
            && current.before(endcal.getTime())) {
        return true;
    } else {
        return false;
    }
}
Jokkeri
  • 1,001
  • 1
  • 13
  • 35
  • I am fine with the assumptions and even more so when they are explicit as here. Please don’t teach the young ones to use the long outdated and notoriously troublesome `SimpleDateFormat` class. At least not as the first option. And not without any reservation. We have so much better in [`java.time`, the modern Java date and time API,](https://docs.oracle.com/javase/tutorial/datetime/) and its `DateTimeFormatter`. – Ole V.V. Mar 08 '21 at 17:53
0

Solution function written in Kotlin

/**
  * @param currentTime : Time to compare
  * @param startTime: Start Hour in format like 10:00:00
  * @param endTime: End Hour in format like 15:45:00
  */
fun isTimeInBetweenHours(currentDate: Date, startTime: String, endTime: String): Boolean {
        val simpleDateFormat = SimpleDateFormat("HH:mm:ss", Locale.US)
        try {
            val startTimeCalendar = Calendar.getInstance()
            startTimeCalendar.time = simpleDateFormat.parse(startTime)
            startTimeCalendar.add(Calendar.DATE, 1)
            val endTimeCalendar = Calendar.getInstance()
            endTimeCalendar.time = simpleDateFormat.parse(endTime)
            endTimeCalendar.add(Calendar.DATE, 1)
            val currentTime = simpleDateFormat.format(currentDate) //"01:00:00"
            val currentTimeCalendar = Calendar.getInstance()
            currentTimeCalendar.time = simpleDateFormat.parse(currentTime)
            currentTimeCalendar.add(Calendar.DATE, 1)
            val x = currentTimeCalendar.time
            return x.after(startTimeCalendar.time) && x.before(endTimeCalendar.time)
        } catch (e: ParseException) {
            return false
        }
    }

The formatter only takes HH:mm:ss, so it's agnostic of date. All the dates are computed as 1st Jan 1970 being the epoch start date. Hence the comparison of time happens with only the time as the date for all the cases here is 1st Jan 1970.

Note: Used legacy Java API's instead of the newer ones (LocalTime and DateTimeFormatter) since these newer API's are not supported on older devices like Android below version Oreo. If you are using some other platform where you can get the updated API's, please use them as they are more optimised and less buggy.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Arnab Kar
  • 1,137
  • 1
  • 9
  • 22
  • I recommend you don’t use `Calendar` and `SimpleDateFormat`. Those classes are poorly designed and long outdated, the latter in particular notoriously troublesome. Instead use `LocalTime` and `DateTimeFormatter`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). Also I find your code even a little bit more confusing than it needed to be with `Calendar`. Some explanation might help that part. And I am not convinced that it honours the *regardless of date* part. – Ole V.V. Apr 22 '21 at 15:19
  • The formatter only takes HH:mm:ss, so it's agnostic of date. All the dates are computed as 1st Jan 1970 being the epoch start date. Hence the comparison of time happens with only the time as the date for all the cases here is 1st Jan 1970. – Arnab Kar Apr 22 '21 at 15:53
0

Kotlin code with no fancy library's, only minutes since midnight calculations.

    private fun isInBetween(
        startTime: String,
        endTime: String,
        currentTime: String
    ): Boolean {
        val startMinutesSinceMidnight = calculateMinutesSinceMidnight(startTime)
        val endMinutesSinceMidnight = calculateMinutesSinceMidnight(endTime)
        val currentMinutesSinceMidnight = calculateMinutesSinceMidnight(currentTime)
        if (startMinutesSinceMidnight < endMinutesSinceMidnight) {
            return (currentMinutesSinceMidnight >= startMinutesSinceMidnight) && (currentMinutesSinceMidnight < endMinutesSinceMidnight)
        } else {
            return !((currentMinutesSinceMidnight >= endMinutesSinceMidnight) && (currentMinutesSinceMidnight < startMinutesSinceMidnight))
        }
    }

    private fun calculateMinutesSinceMidnight(time_hh_mm: String): Int {
        val timeStrArray = time_hh_mm.split(":")
        var minutes = timeStrArray[1].toInt()
        minutes += 60 * timeStrArray[0].toInt()
        return minutes
    }
Jonas W
  • 498
  • 4
  • 4
-3

sorry for the sudo code..I'm on a phone. ;)

between = (time < string2 && time > string1);
if (string1 > string2)  between = !between;

if they are timestamps or strings this works. just change the variable names to match

rollstuhlfahrer
  • 3,988
  • 9
  • 25
  • 38
MollyCat
  • 485
  • 1
  • 6
  • 14