Modern Java in Action 6 - Time and Date
Reasons to abandon old API
java.util.Date
- mutable
- unintuitive constructor (days, months, minutes and seconds are 0-based, year represented as delta from 1900), values wrap-around
- cannot be internationalized
java.util.Calendar
- not thread safe
- mutable (no clear semantics date change)
- when to use which?
java.util.DateFormat
- not thead-safe
- can only parse
Date
, notCalendar
New API
java.time package
Classes and interfaces in a new package java.time
(modelled after Joda Time classes) provide better way of thinking about and working with time concepts.
The most important classess in this package are: LocalDate, LocalTime, LocalDateTime, Instant, Duration, and Period .
LocalDateTime and LocalTime instances don’t contain timezone information. They are:
-
immutable
-
can read fields in two ways:
- using getters (e.g.
date.getYear()
) - using TeporalField enum (e.g.
date.get(ChronoField.YEAR)
)
- using getters (e.g.
-
parsing is possible separately for dates and times:
1 2
LocalDate date = LocalDate.parse("2022-06-30"); LocalTime time = LocalTime.parse("12:35:20");
-
combine 2022-06-30 12:36:48 and time with LocalDateTime
1 2 3 4 5
LocalDateTime dt1 = LocalDateTime.of(2022, Month.JUNE, 30, 12, 35, 20); LocalDateTime dt2 = LocalDateTime.of(date, time); LocalDateTime dt3 = date.atTime(12, 35, 20); LocalDateTime dt4 = date.atTime(time); LocalDateTime dt5 = time.atDate(date);
-
extract LocalDate and LocalTime from LocalDateTime (
dt.toLocalDate()
anddt.toLocalTime()
)
Instant - for machine processing
- number of seconds since epoch (midninght, Jan 1 1970 UTC)
- fatcory method
Instant.of(num_of_seconds)
andInstant.of(num_of_seconds, nano_adjustment)
Instant.now()
captures intant of current moment- cannot provide tempopral details (yers or seconds)
Duration
- denotes how much time there is between two temporal objects
- used to represent the amount measured in seconds and nanoseconds
- created with
Duration.between(a1, a2)
where a1 and a2 are either:- time
- datetime
- instant
- created also with:
Duration.ofMinutes(10)
Duration.of(2, CroniUnit.MINUTES)
Period
- represents amount of days, months, years
- can be created with
Period.between
- also with:
Period.ofWeeks(3)
- period of three weeksPeriod.of(10, 2, 3)
- 10 years, 2 months and 3 days
Manipulation
It is not a manupulation but a way to receive another LocalDate from existing one:
|
|
Fun with simple arithmetics
Temporal interface allow to do dates arithmetics:
- you can
plus
andminus
someTemporalAmount
(i.e. Duration or Period) fromTemporal
s - you can check how much is left
until
another Temporal (expressed in givenTemporalUnit
Note: ChronoField and ChronoUnit are located in java.time.temporal package.
|
|
- or what would be next Monday after specific LocalDate:
|
|
More fun with TemporalAdjusters
Class TemporalAdjusters allows to find :
- first or last day of this/next month
- first or last day in the year
- first or last day-of-week within a month (first Friday in May)
- next or previous day of week (next Sunday)
You can create your own adjuster with:
|
|
or implement custo m TemporalAdjuster
:
|
|
Formatting and parsing
This functionality lives in java.time.format package. Predefined instances of DateTimeFormatter
(as static contants) provde common ways for formatting/parsing of dates.
- formatting
|
|
- parsing
|
|
Working with timezones
This is the pearl of this package.
- ZoneId represents a zone in a form “{area}/{city}” (taken from IANA)
- each might have specific rules determining the time
LocalDateTime can be converted to Instant provided the ZoneId; Instant can be converted to LocalDateTime also only when it is known in what timezone the date is needed:
|
|
ZoneOffset can express a time zone with fixed offset from UTC/Greenwich:
|
|
which can be used to see hat offset time there is right now:
|
|
Alternative calendar systems
There are other calendar systems available as well:
ThaiBuddhistDate, MinguoDate, JapaneseDate, and HijrahDate
Example:
|
|
Note
As a refresher on date-time types in PostgreSQL, see my other blog post: postgres - dates
Ten wpis jest częścią serii modern-java-in-action.
- 2022-05-07 - Modern Java in Action 8 - concurrency and reactive programming
- 2022-02-07 - Modern Java in Action 7 - notes about the module system
- 2022-30-06 - Modern Java in Action 6 - Time and Date
- 2022-20-06 - Modern Java in Action 5 - Optional
- 2022-17-06 - Modern Java in Action 4 - refactoring and testing
- 2022-15-06 - Modern Java in Action 3 - collection API
- 2022-14-06 - Modern Java in Action 2 - fork-join and spliterators
- 2022-03-06 - Modern Java in Action 1 - Java 8 refresher