1010import org .elasticsearch .xcontent .XContentParser ;
1111
1212import java .io .IOException ;
13+ import java .time .DateTimeException ;
14+ import java .time .ZoneId ;
1315import java .util .HashMap ;
1416import java .util .Map ;
1517import java .util .Set ;
18+ import java .util .TimeZone ;
1619
1720public class ScheduleRegistry {
1821 private final Map <String , Schedule .Parser <? extends Schedule >> parsers = new HashMap <>();
@@ -29,9 +32,15 @@ public Schedule parse(String context, XContentParser parser) throws IOException
2932 String type = null ;
3033 XContentParser .Token token ;
3134 Schedule schedule = null ;
35+ TimeZone timeZone = null ; // Default to UTC
3236 while ((token = parser .nextToken ()) != XContentParser .Token .END_OBJECT ) {
3337 if (token == XContentParser .Token .FIELD_NAME ) {
34- type = parser .currentName ();
38+ var fieldName = parser .currentName ();
39+ if (fieldName .equals (ScheduleTrigger .TIMEZONE_FIELD )) {
40+ timeZone = parseTimezone (parser );
41+ } else {
42+ type = parser .currentName ();
43+ }
3544 } else if (type != null ) {
3645 schedule = parse (context , type , parser );
3746 } else {
@@ -44,9 +53,38 @@ public Schedule parse(String context, XContentParser parser) throws IOException
4453 if (schedule == null ) {
4554 throw new ElasticsearchParseException ("could not parse schedule. expected a schedule type field, but no fields were found" );
4655 }
56+
57+ if (timeZone != null && schedule instanceof CronnableSchedule cronnableSchedule ) {
58+ cronnableSchedule .setTimeZone (timeZone );
59+ } else if (timeZone != null ) {
60+ throw new ElasticsearchParseException (
61+ "could not parse schedule. Timezone is not supported for schedule type [{}]" ,
62+ schedule .type ()
63+ );
64+ }
65+
4766 return schedule ;
4867 }
4968
69+ private static TimeZone parseTimezone (XContentParser parser ) throws IOException {
70+ TimeZone timeZone ;
71+ XContentParser .Token token = parser .nextToken ();
72+ if (token == XContentParser .Token .VALUE_STRING ) {
73+ String text = parser .text ();
74+ try {
75+ timeZone = TimeZone .getTimeZone (ZoneId .of (text ));
76+ } catch (DateTimeException e ) {
77+ throw new ElasticsearchParseException ("could not parse schedule. invalid timezone [{}]" , e , text );
78+ }
79+ } else {
80+ throw new ElasticsearchParseException (
81+ "could not parse schedule. expected a string value for timezone, but found [{}] instead" ,
82+ token
83+ );
84+ }
85+ return timeZone ;
86+ }
87+
5088 public Schedule parse (String context , String type , XContentParser parser ) throws IOException {
5189 Schedule .Parser <?> scheduleParser = parsers .get (type );
5290 if (scheduleParser == null ) {
0 commit comments