【问题标题】:ZonedDateTime format- Elasticsearch index mappingZonedDateTime 格式 - Elasticsearch 索引映射
【发布时间】:2020-11-24 00:02:43
【问题描述】:

我正在尝试在我的 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


    【解决方案1】:

    我没有 Elasticsearch 方面的专业知识。但是,以下解决方案应该可以帮助您解决问题。

    您可以提及uuuu-MM-dd'T'HH:mm:ss.SSSX['['z']'] 的格式,如documentation page 上的示例所示。

    演示:

    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']' optional 其中[] 是文字,而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 来解析日期时间字符串。 documentation page 提到默认格式是 strict_date_optional_timeepoch_millis,如下所示:

    可以自定义日期格式,但如果没有指定格式,则 使用默认值:

    “strict_date_optional_time||epoch_millis”

    因此,为了符合默认格式,另一种方法是从日期时间字符串的末尾删除[UTC]。更改后,ZonedDateTimeOffsetDateTimeInstant 都可以解析字符串,而无需任何格式化程序。

    演示:

    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
    

    【讨论】:

      【解决方案2】:

      您首先需要对Z 本身进行转义——它是represents zone offsets 的符号,本身不是有效值。

      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

      【讨论】:

        猜你喜欢
        • 2017-03-11
        • 2020-09-23
        • 2021-03-23
        • 1970-01-01
        • 2015-12-04
        • 2015-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多