I am designing for banking application, where user is not allowed to login in particular time.
For example restricted time would be :-
Date : 2022-01-28 to 2022-05-28
Time : 1:00 AM to 4:00 AM
Day : Mon, Tue, Fri
Restricted duration would be configured in database and I need to do restriction check in Service/DAO layer using Java Code.
I found multiple answers for checking date and time but not for Day.
Can anyone provide consolidated answer for comparing all Date,Time and Day. Thanks for Help!!
CodePudding user response:
Here is one way. Use the DayOfWeek enum in the java.time package.
String[] days = {"Monday", "Tuesday", "Friday"};
LocalDate today = LocalDate.of(2022,1,25);
for (String d : days) {
System.out.println(DayOfWeek.valueOf(d.toUpperCase())
.equals(today.getDayOfWeek()));
}
prints
false
true
false
You could also do something like.
String allowed = "MON TUE FRI";
boolean result = allowed.contains(today.getDayOfWeek().name()
.substring(0,3));
System.out.println(result);
prints
true
CodePudding user response:
tl;dr
You said:
I found multiple answers for checking date and time but not for Day.
LocalDate.now().getDayOfWeek().equals( DayOfWeek.MONDAY ) // Is today Monday?
Time zone
You omitted a crucial element: time zone. I will ignore that if you are certain your software applies only locally to a single time zone. I do not recommend ignoring time zone, but I'll follow your lead on this one.
Record
Define a record to represent your restricted rules set.
record LoginForbidden (
LocalDate startDate , LocalDate endDate ,
LocalTime startTime , LocalTime endTime ,
Set< DayOfWeek > dows
) {}
Database
Retrieve the date and time objects using JDBC 4.2 or later.
LocalDate startDate = myResultSet.getObject( … , LocalDate.class ) ;
…
LocalTime startTime = myResultSet.getObject( … , LocalTime.class ) ;
…
For day-of-week, there is no SQL standard data type. So I suggest you store either 1-7 for Monday-Sunday per ISO 8601, or the all uppercase string name of each DayOfWeek enum object (MONDAY, TUESDAY, etc.). Retrieve as an int or String, respectively. Obtain a DayOfWeek object by calling DayOfWeek.values()[myOrdinalDowNumber-1] or DayOfWeek.valueOf( String ), respectively.
Current moment
Capture the current moment. Doing so requires a time zone. For any given moment, the date and time-of-day both vary around the globe by zone. If you omit the time zone, java.time uses the JVM’s current default time zone.
ZonedDateTime zdt = ZonedDateTime.now() ;
Extract the date portion.
LocalDate today = zdt.toLocalDate() ;
Search your collection of LoginForbidden objects (loginForbiddens) for the current date.
List< LoginForbidden > loginForbiddensForToday =
loginForbiddens
.stream()
.filter(
loginForbidden -> ( ! today.isBefore( startDate ) ) && today.isBefore( loginForbidden.endDate )
)
.toList()
;
We should find exactly one object, I presume. So verify.
if( loginForbiddensForToday.size() != 1 ) { throw new IllegalStateException( "Other than one LoginForbidden found for date: " today.toString() ) ; }
If valid, extract the one and only object.
LoginForbidden loginForbiddenForToday = loginForbiddens.get( 0 ) ;
Day of week
Proceed, comparing the day of week.
DayOfWeek dow = today.getDayOfWeek() ;
boolean dayForbidden = loginForbiddenForToday.dows().contains( dow ) ;
Time of day
If the day is forbidden, then move on to compare current time-of-day against the start and stop times.
LocalTime lt = zdt.toLocalTime() ;
boolean denyLogin = ( ! lt.isBefore( loginForbiddenForToday.startTime() ) ) && lt.isBefore( loginForbiddenForToday.endTime() ) ;
This is all rough-draft, untested code. But it should get you pointed in the right direction.
