Issue
I have trouble upgrading to a new java version even though it says success, but thats not important as i cant redo everything now.
I am creating a workday calendar and I have code that sets daily worktime from e.g 8:00-16:00 (workDayStartStop). And a code that given a start date and increment in days should print out the end date. Increment in workingdays could be e.g 1.5f (which means 8 + 4 hours working day) or 1.25f (8 + 2 working hours).
##Issues:
My code does not yet check for holidays and weekends
My code only prints the days and hours correctly (for future), but it needs to calculate minutes too.
My code needs to calculate backwards too if negative values are provided in days to increment.
public void setWorkdayStartAndStop(Calendar start, Calendar stop) { ZonedDateTime startZdt = ((GregorianCalendar) start).toZonedDateTime(); ZonedDateTime endZdt = ((GregorianCalendar) stop).toZonedDateTime(); long wholeDays = ChronoUnit.DAYS.between(startZdt, endZdt); startZdt = startZdt.plusDays(wholeDays); Duration workDay = Duration.between(startZdt, endZdt); this.workdayStartAndStop = (float) workDay.toMinutes() / (float) Duration.ofHours(1).toMinutes();
}
public LocalDateTime getWorkdayIncrement(LocalDateTime startDate, float incrementInWorkdays) {
Holidays holidays = new Holidays();
CalendarController cc = new CalendarController();
holidays.setHolidayIfIsSetToRecurring();
int days = (int) Math.abs(incrementInWorkdays);
float remaining = incrementInWorkdays - days;
float fHours = remaining * 24f;
int hours = (int) fHours;
remaining = fHours - hours;
float fMinutes = remaining * 60f;
int minutes = (int) fMinutes;
LocalDateTime mDateTime = null;
for (int i = 0; i <= days; i++) {
mDateTime = startDate.plusDays(i).plusHours(hours).plusMinutes(minutes);
LocalDate toLocalDate = mDateTime.toLocalDate();
//if the incremented day is a holiday, skip to nextday
if (cc.isHoliday(toLocalDate)) {
days += 1;
}
}
return mDateTime;
}
}
public static void main(String[] args) {
WorkdayCalendar workdayCalendar = new WorkdayCalendar();
workdayCalendar.setWorkdayStartAndStop(
LocalDateTime.of(2020, 1, 1, 8, 0),
LocalDateTime.of(2020, 1, 1, 16, 0));
workdayCalendar.setRecurringHoliday(
MonthDay.of(5, 17));
workdayCalendar.setHoliday(LocalDate.of(2020, 5, 27));
LocalDateTime start = LocalDateTime.of(2020, 5, 24, 8, 5);
String datePattern = "dd-MM-yyyy HH:mm";
DateTimeFormatter europeanDateFormatter = DateTimeFormatter.ofPattern(datePattern);
float increment = 1.5f;
System.out.println(
europeanDateFormatter.format(start) +
" with the addition of " +
increment +
" working days is " +
europeanDateFormatter.format(workdayCalendar.getWorkdayIncrement(start, increment)));
}
Output is:
24-05-2020 08:05 with the addition of 1.5 working days is 26-05-2020 20:05
starting 24th 8 o'clock in the morning it should end 25th 12 o'clock in the morning (8h + 4h) . 1 workday is only from 8-16, then it should skip to next day. it should only give results between 8-16 if startDate is set fra 08:00 and wokringhours is set to 8hours a day.
Solution
You are using outdated and broken date/time API which are confusing and error-prone. Use modern date/time API which are smart and intuitive:
import java.time.LocalDateTime;
import java.time.Month;
public class Main {
public static void main(String[] args) {
LocalDateTime ldt = LocalDateTime.of(2020, Month.JUNE, 18, 21, 50, 5);
System.out.println(ldt);
// After 2.75 days
System.out.println(getWorkdayIncrement(ldt, 2.75f));
}
public static LocalDateTime getWorkdayIncrement(LocalDateTime startDate, float incrementInWorkdays) {
int days = (int) incrementInWorkdays;
float remaining = incrementInWorkdays - days;
float fhours = remaining * 24f;
int hours = (int) fhours;
remaining = fhours - hours;
float fminutes = remaining * 60f;
int minutes = (int) fminutes;
return startDate.plusDays(days).plusHours(hours).plusMinutes(minutes);
}
}
Output:
2020-06-18T21:50:05
2020-06-21T15:50:05
[Update]
Given below is how you can get LocalDate
out of MonthDay
:
import java.time.LocalDate;
import java.time.Month;
import java.time.MonthDay;
public class Main {
public static void main(String[] args) {
// Month-day of June, 20
MonthDay monthDay = MonthDay.of(Month.JUNE, 20);
LocalDate date = monthDay.atYear(2020);
System.out.println(date);
// Month-day now
monthDay = MonthDay.now();
date = monthDay.atYear(2020);
System.out.println(date);
}
}
Output:
2020-06-20
2020-06-20
Answered By - Arvind Kumar Avinash