'How to calculate from a date to another date?

I am creating a workday calendar which calculates which date the workday ends. I have a code that sets daily worktime from e.g 8:00-16:00 (workDayStartStop). And a code when given a start date and increment in days should print out which 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:

  1. My code only prints the days and hours correctly, but it needs to calculate minutes too.

  2. 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 1:[1]

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1