posted by 구로공돌이 2025. 5. 19. 13:39

import java.time.*;
import java.time.temporal.ChronoUnit;

public class WorkTimeCalculator {

    private static final LocalTime WORK_START = LocalTime.of(8, 30);
    private static final LocalTime WORK_END = LocalTime.of(18, 0);
    private static final Duration DAILY_MAX = Duration.ofHours(8);
    private static final Duration MINIMUM_WORK_TIME = Duration.ofMinutes(6); // 예시 6분 기준

    public static Duration calculateWorkDuration(LocalDateTime start, LocalDateTime end) {
        if (end.isBefore(start)) return Duration.ZERO;

        Duration total = Duration.ZERO;
        LocalDate currentDate = start.toLocalDate();

        while (!currentDate.isAfter(end.toLocalDate())) {
            DayOfWeek day = currentDate.getDayOfWeek();
            if (day != DayOfWeek.SATURDAY && day != DayOfWeek.SUNDAY) {

                // 시작일
                if (currentDate.equals(start.toLocalDate())) {
                    if (currentDate.equals(end.toLocalDate())) {
                        // 시작일 == 종료일
                        LocalTime from = start.toLocalTime();
                        LocalTime to = end.toLocalTime().isAfter(WORK_END) ? WORK_END : end.toLocalTime();
                        if (!to.isAfter(WORK_START)) continue;
                        if (from.isBefore(WORK_START)) from = WORK_START;
                        if (to.isAfter(WORK_END)) to = WORK_END;
                        Duration duration = Duration.between(from, to);
                        total = total.plus(duration);
                    } else {
                        // 시작일만
                        Duration duration = Duration.between(start.toLocalTime(), WORK_END);
                        if (duration.isNegative()) continue;
                        total = total.plus(duration.compareTo(DAILY_MAX) > 0 ? DAILY_MAX : duration);
                    }
                }

                // 종료일
                else if (currentDate.equals(end.toLocalDate())) {
                    LocalTime from = WORK_START;
                    LocalTime to = end.toLocalTime().isAfter(WORK_END) ? WORK_END : end.toLocalTime();
                    if (!to.isAfter(from)) continue;
                    Duration duration = Duration.between(from, to);
                    total = total.plus(duration.compareTo(DAILY_MAX) > 0 ? DAILY_MAX : duration);
                }

                // 중간 평일
                else {
                    total = total.plus(DAILY_MAX);
                }
            }

            currentDate = currentDate.plusDays(1);
        }

        // 최소 시간 보정
        if (total.compareTo(MINIMUM_WORK_TIME) < 0) {
            total = MINIMUM_WORK_TIME;
        }

        return total;
    }

    // 테스트 예시
    public static void main(String[] args) {
        LocalDateTime start = LocalDateTime.of(2025, 5, 15, 7, 0);
        LocalDateTime end = LocalDateTime.of(2025, 5, 15, 10, 0);
        Duration result = calculateWorkDuration(start, end);
        System.out.println("작업시간 (분): " + result.toMinutes());
    }
}