Reputation: 190
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
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
Reputation: 79105
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
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