Preamble
All support for other temporal types is centralized in the special conversion class
TemporalType
and its subtypes. These classes allow conversion between the external type S and Time4J-type T. For the
direction T => S, you simply use the method from(T)
. The method translate(S)
realizes the reverse direction.
Bridge to java.util.Date
This is mainly realized by the element constant TemporalType.JAVA_UTIL_DATE
which performs
a transformation between the global types java.util.Date
and Moment
. Note that
this transformation is sometimes lossy: Leap seconds will get lost as well as micro- or nanoseconds.
// S => T java.util.Date jud = new java.util.Date(0L); Moment moment = TemporalType.JAVA_UTIL_DATE.translate(jud); // 1970-01-01T00:00:00,000000000Z // T => S Moment moment = Moment.of(0, 123456789, TimeScale.POSIX); java.util.Date jud = TemporalType.JAVA_UTIL_DATE.from(moment); // 1970-01-01T00:00:00,123000000Z
There is also direct support for the interpretation of the count of milliseconds since UNIX-epoch as long
via the element constant MILLIS_SINCE_UNIX
which performs a transformation to the class
Moment
, too.
SQL-support
The mapping between JDBC-SQL-types and Time4J is done this way (using the subclass JDBCAdapter):
java.sql.Date
<=>PlainDate
in the year range 1900-9999java.sql.Time
<=>PlainTime
without the special time T24:00java.sql.Timestamp
<=>PlainTimestamp
(subsecond support based on best efforts)java.sql.Timestamp
<=>Moment
(for SQL-type TIMESTAMP WITH ZONE)
Objects of type Moment
can be stored in the database by either using its canonical ISO-representation
(preserving all details like nanosecond precision or leap seconds) or by mapping to a long number using
the elapsed seconds since UNIX epoch. Or you simply convert a Moment
first to java.util.Date
and store the latter one.
XML-support
The mapping between XML-types and Time4J is done this way (using the subclass XMLAdapter):
javax.xml.datatype.XMLGregorianCalendar
<=>PlainDate
javax.xml.datatype.XMLGregorianCalendar
<=>PlainTime
without the special time T24:00javax.xml.datatype.XMLGregorianCalendar
<=>PlainTimestamp
javax.xml.datatype.XMLGregorianCalendar
<=>ZonalDateTime
javax.xml.datatype.Duration
<=>net.time4j.Duration<IsoUnit>
How to convert between java.util.Date
and local types?
This conversion always requires a timezone or an offset because java.util.Date
is a
global type. Consequently you have to use an intermediate instance of class Moment
. Example
for PlainDate
:
TZID tzid = EUROPE.PARIS; // one hour ahead of UTC+00:00 // to PlainDate java.util.Date jud1 = new java.util.Date(0L); PlainDate date1 = TemporalType.JAVA_UTIL_DATE.translate(jud1).toZonalTimestamp(tzid).getCalendarDate(); System.out.println(date1); // output: 1970-01-01 // from PlainDate (at midnight T00:00) PlainDate date2 = PlainDate.of(1970, 1, 1); java.util.Date jud2 = TemporalType.JAVA_UTIL_DATE.from(date2.atStartOfDay().inTimezone(tzid)); System.out.println(jud2.getTime() + " ms"); // -3600000 ms (= 1969-12-31T23:00)
Interoperability with Java 8+
The class TemporalType
is extended by several conversion constants which help to
convert between some Time4J-types and the most important types of the new built-in library java.time
in Java-8 (JSR-310).
java.time.LocalDate
<=>PlainDate
java.time.LocalTime
<=>PlainTime
java.time.LocalDateTime
<=>PlainTimestamp
java.time.Instant
<=>Moment
java.time.ZonedDateTime
<=>ZonalDateTime
java.time.Duration
<=>net.time4j.Duration<ClockUnit>
java.time.Period
<=>net.time4j.Duration<CalendarUnit>
java.time.Clock
<=>TimeSource<?>
All four basic types of Time4J (that is PlainDate
, PlainTime
, PlainTimestamp
and Moment
)
also offer short-cut-conversions using the methods from(...)
and toTemporalAccessor()
. Example:
LocalDate input = ...; PlainDate date = PlainDate.from(input); date = date.with(PlainDate.DAY_OF_QUARTER.maximized()); LocalDate endOfCurrentQuarterYear = date.toTemporalAccessor();
Every basic type of Time4J is also a TemporalAccessor
. This enables you to use these types directly in code expressions
based on java.util.Formatter
. Example:
String s = String.format(Locale.ENGLISH, "%1$tb %1$te, %1$tY", PlainDate.of(1995, MAY, 23)); System.out.println(s); // May 23, 1995
Please also note the fact that a type like PlainDate
can be directly used in the format engine of Java-8 (using its class
DateTimeFormatter
). However, this is less recommended because Time4J has its own more powerful format engine embedded in the
i18n-module. Latter one can even directly print any TemporalAccessor
as far as it is convertible. So the JSR-310-classes can
easily take profit from the extra features of ChronoFormatter
, for example printing historical dates, see next page.