@@ -66,19 +66,19 @@ ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.of('Z'));
66
66
[source,Painless]
67
67
----
68
68
String datetime = '1983-10-13T22:15:30Z';
69
- ZonedDateTime zdt = ZonedDateTime.parse(datetime);
69
+ ZonedDateTime zdt = ZonedDateTime.parse(datetime); <1>
70
70
----
71
- Note the parse method uses ISO 8601 by default.
71
+ <1> Note the parse method uses ISO 8601 by default.
72
72
+
73
73
* parse from RFC 1123
74
74
+
75
75
[source,Painless]
76
76
----
77
77
String datetime = 'Thu, 13 Oct 1983 22:15:30 GMT';
78
78
ZonedDateTime zdt = ZonedDateTime.parse(datetime,
79
- DateTimeFormatter.RFC_1123_DATE_TIME);
79
+ DateTimeFormatter.RFC_1123_DATE_TIME); <1>
80
80
----
81
- Note the use of a built-in DateTimeFormatter.
81
+ <1> Note the use of a built-in DateTimeFormatter.
82
82
+
83
83
* parse from a custom format
84
84
+
@@ -87,9 +87,9 @@ Note the use of a built-in DateTimeFormatter.
87
87
String datetime = 'custom y 1983 m 10 d 13 22:15:30 Z';
88
88
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(
89
89
"'custom' 'y' yyyy 'm' MM 'd' dd HH:mm:ss VV");
90
- ZonedDateTime zdt = ZonedDateTime.parse(datetime, dtf);
90
+ ZonedDateTime zdt = ZonedDateTime.parse(datetime, dtf); <1>
91
91
----
92
- Note the use of a custom DateTimeFormatter.
92
+ <1> Note the use of a custom DateTimeFormatter.
93
93
94
94
===== Datetime Formatting Examples
95
95
@@ -99,9 +99,9 @@ Note the use of a custom DateTimeFormatter.
99
99
----
100
100
ZonedDateTime zdt =
101
101
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));
102
- String datetime = zdt.format(DateTimeFormatter.ISO_INSTANT);
102
+ String datetime = zdt.format(DateTimeFormatter.ISO_INSTANT); <1>
103
103
----
104
- Note the use of a built-in DateTimeFormatter.
104
+ <1> Note the use of a built-in DateTimeFormatter.
105
105
+
106
106
* format to a custom format
107
107
+
@@ -111,9 +111,9 @@ ZonedDateTime zdt =
111
111
ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z'));
112
112
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(
113
113
"'date:' yyyy/MM/dd 'time:' HH:mm:ss");
114
- String datetime = zdt.format(dtf);
114
+ String datetime = zdt.format(dtf); <1>
115
115
----
116
- Note the use of a custom DateTimeFormatter.
116
+ <1> Note the use of a custom DateTimeFormatter.
117
117
118
118
==== Datetime Conversion
119
119
@@ -238,7 +238,7 @@ complex datetimes there is often a method or another complex type
238
238
<<painless-api-reference-shared-ChronoUnit, ChronoUnit>>
239
239
to calculate the difference between two complex datetimes if supported.
240
240
241
- ===== Elapsed Time Examples
241
+ ===== Datetime Difference Examples
242
242
243
243
* Difference in milliseconds between two numeric datetimes
244
244
+
@@ -334,3 +334,236 @@ if (zdt1.isAfter(zdt2)) {
334
334
// handle condition
335
335
}
336
336
----
337
+
338
+ ==== Datetime Input
339
+
340
+ There are several common ways datetimes are used as input for a script
341
+ determined by the <<painless-contexts, Painless context>>. Typically, datetime
342
+ input will be accessed from parameters specified by the user, from an original
343
+ source document, or from an indexed document.
344
+
345
+ ===== Datetime Input From User Parameters
346
+
347
+ Use the {ref}/modules-scripting-using.html#_script_parameters[params section]
348
+ during script specification to pass in a numeric datetime or string datetime as
349
+ a script input. Access to user-defined parameters within a script is dependent
350
+ on the Painless context, though, the parameters are most commonly accessible
351
+ through an input called `params`.
352
+
353
+ *Examples*
354
+
355
+ * Parse a numeric datetime from user parameters to a complex datetime
356
+ +
357
+ ** Input:
358
+ +
359
+ [source,JSON]
360
+ ----
361
+ ...
362
+ "script": {
363
+ ...
364
+ "params": {
365
+ "input_datetime": 434931327000
366
+ }
367
+ }
368
+ ...
369
+ ----
370
+ +
371
+ ** Script:
372
+ +
373
+ [source,Painless]
374
+ ----
375
+ long inputDatetime = params['input_datetime'];
376
+ Instant instant = Instant.ofEpochMilli(inputDateTime);
377
+ ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.of('Z'));
378
+ ----
379
+ +
380
+ * Parse a string datetime from user parameters to a complex datetime
381
+ +
382
+ ** Input:
383
+ +
384
+ [source,JSON]
385
+ ----
386
+ ...
387
+ "script": {
388
+ ...
389
+ "params": {
390
+ "input_datetime": "custom y 1983 m 10 d 13 22:15:30 Z"
391
+ }
392
+ }
393
+ ...
394
+ ----
395
+ +
396
+ ** Script:
397
+ +
398
+ [source,Painless]
399
+ ----
400
+ String datetime = params['input_datetime'];
401
+ DateTimeFormatter dtf = DateTimeFormatter.ofPattern(
402
+ "'custom' 'y' yyyy 'm' MM 'd' dd HH:mm:ss VV");
403
+ ZonedDateTime zdt = ZonedDateTime.parse(datetime, dtf); <1>
404
+ ----
405
+ <1> Note the use of a custom DateTimeFormatter.
406
+
407
+ ===== Datetime Input From a Source Document
408
+
409
+ Use an original {ref}/mapping-source-field.html[source] document as a script
410
+ input to access a numeric datetime or string datetime for a specific field
411
+ within that document. Access to an original source document within a script is
412
+ dependent on the Painless context and is not always available. An original
413
+ source document is most commonly accessible through an input called
414
+ `ctx['_source']` or `params['_source']`.
415
+
416
+ *Examples*
417
+
418
+ * Parse a numeric datetime from a sourced document to a complex datetime
419
+ +
420
+ ** Input:
421
+ +
422
+ [source,JSON]
423
+ ----
424
+ {
425
+ ...
426
+ "input_datetime": 434931327000
427
+ ...
428
+ }
429
+ ----
430
+ +
431
+ ** Script:
432
+ +
433
+ [source,Painless]
434
+ ----
435
+ long inputDatetime = ctx['_source']['input_datetime']; <1>
436
+ Instant instant = Instant.ofEpochMilli(inputDateTime);
437
+ ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.of('Z'));
438
+ ----
439
+ <1> Note access to `_source` is dependent on the Painless context.
440
+ +
441
+ * Parse a string datetime from a sourced document to a complex datetime
442
+ +
443
+ ** Input:
444
+ +
445
+ [source,JSON]
446
+ ----
447
+ {
448
+ ...
449
+ "input_datetime": "1983-10-13T22:15:30Z"
450
+ ...
451
+ }
452
+ ----
453
+ +
454
+ ** Script:
455
+ +
456
+ [source,Painless]
457
+ ----
458
+ String datetime = params['_source']['input_datetime']; <1>
459
+ ZonedDateTime zdt = ZonedDateTime.parse(datetime); <2>
460
+ ----
461
+ <1> Note access to `_source` is dependent on the Painless context.
462
+ <2> Note the parse method uses ISO 8601 by default.
463
+
464
+ ===== Datetime Input From an Indexed Document
465
+
466
+ Use an indexed document as a script input to access a complex datetime for a
467
+ specific field within that document where the field is mapped as a
468
+ {ref}/date.html[standard date] or a {ref}/date_nanos.html[nanosecond date].
469
+ Numeric datetime fields mapped as {ref}/number.html[numeric] and string
470
+ datetime fields mapped as {ref}/keyword.html[keyword] are accessible through an
471
+ indexed document as well. Access to an indexed document within a script is
472
+ dependent on the Painless context and is not always available. An indexed
473
+ document is most commonly accessible through an input called `doc`.
474
+
475
+ *Examples*
476
+
477
+ * Format a complex datetime from an indexed document to a string datetime
478
+ +
479
+ ** Assumptions:
480
+ +
481
+ *** The field `input_datetime` exists in all indexes as part of the query
482
+ *** All indexed documents contain the field `input_datetime`
483
+ +
484
+ ** Mappings:
485
+ +
486
+ [source,JSON]
487
+ ----
488
+ {
489
+ "mappings": {
490
+ ...
491
+ "properties": {
492
+ ...
493
+ "input_datetime": {
494
+ "type": "date"
495
+ }
496
+ ...
497
+ }
498
+ ...
499
+ }
500
+ }
501
+ ----
502
+ +
503
+ ** Script:
504
+ +
505
+ [source,Painless]
506
+ ----
507
+ def input = doc['input_datetime'].value;
508
+ String output = input.format(DateTimeFormatter.ISO_INSTANT); <1>
509
+ ----
510
+ <1> Note the use of a built-in DateTimeFormatter.
511
+ +
512
+ * Find the difference between two complex datetimes from an indexed document
513
+ +
514
+ ** Assumptions:
515
+ +
516
+ *** The fields `start_datetime` and `end_datetime` may *not* exist in all
517
+ indexes as part of the query
518
+ *** The fields `start_datetime` and `end_datetime` may *not* have values in all
519
+ indexed documents
520
+ +
521
+ ** Mappings:
522
+ +
523
+ [source,JSON]
524
+ ----
525
+ {
526
+ "mappings": {
527
+ ...
528
+ "properties": {
529
+ ...
530
+ "start_datetime": {
531
+ "type": "date"
532
+ },
533
+ "end_datetime": {
534
+ "type": "date"
535
+ }
536
+ ...
537
+ }
538
+ ...
539
+ }
540
+ }
541
+ ----
542
+ +
543
+ ** Script:
544
+ +
545
+ [source,Painless]
546
+ ----
547
+ if (doc.containsKey('start_datetime') && doc.containsKey('end_datetime')) { <1>
548
+
549
+ if (doc['start_datetime'].size() > 0 && doc['end_datetime'].size() > 0) { <2>
550
+
551
+ def startDatetime = doc['start_datetime'].value;
552
+ def endDatetime = doc['end_datetime'].value;
553
+ long differenceInMillis =
554
+ ChronoUnit.MILLIS.between(startDateTime, endDateTime);
555
+
556
+ // handle difference in times
557
+ } else {
558
+ // handle fields without values
559
+ }
560
+ } else {
561
+ // handle index with missing fields
562
+ }
563
+ ----
564
+ <1> When a query's results span multiple indexes, some indexes may not
565
+ contain a specific field. Use the `containsKey` method call on the `doc` input
566
+ to ensure a field exists as part of the index for the current document.
567
+ <2> Some field's within a document may have no values. Use the `size` method
568
+ call on a field within the `doc` input to ensure that field has at least one
569
+ value for the current document.
0 commit comments