0

I'm trying to determine if the current time e.g. 19:30:00 is between 19:00:00 & 03:00:00 next day, but my code is failing. my code fails with this condition can i use date to campare time if yes please let me know how

import java.util.Calendar;
import java.text.SimpleDateFormat;

public class DateUtils {

    // format 24hre ex. 12:12 , 17:15
    private static String  HOUR_FORMAT = "HH:mm";

    private DateUtils() {    }

    public static String getCurrentHour() {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdfHour = new SimpleDateFormat(HOUR_FORMAT);
        String hour = sdfHour.format(cal.getTime());
        return hour;
    }

    /**
     * @param  target  hour to check
     * @param  start   interval start
     * @param  end     interval end
     * @return true    true if the given hour is between
     */
    public static boolean isHourInInterval(String target, String start, String end) {
        return ((target.compareTo(start) >= 0)
                && (target.compareTo(end) <= 0));
    }

    /**
     * @param  start   interval start
     * @param  end     interval end
     * @return true    true if the current hour is between
     */
    public static boolean isNowInInterval(String start, String end) {
        return DateUtils.isHourInInterval
            (DateUtils.getCurrentHour(), start, end);
    }

    //    TEST
    public static void main (String[] args) {
      String now = DateUtils.getCurrentHour();
      String start = "14:00";
      String end   = "14:26";
      System. out.println(now + " between " + start + "-" + end + "?");
      System. out.println(DateUtils.isHourInInterval(now,start,end));
      /*
       * output example :
       *   21:01 between 14:00-14:26?
       *   false
       *
       */
    }
}
Jon Bates
  • 3,055
  • 2
  • 30
  • 48
Mitesh kambli
  • 25
  • 1
  • 6
  • Tidied up english and added language formatting to code snippet – Jon Bates Dec 04 '19 at 12:29
  • I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead just use `LocalTime` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Dec 04 '19 at 17:08
  • 1
    Does this answer your question? [Check if a given time lies between two times regardless of date](https://stackoverflow.com/questions/17697908/check-if-a-given-time-lies-between-two-times-regardless-of-date) – Shivam Puri Dec 04 '19 at 17:18
  • In the linked original question I in particular recommend [the answer by Basli Bourque](https://stackoverflow.com/a/39712175/5772882) demonstrating the use of java.time. – Ole V.V. Dec 04 '19 at 17:23
  • You shouldn’t send time strings around between methods in your program. When you get a time into your program as string, parse it into a `LocalTime` first thing and handle it as a `LocalTime` from that point. You don’t even need a formatter: `LocalTime.parse(start)` will do it (and throw an exception if the time string is invalid). Many tings will be simpler once you are using proper time objects rather than strings. – Ole V.V. Dec 04 '19 at 17:29

1 Answers1

1

java.time.LocalTime is your friend here. Below is a quick example, sure it can be done somewhat shorter.

void test(){
    var tz = ZoneId.of("CET");
    var anyDate = LocalDate.of(2019,12,4);

    var x = ZonedDateTime.of(LocalDateTime.of(anyDate, LocalTime.of(18,59)),tz).toInstant();

    System.out.println(testTime(Clock.fixed( ZonedDateTime.of(LocalDateTime.of(anyDate, LocalTime.of(18,59)),tz).toInstant(),tz)));
    System.out.println(testTime(Clock.fixed( ZonedDateTime.of(LocalDateTime.of(anyDate, LocalTime.of(19,01)),tz).toInstant(),tz)));
    System.out.println(testTime(Clock.fixed( ZonedDateTime.of(LocalDateTime.of(anyDate, LocalTime.of(00,00)),tz).toInstant(),tz)));
    System.out.println(testTime(Clock.fixed( ZonedDateTime.of(LocalDateTime.of(anyDate, LocalTime.of(02,59)),tz).toInstant(),tz)));
    System.out.println(testTime(Clock.fixed( ZonedDateTime.of(LocalDateTime.of(anyDate, LocalTime.of(03,01)),tz).toInstant(),tz)));
}

boolean testTime(Clock clock){
    var evening =LocalTime.of(19,00);
    var midnight =LocalTime.of(00,00);
    var night =LocalTime.of(03,00);

    LocalTime wallTime = LocalTime.now(clock);

    return (wallTime.isAfter(evening) && wallTime.isBefore(midnight.minusNanos(1))) ||  (midnight.isBefore(wallTime) && wallTime.isBefore(night)) || wallTime.equals(midnight);

}
David Lilljegren
  • 1,799
  • 16
  • 19
  • 1
    Agree that java.time is our friend here (and elsewhere). Don’t rely on three letter time zone abbreviations. Use `ZoneId.of("Asia/Kolkata")` or `ZoneId.of("Europe/Zurich")`. Always *region/city*. – Ole V.V. Dec 04 '19 at 15:04