【问题标题】:How to find first business day of month in Java?如何在Java中找到每月的第一个工作日?
【发布时间】:2021-11-04 06:30:22
【问题描述】:

假设我有当天、第二天和前一天。我想写一个方法,通过对它们进行逻辑运算来找到每月的第一个工作日。比如 2021 年 11 月的第一个工作日从 4 号开始,因为 3 号因为节假日没有工作日。简而言之,我们需要编写一个程序,将非工作日考虑在内,找出每个月的第一个工作日。

【问题讨论】:

  • 第一个工作日是什么意思?比如非节假日?包括公共假期?你有没有尝试过?
  • 例如,我想写一个程序,找到每个月的第一个工作日。假设 11 月的第一个工作日从 3 点开始,因为第 1 天和第 2 天不是工作日,所以 3 重合。
  • 我猜你需要一个假期的 api
  • 你怎么知道什么是工作日,什么不是?按星期几?例如,一些国家/地区从星期日开始工作(例如美国),一些国家/地区从星期一开始工作(俄罗斯),一些国家从不在星期六工作(以色列)...根据您所在国家/地区特定的假期列表?
  • 我猜在 java 语言中没有内部方法来判断一个月中的哪一天是第一天。这取决于国家和年份 - 受法律监管 - 因此即使作为 Locale 的一部分将其放入 java 本身也是没有意义的。它在俄罗斯被称为“производственный календарь” - 工厂日历(在俄罗斯,我们在 Consultant Plus 中查看此日历)。您需要使用一些第三方 JAR 作为依赖项,或者通过 HTTP 调用一些服务器,将您的国家和月份和年份作为参数发送到您的请求中(我需要付费订阅)。

标签: java date


【解决方案1】:

嗯,没有标准的 Java 库来获取假期的日期。这将过于本地化,因为假期很大程度上取决于您所在的国家和地区(众所周知的假期除外,例如圣诞节或复活节)。

您必须依赖一些外部资源,例如假期 API。一旦有了假期,您就可以轻松获得一个月的第一个工作日。

在下面的代码中,我将假期硬编码为SetLocalDates。我还假设工作日是从星期一到星期五。

public static Optional<LocalDate> firstBusinessDayOfMonth(YearMonth month) {

    // I've hardcoded the holidays as LocalDates
    // and put them in a Set
    final Set<LocalDate> holidays = Set.of(
        LocalDate.of(2021, 11, 1),
        LocalDate.of(2021, 11, 2),
        LocalDate.of(2021, 11, 3)
    );
    // For the sake of efficiency, I also put the business days into a Set.
    // In general, a Set has a better lookup speed than a List.
    final Set<DayOfWeek> businessDays = EnumSet.of(
        MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
    );

    return

        // All dates of the month
        month.atDay(1).datesUntil(month.plusMonths(1).atDay(1))

            // Retain all business days. Use static imports from
            // java.time.DayOfWeek.*
            .filter(date -> businessDays.contains(date.getDayOfWeek()))

            // Retain only dates not present in our holidays list
            .filter(date -> !holidays.contains(date))

            // Get the first
            .findFirst();
}

要获取当月的第一个工作日,请使用firstBusinessDayOfMonth(YearMonth.now())

请注意,此方法返回Optional,因为理论上可能是整个月内没有工作日。

【讨论】:

    【解决方案2】:

    感谢所有的答案和帮助,但这正是我想要的。

    在这里,在我的 isOperateDay 变量中,他们说他们已经从其他服务器发送给我的数据是 1 个工作日,而不是 0 个工作日。我只是想做的是检查昨天和今天之间的值是否是第一个工作日。 如您所见,我将昨天的月份与今天的月份进行比较,如果昨天的月份不同,则表示是上个月,而我当天的月份被视为第一个工作日。

    @Data
    class ST_XF_DWH {
        private LocalDateTime previousDate;
        private LocalDateTime currentDate;
        private int isOperateDate;
    }
    
        public void isFirstWorkDay(ST_XF_DWH st_xf_dwh) {
    
            LocalDateTime previousDate = st_xf_dwh.getPreviousDate();
    
            LocalDateTime currentDate = st_xf_dwh.getCurrentDate();
    
            if (previousDate.getMonth() != currentDate.getMonth() && st_xf_dwh.getIsOperateDate() == 1) {
                System.out.println("Is First Work Day" + st_xf_dwh.getCurrentDate());
            } else {
                System.out.println(st_xf_dwh.getCurrentDate() + "is not First Work Day");
            }
    
        }
    

    【讨论】:

    • 你的意思是返回值是布尔值吗? @OleV.V.
    • 如果是这样,那就是这样做的,因为它现在是一个简单的实验。
    • 我会声明 isOperateDate boolean(不是 int)。抱歉,我不清楚。
    • 这不是我的规则,这是规则,提供者声明。
    猜你喜欢
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-20
    • 1970-01-01
    • 1970-01-01
    • 2015-02-26
    相关资源
    最近更新 更多