#722: DateTimeFormatter.java
projectforge-business/src/main/java/org/projectforge/framework/time/DateTimeFormatter.java Date/Time Display Formatter, projectforge-business/src/main/java/org/projectforge/framework/time/DateTimeFormatter.java 321 lines · 152 code · 139 comments · 30 blank
Singleton formatter (extends AbstractFormatter) providing user-locale-aware date, time, timestamp, week-of-year, and duration formatting. The primary display layer between internal date objects and UI output, leveraging i18n patterns from DateFormats.
Singleton Pattern
Implements the singleton pattern via a static instance field and instance() accessor. Extends AbstractFormatter, which provides getI18nMessage() for localized unit labels (day, hour).
Duration Constants
| Constant | Value | Used By |
DEFAULT_HOURS_OF_DAY | 8 | getPrettyFormattedDuration(long) |
DEFAULT_MIN_HOURS4DAY_SEPARATION | 24 | getPrettyFormattedDuration(long) |
A configurable durationOfWorkingDay field (default 8, settable) is used by the non-pretty duration methods.
Date Formatting Methods
| Method | Pattern Source | TimeZone / Locale Source |
getFormattedDate(Object) | DateFormatType.DATE (short) | ThreadLocalUserContext |
getFormattedDate(PFUserDO, Object) | User's configured date format | User's locale & timezone |
getFormattedDate(Object, Locale, TimeZone) | DateFormatType.DATE | Explicit locale & timezone |
getFormattedDate(Object, String pattern) | Explicit pattern | ThreadLocalUserContext |
getFormattedDate(Object, String, Locale, TimeZone) | Explicit pattern | Explicit locale & timezone |
LocalDate support: getFormattedDate(Object, String, Locale, TimeZone) handles java.time.LocalDate via java.time.format.DateTimeFormatter.ofPattern(), while other date types use SimpleDateFormat.
Timestamp Formatting Methods
| Method | Pattern Source |
getFormattedDateTime(Date) | DateFormatType.DATE_TIME_SHORT_MINUTES |
getFormattedDateTime(Date, Locale, TimeZone) | DateFormatType.DATE_TIME_SHORT_MINUTES |
getFormattedDateTime(Date, String pattern) | Explicit pattern |
getFormattedDateTime(Date, String, Locale, TimeZone) | Explicit pattern |
Time & Week Formatting
| Method | Description |
formatWeekOfYear(Date|LocalDate) | Zero-padded 2-digit week number; "" if null |
getFormattedTime(Date) | Time-of-day via TIME_OF_DAY_MINUTES pattern |
getFormattedTime(Date, String pattern) | Time-of-day with explicit pattern |
getFormattedTimePeriodOfDay(TimePeriod) | "{date} {fromTime}-{toTime}" format, e.g., "2026-05-14 09:00-17:00" |
Duration Formatting
Standard Duration
| Method | Example Output |
getFormattedDuration(long millis) | "9:00h" or "12d 1:00h" |
getFormattedDuration(long millis, int hoursOfDay, int minHours4DaySeparation) | Like above with configurable thresholds |
Pretty Duration
Produces dual-format output showing total and day-separated views:
| Method | Example |
getPrettyFormattedDuration(long millis) | "12d 1:00h (97:00h)" |
The second part (in parentheses) only appears when minHours4DaySeparation is -1 (showing total hours without day separation). The pretty method renders both the day-separated and total-hours formats side by side when they differ.
Duration Computation
Both methods delegate to TimePeriod.getDurationFields(millis, hoursOfDay, minHours4DaySeparation), which returns int[3]: [days, hours, minutes]. The getFormattedDuration method builds a localized string with abbreviated unit labels from i18n ("calendar.unit.day", "calendar.unit.hour"). Minutes are zero-padded to 2 digits.
Dependencies
- Internal:
AbstractFormatter, DateFormats, DateFormatType, TimePeriod, ThreadLocalUserContext, UserLocale, UserTimeZone
- JDK:
java.text.SimpleDateFormat, java.time.LocalDate, java.time.format.DateTimeFormatter
Git History
868d6abb7 2026-01-01 2025 -> 2026
63081666f 2025-01-01 Source file headers: 2024-> 2025.
a72903e36 2024-10-14 *.java, *.kt: StringBuffer -> StringBuilder.
b6092df09 2024-01-09 Copyright 2023 -> 2024
ab45d51fa 2023-01-01 Copyright 2001-2022 -> 2001-2023.
556b74ecd 2022-06-27 DateFormats -> Kotlin: supports now user different from ThreadLocalUser (for e-mails) ...
5f7ef41b8 2022-02-18 Copyright 2021 -> 2022
ceb63e8a1 2021-03-08 Source code header: (C) 2001-2021.
78b436d9e 2020-01-17 Replace instances of java.util.date and java.sql.Date with java.time.LocalDate
f070a11e8 2020-01-05 Employee.birthday/eintrittsdatum/austrittsdatum: Date -> LocalDate ...
7c79f1922 2020-01-03 Copyright of source header -> 2020.
73a9755df 2019-10-11 More code cleanup ...
32f634b88 2019-10-09 Optimize imports
000ca723d 2019-10-07 Remove pointless boolean expressions (business)
dd5ca38ac 2019-06-07 CopyRight of all java file-header updated or created.
f751c0b68 2019-04-14 DateTimeFomatter.getFormattedTimePeriodOfDay added.
9ebb88522 2016-07-18 Initial commit