我试图在 Elasticsearch 索引映射中指定日期的格式,如本文档所述:https://www.elastic.co/guide/en/elasticsearch/reference/current/date.html
我有一个以下格式的日期:
2020-10-29T05:36:06.143Z[UTC]
。我如何将其转换为像YYYY-MM-DD...
这样的格式?具体来说,最后的[UTC]
部分如何表示?
目前我有以下映射,我收到以下错误,因此我尝试指定日期的格式以查看是否有效。谢谢!
"createdTimeStamp": {
"type": "date"
},
Elasticsearch exception [type=mapper_parsing_exception, reason=failed to parse field [createdTimeStamp] of type [date] in document with id 'testId1'.
Preview of field's value: '{offset={totalSeconds=0, rules={fixedOffset=true, transitionRules=[], transitions=[]}, id=Z}, year=2015, dayOfYear=1, nano=0, chronology={calendarType=iso8601, id=ISO}, minute=10, second=30, dayOfWeek=THURSDAY, month=JANUARY, hour=12, zone={totalSeconds=0, rules={fixedOffset=true, transitionRules=[], transitions=[]}, id=Z}, dayOfMonth=1, monthValue=1}']];
nested: ElasticsearchException[Elasticsearch exception [type=illegal_state_exception, reason=Can't get text on a START_OBJECT at 1:72]]
我没有 Elasticsearch 方面的专业知识。但是,以下解决方案应该可以帮助您解决问题。
您可以提及格式,
uuuu-MM-dd'T'HH:mm:ss.SSSX['['z']']
,如文档页面上的示例所示。
演示:
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String strDateTime = "2020-10-29T05:36:06.143Z[UTC]";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX['['z']']");
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, formatter);
System.out.println(zdt);
OffsetDateTime odt = OffsetDateTime.parse(strDateTime, formatter);
System.out.println(odt);
}
}
输出:
2020-10-29T05:36:06.143Z[UTC]
2020-10-29T05:36:06.143Z
格式末尾的
['['z']']
使 '['z']'
可选,其中 [
和 ]
是文字,而 z
指定时区。
您的日期时间字符串末尾有
Z[UTC]
,其中 Z
是一个重要的字母,指定 Zulu
日期时间,它只不过是 UTC
日期时间。换句话说,您的日期时间代表 UTC
中的日期时间。 ZonedDateTime
可以解析它,而不需要任何格式化程序。
演示:
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
String strDateTime = "2020-10-29T05:36:06.143Z[UTC]";
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime);
System.out.println(zdt);
}
}
输出:
2020-10-29T05:36:06.143Z[UTC]
但是,Elasticsearch 似乎不使用
ZonedDateTime
来解析日期时间字符串。 文档页面提到默认格式是strict_date_optional_time
或epoch_millis
,如下引用:
日期格式可以自定义,但如果没有指定格式则 使用默认值:
“严格日期可选时间||epoch_millis”
因此,为了符合默认格式,另一种方法是从日期时间字符串末尾删除
[UTC]
。进行此更改后,该字符串可以由所有 ZonedDateTime
、OffsetDateTime
和 Instant
进行解析,而无需任何格式化程序。
演示:
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
String strDateTime = "2020-10-29T05:36:06.143Z[UTC]";
strDateTime = strDateTime.substring(0, strDateTime.indexOf('['));
System.out.println("Trimmed date-time string: " + strDateTime);
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime);
System.out.println(zdt);
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
System.out.println(odt);
Instant instant = Instant.parse(strDateTime);
System.out.println(instant);
}
}
输出:
Trimmed date-time string: 2020-10-29T05:36:06.143Z
2020-10-29T05:36:06.143Z
2020-10-29T05:36:06.143Z
2020-10-29T05:36:06.143Z
您首先需要转义
Z
本身——它是一个 代表区域偏移量 的符号,本身并不是一个有效值。
PUT myindex/
{
"mappings": {
"properties": {
"createdTimeStamp": {
"type": "date",
"format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z[UTC]'"
}
}
}
}
如果您确定所有传入值都将采用 UTC 格式,则可以按原样保留上述内容。这也会逃脱那个
[UTC]
部分。
如果您期望多个时区,则可以使用
yyyy-MM-dd'T'HH:mm:ss.SSS'Z['z']'
代替 - 小写的 z
将为您解析传入的时区,并在内部以 UTC 形式存储日期,但带有偏移量。这样,由于上述原因,您只会转义大写字母 Z
。