我需要实现一个能够计算working days的劳动日历,当然,还有自然日。日历必须能够处理国家节假日,这些日子必须由用户提交。因此,如果我需要计算两天之间的差值,则计数必须忽略星期六、星期日和假日。
Java类Calendar不能处理假日和工作日,所以我需要自己创建它。我认为有两种可能的方法:
第一种方法:
我可以实现一个新的Day
类,它将有一个布尔isHoliday
来检查这是不是工作日,然后创建一个新类,其中包含处理/计算这一天所需的所有方法。
优点:
、toString、toDate等方法
缺点:
我对这种方法的怀疑是如何存储它。这意味着要创建365个对象,并将它们存储在List
或Linked List
中,这需要处理大量数据。
第二种方式:
我的第二个想法是让它更简单。创建一个用于存储假日的Strings
或Dates数组。示例new ArrayList<String> freeDays = ["01/01/2019", "05/01/2019", "06/01/2019"...]
,并使用新的CalendarUtils类或类似的东西来处理它。
优点:
缺点:
对我来说,第一个选项看起来更好,但是,我不想浪费内存或使用糟糕的做法。
哪个选项看起来更好?还有没有第三种选择?
发布于 2018-08-02 01:36:24
避免遗留的日期-时间类
永远不要使用Date
或Date
类。那些非常麻烦的旧类现在是遗留的,被java.time类取代,特别是Instant
和ZonedDateTime
。你可能也会发现LocalDate
很有帮助。
智能对象,而非哑字符串
永远不要在Java代码中使用字符串来表示日期-时间。使用对象,java.time类。
当以文本形式交换日期-时间值时,请始终使用标准ISO 8601格式。默认情况下,java.time类在解析/生成字符串时使用这些格式。日期应为YYYY-MM-DD,例如2018-01-23
。
TemporalAdjuster
接口
要跳过周末,请使用项目中的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类。也许是nextBusinessDay
和previousBusinessDay
。上面提到的ThreeTen-Extra项目是开源的,所以请在那里查找指导您的代码。我隐约记得我自己在Stack Overflow上发布了一个或多个TemporalAdjuster
的实现。
您可以将这些假日日期存储在数据库中以便于持久化。并在运行时将它们按时间顺序表示为List< LocalDate >
,用Collections.sort
排序,用Collections.binarySearch
搜索。但要当心thread-safety。您可能需要在运行时更新该列表。边读边写必须受到保护。搜索更多信息。并阅读这本优秀的书, by Brian Goetz et al.
您可以将跳过假日的代码与跳过周末的代码组合在一起。使用搜索引擎在周末查找我的答案-使用EnumSet
和DayOfWeek
枚举跳过。(不幸的是,Stack Overflow内置的搜索功能偏向于问题,而忽略了答案。)
搜索堆栈溢出。所有这些问题以前都被问过,也回答过。
https://stackoverflow.com/questions/51637777
复制相似问题