Как рассчитать дату окончания с учетом только даты начала (календаря) и количества дней для увеличения с использованием java версии 1.8? - PullRequest
1 голос
/ 18 июня 2020
• 1000 рабочее время, например, с 8: 00-16: 00 (workDayStartStop). А код, который задает дату начала и приращение в днях, должен распечатать дату окончания. Увеличение рабочих дней может составлять, например, 1,5f (что означает 8 + 4 часа рабочего дня) или 1,25f (8 + 2 рабочих часа).

## Проблемы:

  1. Мой код еще не проверяет праздничные и выходные дни

  2. Мой код правильно печатает только дни и часы (на будущее), но он также должен рассчитывать минуты.

  3. Мой код тоже должен рассчитывать в обратном направлении, если в днях указаны отрицательные значения для увеличения.

    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)));
}

Вывод:

24-05-2020 08:05 с добавлением 1,5 рабочих дней 26-05-2020 20: 05

начиная с 24-го в 8 часов утра он должен заканчиваться 25-го в 12 часов утра (8ч + 4ч). 1 рабочий день только с 8 до 16, затем он должен перейти на следующий день. он должен давать результаты только между 8 и 16, если startDate установлен на 08:00, а wokringhours установлен на 8 часов в день.

1 Ответ

3 голосов
/ 18 июня 2020

Вы используете устаревший и неработающий API даты / времени, который сбивает с толку и подвержен ошибкам. Используйте современный API даты и времени , которые умны и интуитивно понятны:

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);
    }
}

Вывод:

2020-06-18T21:50:05
2020-06-21T15:50:05

[Обновить]

Ниже показано, как получить LocalDate из 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);
    }
}

Вывод:

2020-06-20
2020-06-20
...