#721: DateHolder.java

projectforge-business/src/main/java/org/projectforge/framework/time/DateHolder.java Mutable Date Wrapper with Precision, projectforge-business/src/main/java/org/projectforge/framework/time/DateHolder.java 640 lines · 314 code · 247 comments · 79 blank
Mutable, precision-aware date/time holder that wraps a PFDateTime object. Supports truncation/rounding via DatePrecision, date arithmetic, working-day addition, boundary navigation (begin/end of day/week/month/year), and comparison operations. Implements Cloneable, Serializable, and Comparable.

Core Design

DateHolder is a mutable wrapper around an internal PFDateTime instance, paired with a DatePrecision enum that controls how fields are truncated or rounded. All setters call ensurePrecision(), which invokes PFDateTime.withPrecision(precision) to zero-out or round fields below the declared precision level.

DatePrecision Truncation

Constructor Overview

16 constructors covering all combinations of: Date (or none for current time), DatePrecision, TimeZone, and Locale. All ensure precision after initialization. The no-arg constructor creates a PFDateTime.now() with no precision set.

Field Accessors (Delegated to PFDateTime)

MethodReturns
getUtilDate()java.util.Date
getLocalDate()java.time.LocalDate
getYear()int
getMonth()java.time.Month enum
getMonthValue()1–12 (1-based)
getWeekOfYear()int (delegates to DateHelper.getWeekOfYear logic)
getDayOfYear()1–366
getDayOfMonth()1–31
getDayOfWeek()java.time.DayOfWeek
getHourOfDay()0–23
getMinute()0–59
getSecond()0–59
getMilliSecond()0–999
getTimeInMillis()epoch millis
getTimeOfDay()seconds since midnight (hour*3600 + min*60 + sec)

Boundary Navigation (all return this for chaining)

MethodEffect
setBeginOfYear()Jan 1, 00:00:00.000
setEndOfYear()Dec 31, 23:59:59.999
setBeginOfMonth()1st of month, 00:00:00.000
setEndOfMonth()Last day of month, 23:59:59.999
setBeginOfWeek()First day of week (locale-dependent), 00:00:00.000
setEndOfWeek()Last day of week, 23:59:59.999
setBeginOfDay()00:00:00.000
setEndOfDay()23:59:59.999
isBeginOfWeek()True if day==firstDayOfWeek AND time==00:00:00.000

Comparison & Arithmetic

MethodDescription
before(DateHolder|Date)Delegates to java.util.Date.before()
after(DateHolder|Date)Delegates to java.util.Date.after()
isBetween(Date|DateHolder, Date|DateHolder)Inclusive range check; handles null boundaries
isSameDay(Date|DateHolder)Compares year+dayOfYear via PFDateTime.isSameDay()
daysBetween(Date|DateHolder)Returns (other - this) in calendar days
add(int field, int amount)Adds units using PFDateCompatibilityUtils for field mapping
addWorkingDays(int days)Adds working days (max 10,000); uses PFDayUtils.addWorkingDays()
compareTo(DateHolder)Delegates to PFDateTime.compareTo()

Equality Contract

equals() and hashCode() consider both getTimeInMillis() and getPrecision(). Two DateHolders are equal only if they represent the exact same millisecond and have the same precision level.

Historical Note

This class was originally based on java.util.Calendar and was migrated to PFDateTime (backed by java.time) between Dec 2019 and Jan 2020. All field manipulation now delegates to PFDateTime. The add(int field, int amount) method still uses legacy Calendar field constants mapped via PFDateCompatibilityUtils.

Git History

868d6abb7 2026-01-01 2025 -> 2026
63081666f 2025-01-01 Source file headers: 2024-> 2025.
b6092df09 2024-01-09 Copyright 2023 -> 2024
ab45d51fa 2023-01-01 Copyright 2001-2022 -> 2001-2023.
5f7ef41b8 2022-02-18 Copyright 2021 -> 2022
ceb63e8a1 2021-03-08 Source code header: (C) 2001-2021.
b209e00ba 2020-01-30 PFDay.from -> from, fromOrNow, fromOrNull, PFDateTime.from -> from, fromOrNow, fromOrNull
345e8a999 2020-01-30 DateHolder(LocalDate...) -> PFDay.from(LocalDate...).
8cf9911d4 2020-01-28 HRPlanningList: Fix EditPage
6874f66b4 2020-01-25 FirstDayOfWeek...
7c1c48782 2020-01-21 Replacing more instance of java.sql.Date with java.time.LocalDate ...
e4bcd0f56 2020-01-14 DateHolder.getMonthValue added.
7c79f1922 2020-01-03 Copyright of source header -> 2020.
a1c287b49 2019-12-28 Week of year is now globally the same ...
4b53b6562 2019-12-24 PFDate -> PFDay, IPFDate introduced..
fbb345c70 2019-12-24 Wrong substitution of "calendar" -> "datetime" while refactoring reverted.
8c31eba2a 2019-12-23 Heavy WIP: migration of Calendar, DateHolder, DayHolder etc.
1a1c010ef 2019-12-23 DateHelper/DateHolder: documented, that month is 0-based.
24019a0f5 2019-12-19 Eliminate DateHolder occurences
4cd7c8e69 2019-12-05 Replace DateHolder and DayHolder methods with PFDateTime
48b2b1bfa 2019-10-20 DateHolder.setBeginOfWeek(): Paranoia counter added for avoiding endless loops ...
1812702d5 2019-10-20 DateHolder.setBeginOfWeek() fixed. Calendar.set(DAY_OF_WEEK, firstDayOfWeek) seems to work different in Java 11 ...
97991a2c4 2019-10-09 Revert "Simplify boolean return statements (business)"
40480b54d 2019-10-07 Simplify boolean return statements (business)
000ca723d 2019-10-07 Remove pointless boolean expressions (business)
1ef12e5e7 2019-06-10 Doc
dd5ca38ac 2019-06-07 CopyRight of all java file-header updated or created.
f979e8a42 2017-11-20 MGC-UPDATE: Update auf Version 3.0.0-SNAPSHOT
9ebb88522 2016-07-18 Initial commit