Calculate business days in java without saturdays, sunday and public holiday - java

i have a table in oracle where I saved the twelve public days in Mexico and I need to calculate a limit day since you registered
public Date calcularFechaLimite() {
try {
DiaFestivoDTO dia = new DiaFestivoDTO();
// Calendar fechaActual = Calendar.getInstance();
Calendar fechaL = Calendar.getInstance();
fechaL.add(Calendar.DATE, 3);
switch (fechaL.get(Calendar.DAY_OF_WEEK)) {
case Calendar.SATURDAY:
fechaL.add(Calendar.DATE, 2);
break;
case Calendar.SUNDAY:
fechaL.add(Calendar.DATE, 2);
break;
case Calendar.MONDAY:
fechaL.add(Calendar.DATE, 2);
break;
case Calendar.TUESDAY:
fechaL.add(Calendar.DATE, 1);
default:
break;
}
dia.setFechaLimite(fechaL.getTime());
Integer numeroDiasFest = seleccionPagoBO.obtenerDiasFestivos(dia);
if (numeroDiasFest != 0) {
fechaL.add(Calendar.DATE, numeroDiasFest);
dia.setFechaLimite(fechaL.getTime());
}
fechaLimite = fechaL.getTime();
} catch (Exception e) {
e.printStackTrace();
}
return fechaLimite;
}
This is what i have but March 28 and 29 are public days and it is not working, any idea??

Several issues:
You are not checking if the first 3 days you skip contain weekend days.
Also you are skipping strange amounts of days and skipping for weekdays as well (which are business days and therefore should not be skipped).
I assume the method DiaFestivoDTO.obtenerDiasFestivos() calculates the number of national holidays in a certain date range but what is the start date? Is it initialized to the current date when DiaFestivoDTO is created?
When there is a national holiday in your date range you increase the date range but never check if this new daterange includes new national holidays or weekend days.
If what you are trying to do is calculate a date '3 business days from now' here's roughly what I would do:
// get all the holidays as java.util.Date
DiaFestivoDTO dia = new DiaFestivoDTO();
List<Date> holidays = dia.getAllNationalHolidays();
// get the current date without the hours, minutes, seconds and millis
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
// iterate over the dates from now and check if each day is a business day
int businessDayCounter = 0
while (businessDayCounter < 3) {
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
if (dayOfWeek != Calendar.SATURDAY && dayOfWeek != Calendar.SUNDAY && !holidays.contains(cal.getTime())) {
businessDayCounter++;
}
cal.add(Calendar.DAY_OF_YEAR, 1);
}
Date threeBusinessDaysFromNow = cal.getTime();
For this to work I would advise you to add a new method 'getAllNationalHolidays' to list al the holidays because it is more efficient to store twelve dates in memory than to access the database multiple times to check for them.
If you cannot change/add database methods then you could do this
while (businessDayCounter < 3) {
// determine if this day is a holiday
DiaFestivoDTO dia = new DiaFestivoDTO();
dia.setFechaInitial(cal.getTime());
dia.setFechaLimite(cal.getTime());
boolean isHoliday = seleccionPagoBO.obtenerDiasFestivos(dia) > 0;
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
if (dayOfWeek != Calendar.SATURDAY && dayOfWeek != Calendar.SUNDAY && !isHoliday) {
businessDayCounter++;
}
cal.add(Calendar.DAY_OF_YEAR, 1);
}
Here I assumed you can set the 'from' date in your DiaFestivoDTO using 'setFechaInitial' or something like that. But in this way you would be calling the database at least three times which is inefficient.

Related

Check current time against specific times in Java and Android Studio

