Srikanth K
Srikanth K

Reputation: 190

Find current time is in between the time interval "Mon-Fri 11:00 am - 9:00 pm"

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.

Upvotes: 1

Views: 580

Answers (3)

Anonymous
Anonymous

Reputation: 86296

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.

Upvotes: 0

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79105

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.

Upvotes: 1

mightyWOZ
mightyWOZ

Reputation: 8335

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)

Upvotes: 0

Related Questions