ES存储Date时间问题

目录

时间未设置时区,相差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

  1. 日期字段使用默认格式。
  2. 此文档使用纯日期
  3. 该文档包括一个时间。
  4. 此文档使用纪元后的毫秒数。
  5. 请注意,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)

补一个ES时间格式转yyyy-MM-dd HH:mm:ss格式字符串的方法

    /**
     * ES时间转为yyyy-MM-dd HH:mm:ss格式字符串
     */
    public static String esDateToString(Date esDate) {
        SimpleDateFormat sdf = new SimpleDateFormat ("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK);
        SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parse = null;
        try {
            parse = sdf.parse(esDate.toString());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return df2.format(parse);
    }

测试:

 


  • 10
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑶山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值