mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-06 21:18:31 +00:00
This change abstracts the specific types away from the different representations of datetime as a datetime representation in code can be all kinds of different things. This defines the three most common types of datetimes as numeric, string, and complex while outlining the type most typically used for these as long, String, and ZonedDateTime, respectively. Documentation uses the definitions while examples use the types. This makes the documentation easier to consume especially for people from a non-Java background.
337 lines
10 KiB
Plaintext
337 lines
10 KiB
Plaintext
[[painless-datetime]]
|
|
=== Using Datetime in Painless
|
|
|
|
==== Datetime API
|
|
|
|
Datetimes in Painless use the standard Java libraries and are available through
|
|
the Painless <<painless-api-reference-shared, Shared API>>. Most of the classes
|
|
from the following Java packages are available to use in Painless scripts:
|
|
|
|
* <<painless-api-reference-shared-java-time, java.time>>
|
|
* <<painless-api-reference-shared-java-time-chrono, java.time.chrono>>
|
|
* <<painless-api-reference-shared-java-time-format, java.time.format>>
|
|
* <<painless-api-reference-shared-java-time-temporal, java.time.temporal>>
|
|
* <<painless-api-reference-shared-java-time-zone, java.time.zone>>
|
|
|
|
==== Datetime Representation
|
|
|
|
Datetimes in Painless are most commonly represented as a numeric value, a
|
|
string value, or a complex value.
|
|
|
|
numeric:: a datetime representation as a number from a starting offset called
|
|
an epoch; in Painless this is typically a <<primitive-types, long>> as
|
|
milliseconds since an epoch of 1970-01-01 00:00:00 Zulu Time
|
|
string:: a datetime representation as a sequence of characters defined by
|
|
a standard format or a custom format; in Painless this is typically a
|
|
<<string-type, String>> of the standard format
|
|
https://en.wikipedia.org/wiki/ISO_8601[ISO 8601]
|
|
complex:: a datetime representation as a complex type
|
|
(<<reference-types, object>>) that abstracts away internal details of how the
|
|
datetime is stored and often provides utilities for modification and
|
|
comparison; in Painless this is typically a
|
|
<<painless-api-reference-shared-ZonedDateTime>>
|
|
|
|
Switching between different representations of datetimes is often necessary to
|
|
achieve a script's objective(s). A typical pattern in a script is to switch a
|
|
numeric or string datetime to a complex datetime, modify or compare the complex
|
|
datetime, and then switch it back to a numeric or string datetime for storage
|
|
or to return a result.
|
|
|
|
==== Datetime Parsing and Formatting
|
|
|
|
Datetime parsing is a switch from a string datetime to a complex datetime, and
|
|
datetime formatting is a switch from a complex datetime to a string datetime.
|
|
|
|
A <<painless-api-reference-shared-DateTimeFormatter, DateTimeFormatter>> is a
|
|
complex type (<<reference-types, object>>) that defines the allowed sequence
|
|
of characters for a string datetime. Datetime parsing and formatting often
|
|
requires a DateTimeFormatter. For more information about how to use a
|
|
DateTimeFormatter see the
|
|
{java11-javadoc}/java.base/java/time/format/DateTimeFormatter.html[Java documentation].
|
|
|
|
===== Datetime Parsing Examples
|
|
|
|
* parse from milliseconds
|
|
+
|
|
[source,Painless]
|
|
----
|
|
String milliSinceEpochString = "434931330000";
|
|
long milliSinceEpoch = Long.parseLong(milliSinceEpochString);
|
|
Instant instant = Instant.ofEpochMilli(milliSinceEpoch);
|
|
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.of('Z'));
|
|
----
|
|
+
|
|
* parse from ISO 8601
|
|
+
|
|
[source,Painless]
|
|
----
|
|
String datetime = '1983-10-13T22:15:30Z';
|
|
ZonedDateTime zdt = ZonedDateTime.parse(datetime);
|
|
----
|
|
Note the parse method uses ISO 8601 by default.
|
|
+
|
|
* parse from RFC 1123
|
|
+
|
|
[source,Painless]
|
|
----
|
|
String datetime = 'Thu, 13 Oct 1983 22:15:30 GMT';
|
|
ZonedDateTime zdt = ZonedDateTime.parse(datetime,
|
|
DateTimeFormatter.RFC_1123_DATE_TIME);
|
|
----
|
|
Note the use of a built-in DateTimeFormatter.
|
|
+
|
|
* parse from a custom format
|
|
+
|
|
[source,Painless]
|
|
----
|
|
String datetime = 'custom y 1983 m 10 d 13 22:15:30 Z';
|
|
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(
|
|
"'custom' 'y' yyyy 'm' MM 'd' dd HH:mm:ss VV");
|
|
ZonedDateTime zdt = ZonedDateTime.parse(datetime, dtf);
|
|
----
|
|
Note the use of a custom DateTimeFormatter.
|
|
|
|
===== Datetime Formatting Examples
|
|
|
|
* format to ISO 8601
|
|
+
|
|
[source,Painless]
|
|
----
|
|
ZonedDateTime zdt =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));
|
|
String datetime = zdt.format(DateTimeFormatter.ISO_INSTANT);
|
|
----
|
|
Note the use of a built-in DateTimeFormatter.
|
|
+
|
|
* format to a custom format
|
|
+
|
|
[source,Painless]
|
|
----
|
|
ZonedDateTime zdt =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));
|
|
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(
|
|
"'date:' yyyy/MM/dd 'time:' HH:mm:ss");
|
|
String datetime = zdt.format(dtf);
|
|
----
|
|
Note the use of a custom DateTimeFormatter.
|
|
|
|
==== Datetime Conversion
|
|
|
|
Datetime conversion is a switch from a numeric datetime to a complex datetime
|
|
and vice versa.
|
|
|
|
===== Datetime Conversion Examples
|
|
|
|
* convert from milliseconds
|
|
+
|
|
[source,Painless]
|
|
----
|
|
long milliSinceEpoch = 434931330000L;
|
|
Instant instant = Instant.ofEpochMilli(milliSinceEpoch);
|
|
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.of('Z'));
|
|
----
|
|
+
|
|
* convert to milliseconds
|
|
+
|
|
[source,Painless]
|
|
-----
|
|
ZonedDateTime zdt =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));
|
|
long milliSinceEpoch = zdt.toInstant().toEpochMilli();
|
|
-----
|
|
|
|
==== Datetime Pieces
|
|
|
|
Datetime representations often contain the data to extract individual datetime
|
|
pieces such as year, hour, timezone, etc. Use individual pieces of a datetime
|
|
to create a complex datetime, and use a complex datetime to extract individual
|
|
pieces.
|
|
|
|
===== Datetime Pieces Examples
|
|
|
|
* create a complex datetime from pieces
|
|
+
|
|
[source,Painless]
|
|
----
|
|
int year = 1983;
|
|
int month = 10;
|
|
int day = 13;
|
|
int hour = 22;
|
|
int minutes = 15;
|
|
int seconds = 30;
|
|
int nanos = 0;
|
|
ZonedDateTime zdt = ZonedDateTime.of(
|
|
year, month, day, hour, minutes, seconds, nanos, ZoneId.of('Z'));
|
|
----
|
|
+
|
|
* extract pieces from a complex datetime
|
|
+
|
|
[source,Painless]
|
|
----
|
|
ZonedDateTime zdt =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 100, ZoneId.of(tz));
|
|
int year = zdt.getYear();
|
|
int month = zdt.getMonthValue();
|
|
int day = zdt.getDayOfMonth();
|
|
int hour = zdt.getHour();
|
|
int minutes = zdt.getMinute();
|
|
int seconds = zdt.getSecond();
|
|
int nanos = zdt.getNano();
|
|
----
|
|
|
|
==== Datetime Modification
|
|
|
|
Use either a numeric datetime or a complex datetime to do modification such as
|
|
adding several seconds to a datetime or subtracting several days from a
|
|
datetime. Use standard <<painless-operators-numeric, numeric operators>> to
|
|
modify a numeric datetime. Use
|
|
<<painless-api-reference-shared-ZonedDateTime, methods>> (or fields) to modify
|
|
a complex datetime. Note many complex datetimes are immutable so upon
|
|
modification a new complex datetime is created that requires
|
|
<<variable-assignment, assignment>> or immediate use.
|
|
|
|
===== Datetime Modification Examples
|
|
|
|
* Subtract three seconds from a numeric datetime in milliseconds
|
|
+
|
|
[source,Painless]
|
|
----
|
|
long milliSinceEpoch = 434931330000L;
|
|
milliSinceEpoch = milliSinceEpoch - 1000L*3L;
|
|
----
|
|
+
|
|
* Add three days to a complex datetime
|
|
+
|
|
[source,Painless]
|
|
----
|
|
ZonedDateTime zdt =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));
|
|
ZonedDateTime updatedZdt = zdt.plusDays(3);
|
|
----
|
|
+
|
|
* Subtract 125 minutes from a complex datetime
|
|
+
|
|
[source,Painless]
|
|
----
|
|
ZonedDateTime zdt =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));
|
|
ZonedDateTime updatedZdt = zdt.minusMinutes(125);
|
|
----
|
|
+
|
|
* Set the year on a complex datetime
|
|
+
|
|
[source,Painless]
|
|
----
|
|
ZonedDateTime zdt =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));
|
|
ZonedDateTime updatedZdt = zdt.withYear(1976);
|
|
----
|
|
|
|
==== Datetime Difference (Elapsed Time)
|
|
|
|
Use either two numeric datetimes or two complex datetimes to calculate the
|
|
difference (elapsed time) between two different datetimes. Use
|
|
<<subtraction-operator, subtraction>> to calculate the difference between
|
|
between two numeric datetimes of the same time unit such as milliseconds. For
|
|
complex datetimes there is often a method or another complex type
|
|
(<<reference-types, object>>) available to calculate the difference. Use
|
|
<<painless-api-reference-shared-ChronoUnit, ChronoUnit>>
|
|
to calculate the difference between two complex datetimes if supported.
|
|
|
|
===== Elapsed Time Examples
|
|
|
|
* Difference in milliseconds between two numeric datetimes
|
|
+
|
|
[source,Painless]
|
|
----
|
|
long startTimestamp = 434931327000L;
|
|
long endTimestamp = 434931330000L;
|
|
long differenceInMillis = endTimestamp - startTimestamp;
|
|
----
|
|
+
|
|
* Difference in milliseconds between two complex datetimes
|
|
+
|
|
[source,Painless]
|
|
----
|
|
ZonedDateTime zdt1 =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 11000000, ZoneId.of('Z'));
|
|
ZonedDateTime zdt2 =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 35, 0, ZoneId.of('Z'));
|
|
long differenceInMillis = ChronoUnit.MILLIS.between(zdt1, zdt2);
|
|
----
|
|
+
|
|
* Difference in days between two complex datetimes
|
|
+
|
|
[source,Painless]
|
|
----
|
|
ZonedDateTime zdt1 =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 11000000, ZoneId.of('Z'));
|
|
ZonedDateTime zdt2 =
|
|
ZonedDateTime.of(1983, 10, 17, 22, 15, 35, 0, ZoneId.of('Z'));
|
|
long differenceInDays = ChronoUnit.DAYS.between(zdt1, zdt2);
|
|
----
|
|
|
|
==== Datetime Comparison
|
|
|
|
Use either two numeric datetimes or two complex datetimes to do a datetime
|
|
comparison. Use standard <<painless-operators-boolean, comparison operators>>
|
|
to compare two numeric datetimes of the same time unit such as milliseconds.
|
|
For complex datetimes there is often a method or another complex type
|
|
(<<reference-types, object>>) available to do the comparison.
|
|
|
|
===== Datetime Comparison Examples
|
|
|
|
* Greater than comparison of two numeric datetimes in milliseconds
|
|
+
|
|
[source,Painless]
|
|
----
|
|
long timestamp1 = 434931327000L;
|
|
long timestamp2 = 434931330000L;
|
|
|
|
if (timestamp1 > timestamp2) {
|
|
// handle condition
|
|
}
|
|
----
|
|
+
|
|
* Equality comparision of two complex datetimes
|
|
+
|
|
[source,Painless]
|
|
----
|
|
ZonedDateTime zdt1 =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));
|
|
ZonedDateTime zdt2 =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));
|
|
|
|
if (zdt1.equals(zdt2)) {
|
|
// handle condition
|
|
}
|
|
----
|
|
+
|
|
* Less than comparision of two complex datetimes
|
|
+
|
|
[source,Painless]
|
|
----
|
|
ZonedDateTime zdt1 =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));
|
|
ZonedDateTime zdt2 =
|
|
ZonedDateTime.of(1983, 10, 17, 22, 15, 35, 0, ZoneId.of('Z'));
|
|
|
|
if (zdt1.isBefore(zdt2)) {
|
|
// handle condition
|
|
}
|
|
----
|
|
+
|
|
* Greater than comparision of two complex datetimes
|
|
+
|
|
[source,Painless]
|
|
----
|
|
ZonedDateTime zdt1 =
|
|
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));
|
|
ZonedDateTime zdt2 =
|
|
ZonedDateTime.of(1983, 10, 17, 22, 15, 35, 0, ZoneId.of('Z'));
|
|
|
|
if (zdt1.isAfter(zdt2)) {
|
|
// handle condition
|
|
}
|
|
----
|