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 (<<reference-types, object>>) that abstracts away internal details of how the
datetime is stored and often provides utilities for modification and datetime is stored and often provides utilities for modification and
comparison; in Painless this is typically a 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 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 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 ==== Datetime Input
There are several common ways datetimes are used as input for a script 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: ** Assumptions:
+ +
*** The fields `start_datetime` and `end_datetime` may *not* exist in all *** The fields `start` and `end` may *not* exist in all indexes as part of the
indexes as part of the query query
*** The fields `start_datetime` and `end_datetime` may *not* have values in all *** The fields `start` and `end` may *not* have values in all indexed documents
indexed documents
+ +
** Mappings: ** Mappings:
+ +
@ -527,10 +563,10 @@ indexed documents
... ...
"properties": { "properties": {
... ...
"start_datetime": { "start": {
"type": "date" "type": "date"
}, },
"end_datetime": { "end": {
"type": "date" "type": "date"
} }
... ...
@ -544,14 +580,13 @@ indexed documents
+ +
[source,Painless] [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 start = doc['start'].value;
def endDatetime = doc['end_datetime'].value; def end = doc['end'].value;
long differenceInMillis = long differenceInMillis = ChronoUnit.MILLIS.between(start, end);
ChronoUnit.MILLIS.between(startDateTime, endDateTime);
// handle difference in times // handle difference in times
} else { } else {

View File

@ -22,7 +22,7 @@ package org.elasticsearch.painless;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
public class DateTests extends ScriptTestCase { public class DateTimeTests extends ScriptTestCase {
public void testLongToZonedDateTime() { public void testLongToZonedDateTime() {
assertEquals(ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of("Z")), exec( 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);" "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);"));
}
} }