Add timezone documentation for Painless datetimes (#43768)

This commit is contained in:
Jack Conradson 2019-07-01 21:29:01 -07:00
parent 4eb89a6912
commit 81f60652d8
2 changed files with 63 additions and 14 deletions

View File

@ -29,7 +29,7 @@ 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>>
<<painless-api-reference-shared-ZonedDateTime, 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
@ -335,6 +335,43 @@ if (zdt1.isAfter(zdt2)) {
}
----
==== Datetime Zone
Both string datetimes and complex datetimes have a timezone with a default of
`UTC`. Numeric datetimes do not have enough explicit information to
have a timezone, so `UTC` is always assumed. Use
<<painless-api-reference-shared-ZonedDateTime, methods>> (or fields) in
conjunction with a <<painless-api-reference-shared-ZoneId, ZoneId>> to change
the timezone for a complex datetime. Parse a string datetime into a complex
datetime to change the timezone, and then format the complex datetime back into
a desired string 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 Zone Examples
* Modify the timezone for a complex datetime
+
[source,Painless]
----
ZonedDateTime utc =
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));
ZonedDateTime pst = utc.withZoneSameInstant(ZoneId.of('America/Los_Angeles'));
----
+
* Modify the timezone for a string datetime
+
[source,Painless]
----
String gmtString = 'Thu, 13 Oct 1983 22:15:30 GMT';
ZonedDateTime gmtZdt = ZonedDateTime.parse(gmtString,
DateTimeFormatter.RFC_1123_DATE_TIME); <1>
ZonedDateTime pstZdt =
gmtZdt.withZoneSameInstant(ZoneId.of('America/Los_Angeles'));
String pstString = pstZdt.format(DateTimeFormatter.RFC_1123_DATE_TIME);
----
<1> Note the use of a built-in DateTimeFormatter.
==== Datetime Input
There are several common ways datetimes are used as input for a script
@ -513,10 +550,9 @@ String output = input.format(DateTimeFormatter.ISO_INSTANT); <1>
+
** Assumptions:
+
*** The fields `start_datetime` and `end_datetime` may *not* exist in all
indexes as part of the query
*** The fields `start_datetime` and `end_datetime` may *not* have values in all
indexed documents
*** The fields `start` and `end` may *not* exist in all indexes as part of the
query
*** The fields `start` and `end` may *not* have values in all indexed documents
+
** Mappings:
+
@ -527,10 +563,10 @@ indexed documents
...
"properties": {
...
"start_datetime": {
"start": {
"type": "date"
},
"end_datetime": {
"end": {
"type": "date"
}
...
@ -544,14 +580,13 @@ indexed documents
+
[source,Painless]
----
if (doc.containsKey('start_datetime') && doc.containsKey('end_datetime')) { <1>
if (doc.containsKey('start') && doc.containsKey('end')) { <1>
if (doc['start_datetime'].size() > 0 && doc['end_datetime'].size() > 0) { <2>
if (doc['start'].size() > 0 && doc['end'].size() > 0) { <2>
def startDatetime = doc['start_datetime'].value;
def endDatetime = doc['end_datetime'].value;
long differenceInMillis =
ChronoUnit.MILLIS.between(startDateTime, endDateTime);
def start = doc['start'].value;
def end = doc['end'].value;
long differenceInMillis = ChronoUnit.MILLIS.between(start, end);
// handle difference in times
} else {

View File

@ -22,7 +22,7 @@ package org.elasticsearch.painless;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class DateTests extends ScriptTestCase {
public class DateTimeTests extends ScriptTestCase {
public void testLongToZonedDateTime() {
assertEquals(ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of("Z")), exec(
@ -177,4 +177,18 @@ public class DateTests extends ScriptTestCase {
"return zdt1.isAfter(zdt2);"
));
}
public void testTimeZone() {
assertEquals(ZonedDateTime.of(1983, 10, 13, 15, 15, 30, 0, ZoneId.of("America/Los_Angeles")), exec(
"ZonedDateTime utc = ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));" +
"return utc.withZoneSameInstant(ZoneId.of('America/Los_Angeles'));"));
assertEquals("Thu, 13 Oct 1983 15:15:30 -0700", exec(
"String gmtString = 'Thu, 13 Oct 1983 22:15:30 GMT';" +
"ZonedDateTime gmtZdt = ZonedDateTime.parse(gmtString," +
"DateTimeFormatter.RFC_1123_DATE_TIME);" +
"ZonedDateTime pstZdt =" +
"gmtZdt.withZoneSameInstant(ZoneId.of('America/Los_Angeles'));" +
"return pstZdt.format(DateTimeFormatter.RFC_1123_DATE_TIME);"));
}
}