1

Tried with SimpleDateFormat and not getting results as expected below:

Mon, 11:00 am - 9:00 pm
Tue, 11:00 am - 9:00 pm
Wed, 11:00 am - 9:00 pm
Thu, 11:00 am - 9:00 pm
Fri, 11:00 am - 9:00 pm

Need to return true if the current time is in between any of these times.

Srikanth K
  • 190
  • 3
  • 12
  • Does it 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) – Arvind Kumar Avinash Jan 29 '21 at 11:13
  • Does it answer your question? [Check current time lies in two times in java](https://stackoverflow.com/questions/37956444/check-current-time-lies-in-two-times-in-java) – Arvind Kumar Avinash Jan 29 '21 at 11:14
  • Does it answer your question? [How to check if time in day is between two times?](https://stackoverflow.com/questions/29112299/how-to-check-if-time-in-day-is-between-two-times) or [How to know if now time is between two hours?](https://stackoverflow.com/questions/17212848/how-to-know-if-now-time-is-between-two-hours) – Arvind Kumar Avinash Jan 29 '21 at 11:15
  • Hi @LiveandLetLive thanks for your reference that solves half of the problem, and I am facing problems with converting "Mon-Thu 11:00 am - 10:00 pm" as two dates. could you please help me with this? – Srikanth K Jan 29 '21 at 11:16
  • Srikanth K - Edit your question to post what you have tried and where you are stuck at. Also, make your question clearer by adding some examples of valid time. – Arvind Kumar Avinash Jan 29 '21 at 11:18
  • @SrikanthK There is no such rule, tap on this [link](https://stackoverflow.com/posts/65953301/edit) to edit your question. – letsintegreat Jan 29 '21 at 11:23
  • @LiveandLetLive, Letsintegreat - I have updated the question hope it can help answer my question. – Srikanth K Jan 29 '21 at 11:38
  • 1
    I recommend you don’t use `SimpleDateFormat` and its fellow date-time classes from Java 1.0 and 1.1. Those classes are poorly designed and long outdated and `SimpleDateFormat` in particular notoriously troublesome. Instead use [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Jan 29 '21 at 16:18

3 Answers3

1

java.time

I recommend you do it using java.time which provides you with a rich set of API.

import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;

public class Main {
    public static void main(String[] args) {
        // Change the time-zone as per your requirement e.g. ZoneId.of("Europe/London")
        LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());

        LocalDateTime end = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.FRIDAY))
                                .withHour(21);
        
        boolean valid = false;
        for (LocalDateTime start = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); !start
                .isAfter(end); start = start.plusDays(1)) {
            if (!now.isBefore(start.withHour(11)) && !now.isAfter(start.withHour(21))) {
                valid = true;
                break;
            }
        }

        if (!valid) {
            System.out.println("Invalid");
        } else {
            System.out.println("Valid");
        }
    }
}

Output:

Valid

Learn about the modern date-time API from Trail: Date Time.

The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • is it really required to make code more complicated, when same thing can be done in 3-4 lines of code – mightyWOZ Jan 29 '21 at 12:09
  • @mightyWOZ - It would be great if you post a less complicated answer using modern date-time API. If you do not know modern date-time API, you should learn it instead of teaching someone to use the broken `java.util` date-time API. – Arvind Kumar Avinash Jan 29 '21 at 12:12
  • Question is tagged android, and I dont think you know Android doesnt run a full fledged JVM, java 8 and all the features that you suggest are inherently broken on android – mightyWOZ Jan 29 '21 at 12:16
  • 1
    @mightyWOZ - The last point in my answer has links to help you use Java 8 date-time API. – Arvind Kumar Avinash Jan 29 '21 at 12:17
  • Thank you very much, I will prefer native API's rather than some backport ripoff of the original thing, which is most likely going to break – mightyWOZ Jan 29 '21 at 12:20
  • 1
    @mightyWOZ - Did you check [Java 8+ APIs available through desugaring](https://developer.android.com/studio/write/java8-support-table)? – Arvind Kumar Avinash Jan 29 '21 at 12:35
  • 1
    *is most likely going to break*. Not so, don’t worry. According to most experience, using the old and poorly designed date and time classes will be more likely to break. – Ole V.V. Jan 29 '21 at 20:49
  • @LiveandLetLive - Thanks for the solution It worked! :) – Srikanth K Jan 31 '21 at 03:57
