在工作日处理Java日历的最佳方法?

时间:2018-08-01 16:04:40

标签: java date calendar

我需要实施一个能够记录工作天以及自然天数的劳动日历。日历必须能够处理国定假日,并且这些天必须由用户提交。 因此,如果我需要计算两天之间的差额,则计数必须忽略周六,周日和节假日。

Java类Calendar不能处理假期或工作日,因此我需要自己做。我认为有两种可能的方式:

第一种方式:

我可以实现一个新的Day类,该类具有一个布尔isHoliday来检查这是否是一个工作日,然后使用我需要处理的所有方法创建一个新类/计算天数。

优点:

  • 易于处理
  • 我可以覆盖/创建诸如toString,toDate等的方法...

缺点:

  • 沉重(也许吗?)

我对此方法的怀疑是如何存储它。这意味着要制作365个对象并将它们存储在ListLinked List中,这需要处理大量数据。

第二种方式:

我的第二个想法是使其更简单。创建一个StringsDates数组,用于存储假期。 示例new ArrayList<String> freeDays = ["01/01/2019", "05/01/2019", "06/01/2019"...],并使用新的CalendarUtils类或类似的类来进行处理。

优点:

  • 更具可读性

缺点:

  • 很难与之合作

对我来说,第一种选择看起来更好,但是,我不想浪费内存或使用不良做法。

哪个选项看起来更好?有第三种选择吗?

1 个答案:

答案 0 :(得分:1)

避免使用旧的日期时间类

从不使用DateCalendar类。那些非常麻烦的旧类现在已成为旧版,由 java.time 类取代,特别是InstantZonedDateTime。您可能会发现LocalDate也很有帮助。

智能对象,而不是哑字符串

请不要在Java代码中使用字符串来表示日期时间。使用对象,即 java.time 类。

以文本形式交换日期时间值时,请始终使用标准的ISO 8601格式。 java.time 类在解析/生成字符串时默认使用这些格式。对于将为YYYY-MM-DD的日期,例如2018-01-23

TemporalAdjuster界面

要跳过周末,请使用TemporalAdjuster项目中的ThreeTen-Extra实现。

示例:

LocalDate                        // Represent a date-only value, without a time-of-day and without a time zone. 
.now(                            // Capture the current date. 
    ZoneId.of( "Africa/Tunis" )  // Time zone required. For any given moment the date varies around the globe by zone. 
)
.with(                           // Invoke a `TemporalAdjuster` implementation. 
    org.threeten.extra.Temporals.nextWorkingDay() 
)                                // Returns a `LocalDate`. Using immutable objects pattern, producing a fresh object based on the values of another while leaving the original unaltered. 

要跳过假期,您必须编写自己的代码。没有两个人,公司或国家/地区对假期有相同的定义。

您需要定义自己的假期列表。我建议将其写为TemporalAdjuster的实现,以便与 java.time 类一起使用。也许nextBusinessDaypreviousBusinessDay。上面提到的 ThreeTen-Extra 项目是开源的,因此请参考那里的代码来指导您。我隐约记得在堆栈溢出中自己张贴了TemporalAdjuster的一个或多个实现。

您可以将那些假期日期存储在数据库中以保持持久性。并在运行时按时间顺序将它们表示为List< LocalDate >,用Collections.sort排序并用Collections.binarySearch搜索。但请注意thread-safety。您可能需要在运行时更新该列表。阅读时写作必须受到保护。搜索更多信息。并阅读优秀的书籍Java Concurrency in Practice by Brian Goetz et al.

您可以将假期跳过代码与周末跳过代码结合使用。使用搜索引擎使用EnumSetDayOfWeek枚举在周末跳过时找到我的答案。 (不幸的是,Stack Overflow中内置的搜索功能偏向于“问题”,而忽略了“答案”。)

搜索堆栈溢出。所有这些都已经被问过并回答过。