ZonedDateTime 格式 - Elasticsearch 索引映射

问题描述 投票:0回答:2

我试图在 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]]
datetime elasticsearch mapping zoneddatetime datetimeformatter
2个回答
1
投票

我没有 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

1
投票

您首先需要转义

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

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.