I want to set a boolean value isBasePriceTime to false if the current time is equal to 6pm or after 6pm and is not between midnight and 6am the next day. However it keeps setting the isBasePriceTime to false if the current time of the day is for example 2pm.
private boolean checkCurrentTimePriceType()
{
/*Get the current price type depending on the time of the day the user wants to
get a cab */
Calendar today = Calendar.getInstance();
Date currentDate = today.getTime();
//creates a time for 6pm
String nightPriceFullTime = "18:00:00";
Date nightPriceTime = java.sql.Time.valueOf(nightPriceFullTime);
Calendar nightPriceDateCalendar = Calendar.getInstance();
nightPriceDateCalendar.setTime(nightPriceTime);
//creates a time for midnight
String nightPriceFullTimeMidnight = "00:00:00";
Date nightPriceTimeMidnight = java.sql.Time.valueOf(nightPriceFullTimeMidnight);
Calendar nightPriceMidnightDateCalendar = Calendar.getInstance();
nightPriceMidnightDateCalendar.setTime(nightPriceTimeMidnight);
//creates a time for 6am
String basePriceFullTime = "06:00:00";
Date basePriceTime = java.sql.Time.valueOf(basePriceFullTime);
Calendar basePriceDateCalendar = Calendar.getInstance();
basePriceDateCalendar.setTime(basePriceTime);
boolean isBasePriceTime;
//checks if the current time is or after 6pm, or if the the current time is between midnight and 6am
if(((today.getTime().after(nightPriceDateCalendar.getTime())) || (today.getTime().equals(nightPriceDateCalendar.getTime())))
|| ((today.getTime().before(basePriceDateCalendar.getTime())) && (today.getTime().after(nightPriceMidnightDateCalendar.getTime()))))
{
//user will pay a night time price
isBasePriceTime = false;
}
else
{
//user will pay a base time price
isBasePriceTime = true;
}
//return value of isNightPrice boolean variable
return isBasePriceTime;
}
Maybe this simplification will work for you:
int currentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); //Current hour
return currentHour < 18 //False if after 6pm
Using Jodatime:
LocalTime time = new LocalTime(/* Optional but recommended: specify timezone */);
return time.isAfter(LocalTime.of(18, 0))
|| time.isBefore(LocalTime.of(6, 0));
Using Java 8:
LocalTime time = LocalTime.now(/* Optional but recommended: specify timezone */);
return time.isAfter(LocalTime.of(18, 0))
|| time.isBefore(LocalTime.of(6, 0));
(Note that the class names are the same, but they are from different packages).
java.sql.Time.valueOf(nightPriceFullTime) will return January 1, 1970 18:00:00. You should use some other way to convert the Strings into dates. If you want to keep using this conversion method, you will have to change how you compare the time of the different calendars. For example:
if(nightPriceDateCalendar.get(Calendar.HOUR_OF_DAY) > today.get(Calendar.HOUR_OF_DAY) && ...){...}
Another approach will be this:
String time = "18:00:00";
SimpleDateFormat sdf = SimpleDateFormat("yyyy/MM/dd");
String onlyDate = sdf.format(new Date());
sdf = SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date dateAndTime = sdf.parse(onlyDate+" "+time);
Calendar nightPriceDateCalendar = Calendar.getInstance();
nightPriceDateCalendar.setTime(dateAndTime);

How to check if the date belongs to current week or not? [duplicate]

