【问题标题】:Best way to handle Java Calendar with working days?在工作日处理 Java 日历的最佳方法?
【发布时间】:2018-08-02 04:25:12
【问题描述】:

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

Java类Calendar,不处理节假日和工作日,需要自己做。我想了两种可能的方法:

第一种方式:

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

优点:

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

缺点:

  • (也许?)

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

第二种方式:

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

优点:

  • 更具可读性

缺点:

  • 很难合作

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

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

【问题讨论】:

标签: java date calendar


【解决方案1】:

避免使用旧的日期时间类

永远不要使用 DateCalendar 类。 那些非常麻烦的旧类现在已被遗留,被 java.time 类取代,特别是 InstantZonedDateTime。您可能会发现LocalDate 也很有帮助。

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

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

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

TemporalAdjuster接口

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

例子:

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 项目是开源的,因此请查看那里的代码来指导您。我隐约记得自己在 Stack Overflow 上发布了一个或多个 TemporalAdjuster 的实现。

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

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

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

【讨论】:

  • 正是我需要知道的。非常感谢。
猜你喜欢
  • 2014-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多