使用Java 8计算两个日期之间的天数,同时忽略一周中的某些天 [英] Count days between two dates with Java 8 while ignoring certain days of week

查看:172
本文介绍了使用Java 8计算两个日期之间的天数,同时忽略一周中的某些天的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面我有3种方法。第一个很简单。它只计算总天数。但是,第二个不仅会计算天数,还会忽略传递给方法的星期几。

Below I have 3 methods. The first is very simple. It just counts the total number of days. The second, however, will not only count the days, but will ignore the days of the week that are passed in to the method.

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

My problem is that the third method is not always correct. It should match the second method. I am guessing it has something to do with leap years, because the difference is usually +=3|4 when it is incorrect.

我正在尝试模拟Excel的工作日(serial_number,[return_type] ])某种方式的公式。

I am attempting to mock Excel's weekday(serial_number,[return_type]) formula in a way.

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



示例



Example

  | 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,2,4,6},1)+$B$2-$B$1)/7)) | 2248 

此处有关于此功能的更多信息:如何计算/计算Excel中两个日期之间的天数?

There is more information on this function here: How to count / calculate the number of days between two dates in Excel?


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

  1. Simply count the number of days between two dates.

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


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

  • Count number of days, ignoring certain days of week, using a loop.

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


  • 计算天数。再次但没有循环。

  • Count number of days. again but without a loop.

    public static int bestDaysBetween(final LocalDate start,
            final LocalDate end, 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;
    }
    




  • 完整代码



    Full code

    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, 9, 7);
            final LocalDate end = LocalDate.of(2025, 6, 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, end, 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 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 LocalDate end, 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特性...

    If we talk about a Java 8 API, why not use the Java 8 features consequently…

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

    这篇关于使用Java 8计算两个日期之间的天数,同时忽略一周中的某些天的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