This question already has answers here:
Get the week start and end date given a current date and week start
(4 answers)
Closed 8 years ago.
I have the date and time stored in preferences as Long:
// put
SharedPreferences settings =
PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
settings.edit().putLong("pref_datetime", System.currentTimeMillis()).commit();
// get
Date date2 = new Date(settings.getLong("pref_datetime", 0));
Once date is extracted, how could I check if it belongs to the current week (starting on Monday) or not?
You can use a Calendar instance to create this Monday and next Monday Date instances based on the current date then check that your date lies between them.
Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek(Calendar.MONDAY);
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
Date monday = c.getTime();
Date nextMonday= new Date(monday.getTime()+7*24*60*60*1000);
boolean isThisWeek = date2.after(monday) && date2.before(nextMonday);
You can construct a Calendar, and use getField(int) to get both the Calendar.YEAR and the Calendar.WEEK_OF_YEAR. When those are the same, the two Dates are from the same week.
When constructing the Calendar, also call setFirstDayOfWeek(Calendar.MONDAY) to make sure the weeks start on Monday (if you don't, it depends on the current locale).
After #SiKelly's objection that this won't work reliably in the end of December, beginning of January:
Compare WEEK_OF_YEAR.
If not equal, it is a different week.
If equal, it could be the wrong year, but that is hard to check. So just also check that the difference in getTime() is less than 8 * 24 * 60 * 60 * 1000 (eight days to be on the safe side).
(you could do step 3 first. then you avoid having to construct the calendar at all in many cases).
You can use Calendar to calculate week number for today and your date also,then simpy try to match it,
// put
SharedPreferences settings =
PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
settings.edit().putLong("pref_datetime", System.currentTimeMillis()).commit();
// get
Date date2 = new Date(settings.getLong("pref_datetime", 0));
Calendar calendar = Calendar.getInstance();
calendar.setFirstDayOfWeek(Calendar.MONDAY);
int current_year = calendar.get(Calendar.YEAR);
int current_week_number = calendar.get(Calendar.WEEK_OF_YEAR);
calendar.setTime(date2);
int year = calendar.get(Calendar.YEAR);
int week_number= calendar.get(Calendar.WEEK_OF_YEAR);
if(current_year==year && current_week_number==week_number)
{
//same
}
else
{
//different
}
try this
private boolean is_ThisWeek(Date date2){
Date now =new Date(System.currentTimeMillis());
int diffInDays = (int)( (now.getTime() - date2.getTime())
/ (1000 * 60 * 60 * 24) );
Calendar calendar = Calendar.getInstance();
calendar.setTime(now);
int reslut = calendar.get(Calendar.DAY_OF_WEEK);
int days_before = get_days_before(reslut);
if (diffInDays<days_before) {
Toast.makeText(this, "this week", Toast.LENGTH_SHORT).show();
return true;
}else {
Toast.makeText(this,"not this week", Toast.LENGTH_SHORT).show();
return false;
}
}
int get_days_before(int reslut){
int days_before = 0;
switch (reslut) {
case Calendar.MONDAY:
days_before=1;
break;
case Calendar.TUESDAY:
days_before=2;
break;
case Calendar.WEDNESDAY:
days_before=3;
break;
case Calendar.THURSDAY:
days_before=4;
break;
case Calendar.FRIDAY:
days_before=5;
break;
case Calendar.SATURDAY:
days_before=6;
break;
case Calendar.SUNDAY:
days_before=7;
break;
}
return days_before;
}

Comparing if 2 dates are the same day Java

Good day, quick question, Am trying to compare if 2 dates are the same day for the same time zone (city)Anyone have any idea why the following code holds and the other doesn't, can't seem to understand why.
SimpleDateFormat fmt = new SimpleDateFormat("EEE dd,MMM");
Date newparsetemp = fmt.parse(parsedate);
Date currentdateparse = fmt.parse(currentdate);
if(currentdateparse.equals(newparsetemp)){
//code executes
}
but if i do use this, the if condition doesn't hold
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
Date newparsetemp = fmt.parse(parsedate);
Date currentdateparse = fmt.parse(currentdate);
if(currentdateparse.equals(newparsetemp)){
//does not
}
Consider using Joda-Time's LocalDate.
Date data1 = ...
Date date2 = ...
new LocalDate(date1).equals(new LocalDate(date2))
Better yet just skip Date and use LocalDate instead.
Comparing after formatting to a string is an odd thing to do. Try this instead:
Calendar cal = GregorianCalendar.getInstance();
cal.setTime(parsedate);
Calendar cal2 = GregorianCalendar.getInstance();
cal2.setTime(currentdate);
cal2.set(Calendar.HOUR, 0);
cal2.set(Calendar.MINUTE, 0);
cal2.set(Calendar.SECOND, 0);
cal2.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
System.out.println(cal.equals(cal2) ? "true" : "false");
Your comment about timezones needs clarification. Did you mean to say
compare if 2 dates are the same day for different time zones?
If you mean "comparing only the day of week", have you tried comparing the result of Calendar.get(Calendar.DAY_OF_WEEK) instead?
do you agree that there is a chance that two different dates from different years, in the same month and day, can match the same day of the week?
and that there's no chance of two different dates match the same day, month and year?
I've actually done this not too long ago in one of my Android apps,
public boolean isSameDay(Event otherEvent) {
if(otherEvent == null) return false;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
try {
Calendar otherEventDate = Calendar.getInstance();
otherEventDate.setTime(format.parse(otherEvent.getStartTime()));
Calendar thisEventDate = Calendar.getInstance();
thisEventDate.setTime(format.parse(getStartTime()));
return (otherEventDate.get(Calendar.DAY_OF_MONTH) == thisEventDate.get(Calendar.DAY_OF_MONTH) &&
otherEventDate.get(Calendar.DAY_OF_YEAR) == thisEventDate.get(Calendar.DAY_OF_YEAR));
} catch(ParseException e) {
System.out.println(e.toString());
e.printStackTrace();
}
return false;
}
Here's the code as I did it, I'm just checking if the two events are occurring the same day. If you wish to add some more precision you'll just have to add this for yourself.

Get Last Quater Last date from Java date/Calender

I want to get the last quater's last date from Java Date/Calender classes.
For example :
If current date = 3rd Oct
Lat Quater Last Date : 30th Sept.
I am able to get the same using date.getMonth() methods, but since these methods are depricated, wondering if any better way to achive the same.
for date manipulation you should use Calendar. This may not be the most efficient way, but it works for your problem:
public Date calculateLastDayOfLastQuarter(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
int year = calendar.get(Calendar.YEAR);
try {
switch (calendar.get(Calendar.MONTH)) {
case Calendar.JANUARY:
case Calendar.FEBRUARY:
case Calendar.MARCH:
return sdf.parse("31.12." + (year - 1));
case Calendar.APRIL:
case Calendar.MAY:
case Calendar.JUNE:
return sdf.parse("31.03." + year);
case Calendar.JULY:
case Calendar.AUGUST:
case Calendar.SEPTEMBER:
return sdf.parse("30.06." + year);
case Calendar.OCTOBER:
case Calendar.NOVEMBER:
case Calendar.DECEMBER:
return sdf.parse("30.09." + year);
default:
return null;
}
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}

Checking time interval in java

I want some Java code that will tell me when school is open based on the current time.
When I call this method between 9AM and 6PM it should return "school is open", otherwise it should return "school is closed" after 6 pm and before 9 am.
public Calendar shopStartTime(String msg)
{
Calendar currentTime = Calendar.getInstance();
Calendar schoolTime = Calendar.getInstance();
Calendar schoolClosedTime = Calendar.getInstance();
schoolTime.set(Calendar.HOUR_OF_DAY, 9);
schoolTime.set(Calendar.MINUTE, 0);
schoolTime.set(Calendar.SECOND, 0);
schoolTime.set(Calendar.MILLISECOND, 0);
schoolClosedTime.set(Calendar.HOUR_OF_DAY, 18);
schoolClosedTime.set(Calendar.MINUTE, 0);
schoolClosedTime.set(Calendar.SECOND, 0);
schoolClosedTime.set(Calendar.MILLISECOND, 0);
if (schoolTime.compareTo(currentTime) <= 0 &&
(currentTime.compareTo(schoolClosedTime)>=0))
{
// check for time
Toast.makeText(getSherlockActivity(), "school is closed ",
Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getSherlockActivity(), " school is open",
Toast.LENGTH_SHORT).show();
}
return currentTime;
}
But the code is not working because it always returns the same result. How do I test if one time is between two other time of days?
Read the javadocs!
if (currentTime.after(schoolTime) && currentTime.before(schoolClosedTime)) {
// school is open
} else {
// school is closed
}
check if hour <9 && hour >18:
(or something else)
Calendar currentTime = Calendar.getInstance();
int hour = currentTime.get(Calendar.HOUR_OF_DAY);
you only need ONE calendar
Apart from Calendar that you have used , another simple approach would be :
private boolean inRange(Date now) throws ParseException {
final Date start = new SimpleDateFormat("HH.mm.ss").parse("09.00.00");
final Date end = new SimpleDateFormat("HH.mm.ss").parse("18.00.00");
return now.after(start)&& now.before(end);
}
You can use before() and after() of Calendar as well .

Categories