views:

510

answers:

3

I am sure this was done 1000 times in 1000 different places. The question is I want to know if there is a better/standard/faster way to check if current "time" is between two time values given in hh:mm:ss format. For example, my big business logic should not run between 18:00:00 and 18:30:00. So here is what I had in mind:

 public static  boolean isCurrentTimeBetween(String starthhmmss, String endhhmmss) throws ParseException{
  DateFormat hhmmssFormat = new SimpleDateFormat("yyyyMMddhh:mm:ss");
  Date now = new Date();
  String yyyMMdd = hhmmssFormat.format(now).substring(0, 8);

  return(hhmmssFormat.parse(yyyMMdd+starthhmmss).before(now) &&
    hhmmssFormat.parse(yyyMMdd+endhhmmss).after(now));
 }

Example test case:

  String doNotRunBetween="18:00:00,18:30:00";//read from props file
  String[] hhmmss = downTime.split(",");
  if(isCurrentTimeBetween(hhmmss[0], hhmmss[1])){
   System.out.println("NOT OK TO RUN");
  }else{
   System.out.println("OK TO RUN");
  }

What I am looking for is code that is better

  • in performance
  • in looks
  • in correctness

What I am not looking for

  • third-party libraries
  • Exception handling debate
  • variable naming conventions
  • method modifier issues
+6  A: 

this is all you should need to do, this method is loosely coupled from the input and highly coherent.

boolean isNowBetweenDateTime(final Date s, final Date e)
{
    final Date now = new Date();
    return now.after(s) && now.before(e);
}

how you get the Date objects for start and end is irrelevant to comparing them. You are making things way more complicated than you need to with passing String representations around.

Here is a better way to get the start and end dates, again loosely coupled and highly coherent.

private Date dateFromHourMinSec(final String hhmmss)
{
    if (hhmmss.matches("^[0-2][0-3]:[0-5][0-9]:[0-5][0-9]$"))
    {
        final String[] hms = hhmmss.split(":");
        final GregorianCalendar gc = new GregorianCalendar();
        gc.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hms[0]));
        gc.set(Calendar.MINUTE, Integer.parseInt(hms[1]));
        gc.set(Calendar.SECOND, Integer.parseInt(hms[2]));
        gc.set(Calendar.MILLISECOND, 0);
        return gc.getTime();
    }
    else
    {
        throw new IllegalArgumentException(hhmmss + " is not a valid time, expecting HH:MM:SS format");
    }
}

Now you can make two well named method calls that will be pretty self documenting.

fuzzy lollipop
@fuzzy lollipopYou possibly overlooked at the fact that I am just getting time in format of "hh:mm:ss" as the input.That is why specifically named it "isCurrentTimeBetween"
ring bearer
how you get the data is irrelevant, it should all be normalized into a java.util.Date object so it can be leveraged.
fuzzy lollipop
Naming it a certain way doesn't make it not a bad design. Look up "loosely coupled" and "highly coherent".
fuzzy lollipop
@fuzzy lollipop, sounds good.
ring bearer
I think I'd rather use the OP's SimpleDateFormat() to parse the String; why reinvent the wheel? But separating parsing from "between" determination may be useful.
Michael Campbell
he is going around the world with a bunch of string manipulation to do what the Calendar class is designed to do, he is re-inventing the wheel not the other way around. Plus my way doesn't make all the client code deal with that ParseException which he ommits from his example code.
fuzzy lollipop