<p dir="auto">At the moment, having this in a mapping throws a parsing error:</p>
<p dir="auto">"topic_date" : { "type" : "date", "format": "date_optional_time||yyyy-MM-dd'T'HH:mm" }</p>
<p dir="auto">The following mapping:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="'index': {
    'properties': {
        'date_created': {
            'type': 'date',
            'index': 'not_analyzed',
            'format: 'date_time||date_time_no_millis',
        },
    },
}"><pre class="notranslate"><code class="notranslate">'index': {
    'properties': {
        'date_created': {
            'type': 'date',
            'index': 'not_analyzed',
            'format: 'date_time||date_time_no_millis',
        },
    },
}
</code></pre></div>
<p dir="auto">Gives an error:</p>
<p dir="auto"><code class="notranslate">ElasticSearchException[Illegal pattern component: t]; nested: IllegalArgumentException[Illegal pattern component: t];</code></p>
<p dir="auto">I tried patching as follows, however didn't manage to get it working since <code class="notranslate">forPattern</code> wasn't called as expected:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="diff --git a/src/main/java/org/elasticsearch/common/joda/Joda.java b/src/main/java/org/elasticsearch/common/joda/Joda.java
index a4f3427..e8d6e53 100644
--- a/src/main/java/org/elasticsearch/common/joda/Joda.java
+++ b/src/main/java/org/elasticsearch/common/joda/Joda.java
@@ -31,11 +31,11 @@ import org.joda.time.format.*;
  */
 public class Joda {

-    /**
-     * Parses a joda based pattern, including some named ones (similar to the built in Joda ISO ones).
-     */
-    public static FormatDateTimeFormatter forPattern(String input) {
+    private  static DateTimeFormatter formatterForPattern(String input) {
         DateTimeFormatter formatter;
         if (&quot;basicDate&quot;.equals(input) || &quot;basic_date&quot;.equals(input)) {
             formatter = ISODateTimeFormat.basicDate();
         } else if (&quot;basicDateTime&quot;.equals(input) || &quot;basic_date_time&quot;.equals(input)) {
@@ -76,9 +76,10 @@ public class Joda {
             formatter = ISODateTimeFormat.dateHourMinuteSecondMillis();
         } else if (&quot;dateOptionalTime&quot;.equals(input) || &quot;date_optional_time&quot;.equals(input)) {
             // in this case, we have a separate parser and printer since the dataOptionalTimeParser can't print
-            return new FormatDateTimeFormatter(input,
-                    ISODateTimeFormat.dateOptionalTimeParser().withZone(DateTimeZone.UTC),
-                    ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC));
+            DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
+                    .append(ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC).getPrinter(),
+                            ISODateTimeFormat.dateOptionalTimeParser().withZone(DateTimeZone.UTC).getParser());
+            formatter = builder.toFormatter();
         } else if (&quot;dateTime&quot;.equals(input) || &quot;date_time&quot;.equals(input)) {
             formatter = ISODateTimeFormat.dateTime();
         } else if (&quot;dateTimeNoMillis&quot;.equals(input) || &quot;date_time_no_millis&quot;.equals(input)) {
@@ -125,14 +126,27 @@ public class Joda {
                 formatter = DateTimeFormat.forPattern(input);
             } else {
                 DateTimeParser[] parsers = new DateTimeParser[formats.length];
+                DateTimePrinter printer = null;
                 for (int i = 0; i &lt; formats.length; i++) {
-                    parsers[i] = DateTimeFormat.forPattern(formats[i]).withZone(DateTimeZone.UTC).getParser();
+                    DateTimeFormatter f = formatterForPattern(formats[i]);
+                    parsers[i] = f.getParser();
+                    if (i == 0) {
+                        printer = f.getPrinter();
+                    }
                 }
                 DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
-                        .append(DateTimeFormat.forPattern(formats[0]).withZone(DateTimeZone.UTC).getPrinter(), parsers);
+                        .append(printer, parsers);
                 formatter = builder.toFormatter();
             }
         }
+        return formatter;
+    }
+
+    /**
+     * Parses a joda based pattern, including some named ones (similar to the built in Joda ISO ones).
+     */
+    public static FormatDateTimeFormatter forPattern(String input) {
+        DateTimeFormatter formatter = formatterForPattern(input);
         return new FormatDateTimeFormatter(input, formatter.withZone(DateTimeZone.UTC));
     }"><pre class="notranslate"><code class="notranslate">diff --git a/src/main/java/org/elasticsearch/common/joda/Joda.java b/src/main/java/org/elasticsearch/common/joda/Joda.java
index a4f3427..e8d6e53 100644
--- a/src/main/java/org/elasticsearch/common/joda/Joda.java
+++ b/src/main/java/org/elasticsearch/common/joda/Joda.java
@@ -31,11 +31,11 @@ import org.joda.time.format.*;
  */
 public class Joda {

-    /**
-     * Parses a joda based pattern, including some named ones (similar to the built in Joda ISO ones).
-     */
-    public static FormatDateTimeFormatter forPattern(String input) {
+    private  static DateTimeFormatter formatterForPattern(String input) {
         DateTimeFormatter formatter;
         if ("basicDate".equals(input) || "basic_date".equals(input)) {
             formatter = ISODateTimeFormat.basicDate();
         } else if ("basicDateTime".equals(input) || "basic_date_time".equals(input)) {
@@ -76,9 +76,10 @@ public class Joda {
             formatter = ISODateTimeFormat.dateHourMinuteSecondMillis();
         } else if ("dateOptionalTime".equals(input) || "date_optional_time".equals(input)) {
             // in this case, we have a separate parser and printer since the dataOptionalTimeParser can't print
-            return new FormatDateTimeFormatter(input,
-                    ISODateTimeFormat.dateOptionalTimeParser().withZone(DateTimeZone.UTC),
-                    ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC));
+            DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
+                    .append(ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC).getPrinter(),
+                            ISODateTimeFormat.dateOptionalTimeParser().withZone(DateTimeZone.UTC).getParser());
+            formatter = builder.toFormatter();
         } else if ("dateTime".equals(input) || "date_time".equals(input)) {
             formatter = ISODateTimeFormat.dateTime();
         } else if ("dateTimeNoMillis".equals(input) || "date_time_no_millis".equals(input)) {
@@ -125,14 +126,27 @@ public class Joda {
                 formatter = DateTimeFormat.forPattern(input);
             } else {
                 DateTimeParser[] parsers = new DateTimeParser[formats.length];
+                DateTimePrinter printer = null;
                 for (int i = 0; i &lt; formats.length; i++) {
-                    parsers[i] = DateTimeFormat.forPattern(formats[i]).withZone(DateTimeZone.UTC).getParser();
+                    DateTimeFormatter f = formatterForPattern(formats[i]);
+                    parsers[i] = f.getParser();
+                    if (i == 0) {
+                        printer = f.getPrinter();
+                    }
                 }
                 DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
-                        .append(DateTimeFormat.forPattern(formats[0]).withZone(DateTimeZone.UTC).getPrinter(), parsers);
+                        .append(printer, parsers);
                 formatter = builder.toFormatter();
             }
         }
+        return formatter;
+    }
+
+    /**
+     * Parses a joda based pattern, including some named ones (similar to the built in Joda ISO ones).
+     */
+    public static FormatDateTimeFormatter forPattern(String input) {
+        DateTimeFormatter formatter = formatterForPattern(input);
         return new FormatDateTimeFormatter(input, formatter.withZone(DateTimeZone.UTC));
     }
</code></pre></div>
<p dir="auto">I'm happy to submit a full patch to make it work, but need a hint on where this exception is actually triggered.</p>