0

You can use the Calendar to get the day and time values, then simply perform check if the day and time lies in required range.

val cal = Calendar.getInstance()
val day = cal.get(Calendar.DAY_OF_WEEK)   // sunday 1.. saturday 7
val hour = cal.get(Calendar.HOUR_OF_DAY)  // Hour in 24 hours format

return (day in Calendar.MONDAY..Calendar.FRIDAY && hour in 11..21)
mightyWOZ
  • 7,946
  • 3
  • 29
  • 46
  • thanks for your answer. How can I convert "Mon-Thu 11:00 am - 10:00 pm" as two separate dates? then it will be easy to find the current time is in between these two dates or not. – Srikanth K Jan 29 '21 at 11:25
  • Can you please explain to me why my answer doesn't solve your problem? – mightyWOZ Jan 29 '21 at 12:06
  • I recommend you don’t use `Calendar`. That class is poorly designed and long outdated. Instead use classes from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Jan 29 '21 at 15:44
  • I dont think [google](https://developer.android.com/codelabs/android-training-menus-and-pickers#0) is aware of your opinion. – mightyWOZ Jan 29 '21 at 17:30
  • Are you suggesting that Google — exploiting Java — never read [Why do we need a new date and time library?](https://www.oracle.com/technical-resources/articles/java/jf14-date-time.html) I suggest that they have read it. – Ole V.V. Jan 29 '21 at 19:58
0

Assuming that you are reading your daily opening hours as strings from somewhere (which in a good design should not be necessary, but assuming that in your case it is), you first need a data structure for storing them. I suggest a Map. And I suggest a class like the following for the daily hours.

public class DailyHours {

    private static final DateTimeFormatter timeParser = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .appendPattern("h:mm a")
            .toFormatter(Locale.ENGLISH);
    
    private LocalTime opens;
    private LocalTime closes;
    
    public DailyHours(String times) {
        String[] hours = times.split(" - ");
        if (hours.length != 2) {
            throw new IllegalArgumentException("Improper format " + times + ", must be like 11:00 am - 9:00 pm");
        }
        opens = LocalTime.parse(hours[0], timeParser);
        closes = LocalTime.parse(hours[1], timeParser);
    }
    
    public boolean isBetween(LocalTime time) {
        return ! time.isBefore(opens) && time.isBefore(closes);
    }
}

Now we can read your strings into your map in this way:

    String[] openingHoursTable = {
            "Mon, 11:00 am - 9:00 pm",
            "Tue, 11:00 am - 9:00 pm",
            "Wed, 11:00 am - 9:00 pm",
            "Thu, 11:00 am - 9:00 pm",
            "Fri, 11:00 am - 9:00 pm"
    };
    
    Map<DayOfWeek, DailyHours> hoursPerDay = Arrays.stream(openingHoursTable)
            .map(s -> s.split(", "))
            .collect(Collectors.toMap(arr -> DayOfWeek.from(dayParser.parse(arr[0])), 
                    arr -> new DailyHours(arr[1])));

For this we need the following formatter:

private static final DateTimeFormatter dayParser = DateTimeFormatter.ofPattern("EEE", Locale.ENGLISH);

Once we have done this, we can check whether we are within the opening hours as often as we want:

    ZonedDateTime currentTime = ZonedDateTime.now(ZoneId.systemDefault());
    DailyHours todaysHours = hoursPerDay.get(currentTime.getDayOfWeek());
    if (todaysHours == null) {
        System.out.println("Closed today");
    } else {
        System.out.println("Open now? " + todaysHours.isBetween(currentTime.toLocalTime()));
    }

Running just now (Friday 5:40 PM in my time zone) I got:

Open now? true

Link: Oracle tutorial: Date Time explaining how to use java.time.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161