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?

Solution 1

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();
}

Solution 2

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?

Solution 3

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])

Solution 4

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

Solution 5

 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.

Solution 6

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!

Solution 7

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;
 }

Solution 8

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
}

Solution 9

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);
        } 

}

Solution 10

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;
 } 

Solution 11

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();
}

Solution 12

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.

Solution 13

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;
}

Solution 14

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);

Solution 15

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
        }

Solution 16

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.

Solution 17

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");  
}    

Solution 18

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");
 }

Solution 19

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);
}

Solution 20

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

Solution 21

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;
    }
}

Solution 22

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;
}

Solution 23

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.

Solution 24

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!

Solution 25

/**
 * @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");
    }
}

Solution 26

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

Solution 27

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;
    }
}

Solution 28

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.

Solution 29

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
    }

Solution 30

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));
        }