2

I am trying to create a method in Java that returns true if the current time of day is between a set interval (startTime and endTime).

The date is irrelevant. What is the best way to do this?

Here is my attempt it doesn't work:

public boolean isNowBetweenDateTime()
{
    final Date now = new Date();
    return now.after(startTime) && now.before(endTime);
}

What is the best way (in java) to check if time is within two Date objects, ignoring year, month day?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
CodePrimate
  • 6,646
  • 13
  • 48
  • 86

5 Answers5

3

Your code looks good. Just set the date of now, startTime and endTime to some hard coded value.

aioobe
  • 413,195
  • 112
  • 811
  • 826
  • One subtlety -- this may not work as expected, if now is 29th of February, which happens one time in 4 years. But it may be not a concern for OP. – Victor Sorokin May 02 '12 at 10:34
  • I meant that OP may not realize that some times occur rarely, as 29th of Feb, so it's not very sensible to ask if they are between two arbitrary dates. Another example would be leap second (http://en.wikipedia.org/wiki/File:Leapsecond.png), which , admittedly, happens even more rarely. – Victor Sorokin May 02 '12 at 10:48
  • He wants to *ignore* the date, so I don't see how the date 29th of Feb is problematic. – aioobe May 02 '12 at 12:08
2

tl;dr

Interval.of( start.toInstant() , stop.toInstant() ).contains( Instant.now() )

Half-Open

In date-time handling, the Half-Open approach is commonly used for defining a span of time. The beginning is inclusive while the ending is exclusive. So a week is defined as starting at the first moment of a Monday and running up to, but not including, the first moment of the following Monday. We sometimes use this Half-Open approach intuitively, where a lunch period of 12 to 1 means start at the stroke of noon but be back at your job or class before the clock strikes 1 PM. Using Half-Open consistently throughout your date-time work will make the logic and programming cleaner, clearer, and simpler.

So your logic should be, “Is now not before beginning AND now is before ending”. Notice that “not before” is a compact way of saying “is equal to OR is after”.

boolean isNowBetweenDateTime = ( ! now.before(startTime) ) && now.before(endTime) ; // Not before start AND is before stop.

ZonedDateTime

The Question and other Answers use troublesome old legacy date-time classes now supplanted by the java.time classes.

The ZonedDateTime class represents a moment on the timeline with an assigned time zone.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( z );
ZonedDateTime start = now.minusWeeks( 1 );  // Simulating input.
ZonedDateTime stop = now.plusWeeks( 2 );  // Simulating input.

You could write the logic yourself to test if now is between.

Boolean isBetween = ( ! now.isBefore( start ) ) && stop.isBefore( stop );

Interval

If doing more of this kind of work, look at the ThreeTen-Extra project. This library extends the java.time classes with additional functionality. Specifically the Interval class will be helpful, representing a pair of moments on the timeline. Implements a variety of comparison methods such as contains, encloses, abuts, and overlaps.

Instantiate a Interval with a pair of Instant objects. Instant represents a moment on the timeline in UTC. We can extract an Instant object from each ZonedDateTime object.

Interval interval = Interval.of( start.toInstant() , stop.toInstant() );
Boolean isBetween = interval.contains( now.toInstant() );  // Or pass `Instant.now()`.

You can also get the current moment as an Instant with a call to Instant.now().

About java.time

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

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

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

Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use…).

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

First of all, I would recommend to use Calendar instead of Date. I had some problems before, using date. And I would use the time in milliseconds to compare dates, this is the safest way. The code wuoul be sth like:

Date now = new Date();

long startTimeInMillis = startTime.getTime();
long endTimeInMillis = endTime.getTime();
return now.getTime >= startTimeInMillis && now.getTime < endTimeInMillis;
Finuka
  • 730
  • 7
  • 15
  • 1
    the `before` and `after` methods in `java.util.Date` compare milliseconds, so you don't need to do this. – dogbane May 02 '12 at 10:47
  • ...besides `getTime` returns the number of milliseconds since 1970, so the problem of dates remain. – aioobe May 02 '12 at 10:50
  • I'm a bit confused. You recomment using Calendar but in your code you're still using Date. Is there a difference when using Calendar instead of Date? – CodePrimate May 02 '12 at 11:05
  • well, in the code i was trying to explain how i would do that using dates. I recommend Calendar because it handles itself more things like leap years, etc. – Finuka May 02 '12 at 13:06
0

If you want to ignore the Date and only consider the time of day, consider using Joda-Time's LocalTime, which is designed specifically to hold only the time portion.

Here is an example:

java.util.Date startTime = ... ;
java.util.Date endTime = ... ;

public boolean isNowBetweenDateTime()
{
    // get current time
    final LocalTime now = new LocalTime();

    // convert the java.util.Dates to LocalTimes and then compare
    return now.isAfter(LocalTime.fromDateFields(startTime)) &&
           now.isBefore(LocalTime.fromDateFields(endTime));
}
dogbane
  • 266,786
  • 75
  • 396
  • 414
0

This java function returns true if the current time is between two other times. It ignores the year/month/day.

import java.text.*;
import java.util.Date;

public static boolean isNowBetweenHours() throws ParseException
{
    String leftBoundaryHours = "01:00:00";   //01:00 hours, military time.(1AM)
    String rightBoundaryHours = "14:00:00";  //14:00 hours, military time.(2PM)

    //returns true if current time is between 
    //leftBoundaryHours and rightBoundaryHours.

    //This formatter converts a bare string to a date.
    DateFormat formatter = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");

    //add the hand specified time to 1970-01-01 to create left/right boundaries.
    Date leftTimeBoundary = formatter.parse("1970-01-01 " + leftBoundaryHours);
    Date rightTimeBoundary = formatter.parse("1970-01-01 " + rightBoundaryHours);

    //extract only the hours, minutes and seconds from the current Date.
    DateFormat extract_time_formatter = new SimpleDateFormat("HH:mm:ss");

    //Get the current time, put that into a string, add the 1970-01-01, 
    Date now = formatter.parse("1970-01-01 " + 
        extract_time_formatter.format(new Date()));

    //So it is easy now, with the year, month and day forced as 1970-01-01
    //all you do is make sure now is after left, and now is before right.
    if (now.after(leftTimeBoundary) && now.before(rightTimeBoundary))
        return true;
    else
        return false;
}

Invoke the function like this:

try {
    System.out.println(isNowBetweenHours());
} catch (ParseException e) {

}

If the current time is after 01:00 hours but before 14:00 hours, it returns true. Else it returns false.

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335