ES存储Date时间问题

    技术2025-07-22  11

    目录

    时间未设置时区,相差8小时

    存储时间格式化yyyy-MM-dd HH:mm:ss

    ES默认是不支持yyyy-MM-dd HH:mm:ss格式的

    可以创建的时候自定义格式

    总结

    写法一:默认

    写法二:@JsonFormat

    时间未设置时区,相差8小时

    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8") @Field(type = FieldType.Date) private Date expectTime;

    如果在写入数据时不加时区信息,ElasticSearch默认按UTC时区写入,默认是0时区,但是当我们查看的时候,kibana会读取我们当地的时间,即东八区,进行转换,所以我们看到的时间相差8小时。

    解决方案就是在写入前 +8 或者 指定时区

    我们在往es提交日期数据的时候,直接提交带有时区信息的日期字符串,如:“2016-07-15T12:58:17.136+0800”或者timezone="GMT+8"

    时间中时区的几个名词: 

    GMT:格林威治标准时间 UTC:世界协调时间 DST:夏日节约时间 CST:中国标准时间  SimpleDateFormat sdf_8 = new SimpleDateFormat("yyyy-MM-dd HH:mm"); sdf_8.setTimeZone(TimeZone.getTimeZone("GMT0")); System.out.println("GMT0 = " + sdf_8.format(t)); 其它: TimeZone.getTimeZone("GMT+8:00") TimeZone.getTimeZone("America/Los_Angeles") TimeZone.setDefault(TimeZone.getTimeZone("GMT+8")) 修改默认时区

    存储时间格式化yyyy-MM-dd HH:mm:ss

    ES默认是不支持yyyy-MM-dd HH:mm:ss格式的

    官网时间(Date)格式说明

    关于时间类型说明:https://www.elastic.co/guide/en/elasticsearch/reference/current/date.html关于时间类型格式化:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-date-format.html#strict-date-time

    日期字段使用默认格式。此文档使用纯日期该文档包括一个时间。此文档使用纪元后的毫秒数。请注意,sort自纪元以来,返回的所有值均以毫秒为单位

    可以创建的时候自定义格式

    java写法

    // 实体类 @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8") @Field(type = FieldType.Date, format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_second") private Date time; // 创建索引 @Resource private ElasticsearchTemplate template; if (template.indexExists(entity.class)) { template.deleteIndex(entity.class); } template.createIndex(entity.class); template.putMapping(entity.class);

     通过postman查看结构和数据

    epoch_millis:纪元后的毫秒epoch_second:纪元秒

    格式化成功了但是实际上这个字段是Text类型,单纯的用于展示没问题,用来做搜索条件或者间隔查询基本无效

    (网上有说用脚本的,看了下感觉麻烦,Text类型字段相关帖子不多而且也都是很久之前的了,我后来做间隔查询放弃了这种)

    总结

    写法一:默认

    // 实体类 @Field(type = FieldType.Date) private Date createTime; // 如果前端需要yyyy-MM-dd HH:mm:ss格式字符串,需要手动转下 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); sdf.format("dateStr");

    这种默认写法存的是时间戳,存取正常,格式使用时手动转换下就行了

    写法二:@JsonFormat

    // 实体类 @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8") @Field(type = FieldType.Date, format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_second") private Date createTime; // 适合没有搜索条件的纯展示类时间数据,不需要手动转,查出来就是yyyy-MM-dd HH:mm:ss格式 // 使用@JsonFormat注解上述配置不全会运行报错(format)或者时间数据出错(timezone)

     

     


    Processed: 0.011, SQL: 9