Elasticsearch范围查询抛出Illegal pattern component: p异常求助
解决Joda DateTime解析Elasticsearch Date字段时的IllegalArgumentException问题
问题分析
你遇到的java.lang.IllegalArgumentException: Illegal pattern component: p错误,核心原因是你指定的日期模式和Elasticsearch返回的ts字符串格式不匹配,或者模式本身存在拼写错误。
从你给出的信息来看:
- Elasticsearch的
ts字段格式是strict_date_optional_time||epoch_millis,这意味着它会返回符合ISO标准的日期字符串(比如2024-05-20T12:34:56.789Z)或者时间戳数字。 - 你用的解析模式是
yyyy-MM-dd'T'HH:mm:ss.SSSZ,但错误提示里的"Illegal pattern component: p"说明解析时遇到了模式不识别的p字符——要么是你实际写的模式里不小心混入了p(比如把SSS写成SpS),要么是Elasticsearch返回的ts字符串包含了AM/PM标识(比如下午的p),而你的模式没有对应处理。
解决方案
1. 先确认实际的ts字符串格式
在解析前先打印出ts的实际值,明确要处理的格式:
val tsStr = source.get("ts").get.asInstanceOf[String] println("实际ts字符串:" + tsStr)
这一步能帮你快速定位是模式错了还是字符串格式超出预期。
2. 使用Joda内置的ISO格式器(推荐)
既然Elasticsearch返回的是符合strict_date_optional_time的ISO格式,直接用Joda内置的ISO解析器,不用手动写模式,避免匹配错误:
import org.joda.time.DateTime import org.joda.time.format.ISODateTimeFormat val tsStr = source.get("ts").get.asInstanceOf[String] val dateTime = DateTime.parse(tsStr, ISODateTimeFormat.dateTime())
这个格式器支持所有strict_date_optional_time包含的子格式,包括带时区偏移、带毫秒、不带时间的纯日期等场景。
3. 手动修正模式(如果必须自定义)
如果确实需要手动写模式:
- 如果
ts字符串是UTC标识的格式(比如2024-05-20T12:34:56.789Z),要把Z作为字面量用单引号括起来:val formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") val dateTime = DateTime.parse(tsStr, formatter) - 如果
ts字符串是带时区偏移的格式(比如2024-05-20T12:34:56.789+0800),原模式yyyy-MM-dd'T'HH:mm:ss.SSSZ是正确的,这时候要检查模式是否有拼写错误(比如不小心写了p)。
4. 处理epoch_millis场景
如果Elasticsearch返回的ts是数字类型的时间戳(比如1522871220000),可以直接用DateTime的构造函数:
val tsLong = source.get("ts").get.asInstanceOf[Long] val dateTime = new DateTime(tsLong)
内容的提问来源于stack exchange,提问作者nocturnal
相关产品推荐
相关产品推荐

