zoneddatetime格式-elasticsearch索引Map

frebpwbc  于 2021-06-10  发布在  ElasticSearch
关注(0)|答案(2)|浏览(352)

我试图在elasticsearch索引Map中指定日期的格式,如以下文档所述:https://www.elastic.co/guide/en/elasticsearch/reference/current/date.html
我有这样一个日期: 2020-10-29T05:36:06.143Z[UTC] . 我该如何把它转换成这样的格式 YYYY-MM-DD... ? 具体来说,如何表示 [UTC] 最后的部分?
目前我有下面的Map,我得到下面的错误,所以我试图指定日期的格式,看看是否有效。谢谢!

"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]]
oogrdqng

oogrdqng1#

你得先逃走 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 出于上述原因。

zengzsys

zengzsys2#

我没有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 如下所述:
可以自定义日期格式,但如果未指定格式,则使用默认格式:
“严格的|日期|可选|时间|历元|毫秒”
因此,为了符合默认格式,另一种方法是去掉 [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

相关问题