加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

使用Java 8计算两个日期之间的天数,同时忽略一周中的某些天

发布时间:2020-12-14 23:22:53 所属栏目:Java 来源:网络整理
导读:下面我有3种方法.第一个很简单.它只计算总天数.但是,第二个不仅会计算天数,还会忽略传递给方法的星期几. 我的问题是第三种方法并不总是正确的.它应该匹配第二种方法.我猜它与闰年有关,因为当它不正确时,差异通常是= 3 | 4. 附加信息 我试图以某种方式模拟Exc
下面我有3种方法.第一个很简单.它只计算总天数.但是,第二个不仅会计算天数,还会忽略传递给方法的星期几.

我的问题是第三种方法并不总是正确的.它应该匹配第二种方法.我猜它与闰年有关,因为当它不正确时,差异通常是= 3 | 4.

附加信息

我试图以某种方式模拟Excel的工作日(serial_number,[return_type])公式.

serial_number = startDate:Date - daysOfWeekToInclude:Array<Integer>

| A       | B                                                  | C
  +---------+----------------------------------------------------+-----------
1 | Start   | =DATE(2014,9,7)                                    | 9/7/2014                 
2 | End     | =DATE(2025,6,13)                                   | 6/13/2025                    
3 | Include | ={1,2,4,6} (Mon,Tue,Thu,& Sat)                  | <Disp Only>
4 | Days    | =SUM(INT((WEEKDAY($B$1-{1,6},1)+$B$2-$B$1)/7)) | 2248

这里有关于此功能的更多信息:How to count / calculate the number of days between two dates in Excel?

原始图像

方法

>只需计算两个日期之间的天数.

public static int simpleDaysBetween(final LocalDate start,final LocalDate end) {
    return (int) ChronoUnit.DAYS.between(start,end);
}

>使用循环计算天数,忽略一周中的某些天.

public static int betterDaysBetween(final LocalDate start,final LocalDate end,final List<DayOfWeek> ignore) {
    int count = 0;
    LocalDate curr = start.plusDays(0);

    while (curr.isBefore(end)) {
        if (!ignore.contains(curr.getDayOfWeek())) {
            count++;
        }
        curr = curr.plusDays(1); // Increment by a day.
    }

    return count;
}

>计算天数.再次,但没有循环.

public static int bestDaysBetween(final LocalDate start,final List<DayOfWeek> ignore) {
    int days = simpleDaysBetween(start,end);

    if (days == 0) {
        return 0;
    }

    if (!ignore.isEmpty()) {
        int weeks = days / 7;
        int startDay = start.getDayOfWeek().getValue();
        int endDay = end.getDayOfWeek().getValue();
        int diff = weeks * ignore.size();

        for (DayOfWeek day : ignore) {
            int currDay = day.getValue();
            if (startDay <= currDay) {
                diff++;
            }
            if (endDay > currDay) {
                diff++;
            }
        }

        if (endDay > startDay) {
            diff -= endDay - startDay;
        }

        return days - diff;
    }

    return days;
}

完整代码

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.List;

public class DayCounter {
    public static void main(String[] args) {
        final LocalDate start = LocalDate.of(2014,7);
        final LocalDate end = LocalDate.of(2025,13);
        List<DayOfWeek> ignore = Arrays.asList(DayOfWeek.SUNDAY,DayOfWeek.WEDNESDAY,DayOfWeek.FRIDAY);

        print(start);
        print(end);

        System.out.println(simpleDaysBetween(start,end));
        System.out.println(betterDaysBetween(start,end,ignore));
        System.out.println(bestDaysBetween(start,ignore));
    }

    public static void print(LocalDate date) {
        System.out.printf("%s -> %s%n",date,date.getDayOfWeek());
    }

    public static int simpleDaysBetween(final LocalDate start,final LocalDate end) {
        return (int) ChronoUnit.DAYS.between(start,end);
    }

    public static int betterDaysBetween(final LocalDate start,final List<DayOfWeek> ignore) {
        int count = 0;
        LocalDate curr = start.plusDays(0);

        while (curr.isBefore(end)) {
            if (!ignore.contains(curr.getDayOfWeek())) {
                count++;
            }
            curr = curr.plusDays(1); // Increment by a day.
        }

        return count;
    }

    public static int bestDaysBetween(final LocalDate start,final List<DayOfWeek> ignore) {
        int days = simpleDaysBetween(start,end);

        if (days == 0) {
            return 0;
        }

        if (!ignore.isEmpty()) {
            int weeks = days / 7;
            int startDay = start.getDayOfWeek().getValue();
            int endDay = end.getDayOfWeek().getValue();
            int diff = weeks * ignore.size();

            for (DayOfWeek day : ignore) {
                int currDay = day.getValue();
                if (startDay <= currDay) {
                    diff++;
                }
                if (endDay > currDay) {
                    diff++;
                }
            }

            if (endDay > startDay) {
                diff -= endDay - startDay;
            }

            return days - diff;
        }

        return days;
    }
}

解决方法

如果我们谈论Java 8 API,为什么不使用Java 8功能…
static long daysBetween(LocalDate start,LocalDate end,List<DayOfWeek> ignore) {
    return Stream.iterate(start,d->d.plusDays(1))
                 .limit(start.until(end,ChronoUnit.DAYS))
                 .filter(d->!ignore.contains(d.getDayOfWeek()))
                 .count();
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读