- All Superinterfaces:
Adapter.Contract<T>
,Adapter.Contract.Scalar<T>
- Enclosing interface:
Timespan
- Functional Interface:
- This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
INTERVAL
type's PostgreSQL semantics: separate microseconds,
days, and months components, independently signed.
A type modifier can specify field-presence bits, and precision (number of seconds digits to the right of the decimal point). An empty fields set indicates that fields were not specified.
Why no reference implementation?
The types in the Datetime
interface come with reference
implementations returning Java's JSR310 java.time
types.
For PostgreSQL INTERVAL
, there are two candidate JSR310 types,
Period
and Duration
, each of which would be appropriate
for a different subset of PostgreSQL INTERVAL
values.
Period
is appropriate for the months and days components.
A Period
treats the length of a day as subject to daylight
adjustments following time zone rules, as does PostgreSQL.
Duration
is suitable for the sub-day components. It also allows
access to a "day" field, but treats that as having invariant 24-hour
width.
Both share the superinterface TemporalAmount
. That interface
itself is described as "a framework-level interface that should not
be widely used in application code", recommending instead that new
concrete types can be created that implement it.
In the datatype library that comes with the PGJDBC-NG driver, there is
a class com.impossibl.postgres.api.data.Interval
that takes that
approach exactly; it implements TemporalAmount
and represents
all three components of the PostgreSQL interval with their PostgreSQL
semantics. An application with that library available could use an
implementation of this functional interface that would return instances
of that class.
The PGJDBC driver includes a org.postgresql.util.PGInterval
class
for the same purpose; that one does not derive from any JSR310 type.
Related notes from the ISO SQL/XML specification
SQL/XML specifies how to map SQL INTERVAL
types and values to
the XML Schema types xs:yearMonthDuration
and
xs:dayTimeDuration
, which were added in XML Schema 1.1 as
distinct subtypes of the broader xs:duration
type from XML Schema
1.0. That Schema 1.0 supertype has a corresponding class in the standard
Java library, javax.xml.datatype.Duration
, so an implementation
of this functional interface returning that type would also be easy.
These XML Schema types do not perfectly align with the PostgreSQL
INTERVAL
type, because they group the day with the sub-day
components and treat it as having invariant width. (The only time zone
designations supported in XML Schema are fixed offsets, for which no
daylight rules apply). The XML Schema types allow one overall sign,
positive or negative, but do not allow the individual components to have
signs that differ, as PostgreSQL does.
Java's JSR310 types can be used with equal convenience in the PostgreSQL
way (by assigning days to the Period
and the smaller
components to the Duration
) or in the XML Schema way (by storing
days in the Duration
along with the smaller
components), but of course those choices have different implications.
A related consideration is, in a scheme like SQL/XML's where the SQL
INTERVAL
can be mapped to a choice of types, whether that choice
is made statically (i.e. by looking at the declared type modifier such as
YEAR TO MONTH
or HOUR TO SECOND
for a column) or
per-value (by looking at which fields are nonzero in each value
encountered).
The SQL/XML rule is to choose a static mapping at analysis time according
to the type modifier. YEAR
, MONTH
, or
YEAR TO MONTH
call for a mapping to xs:yearMonthDuration
,
while any of the finer modifiers call for mapping to
xs:dayTimeDuration
, and no mapping is defined for an
INTERVAL
lacking a type modifier to constrain its fields in one
of those ways. Again, those specified mappings assume that days are not
subject to daylight rules, contrary to the behavior of the PostgreSQL
type.
In view of those considerations, there seems to be no single mapping of
PostgreSQL INTERVAL
to a common Java type that is sufficiently
free of caveats to stand as a reference implementation. An application
ought to choose an implementation of this functional interface to create
whatever representation of an INTERVAL
will suit that
application's purposes.
-
Nested Class Summary
Modifier and TypeInterfaceDescriptionstatic enum
static interface
Functional interface to obtain information from the PostgreSQL type modifier applied to the type.Nested classes/interfaces inherited from interface org.postgresql.pljava.Adapter.Contract
Adapter.Contract.Array<T,
E, A extends Adapter<E, ?>>, Adapter.Contract.Scalar<T> -
Field Summary
Modifier and TypeFieldDescriptionstatic final Set
<EnumSet<Timespan.Interval.Field>> static final EnumSet
<Timespan.Interval.Field> static final EnumSet
<Timespan.Interval.Field> static final EnumSet
<Timespan.Interval.Field> static final EnumSet
<Timespan.Interval.Field> static final EnumSet
<Timespan.Interval.Field> static final EnumSet
<Timespan.Interval.Field> static final EnumSet
<Timespan.Interval.Field> static final int
static final EnumSet
<Timespan.Interval.Field> static final EnumSet
<Timespan.Interval.Field> static final EnumSet
<Timespan.Interval.Field> static final EnumSet
<Timespan.Interval.Field> static final EnumSet
<Timespan.Interval.Field> static final EnumSet
<Timespan.Interval.Field> -
Method Summary
-
Field Details
-
YEAR
-
MONTH
-
DAY
-
HOUR
-
MINUTE
-
SECOND
-
YEAR_TO_MONTH
-
DAY_TO_HOUR
-
DAY_TO_MINUTE
-
DAY_TO_SECOND
-
HOUR_TO_MINUTE
-
HOUR_TO_SECOND
-
MINUTE_TO_SECOND
-
ALLOWED_FIELDS
-
MAX_INTERVAL_PRECISION
static final int MAX_INTERVAL_PRECISION- See Also:
-
-
Method Details
-
construct
Constructs a representation T from the components of the PostgreSQL data type.PostgreSQL allows the three components to have independent signs. They are stored separately because the results of combining them with a date or a timestamp cannot be precomputed without knowing the other operand.
In arithmetic involving an interval and a timestamp, the width of one unit in days can depend on the other operand if a timezone applies and has daylight savings rules:
SELECT (t + i) - t FROM (VALUES (interval '1' DAY)) AS s(i), (VALUES (timestamptz '12 mar 2022'), ('13 mar 2022'), ('6 nov 2022')) AS v(t); ---------------- 1 day 23:00:00 1 day 01:00:00
In arithmetic involving an interval and a date or timestamp, the width of one unit in months can depend on the calendar month of the other operand, as well as on timezone shifts as for days:
SELECT (t + i) - t FROM (VALUES (interval '1' MONTH)) AS s(i), (VALUES (timestamptz '1 feb 2022'), ('1 mar 2022'), ('1 nov 2022')) AS v(t); ------------------ 28 days 30 days 23:00:00 30 days 01:00:00
-