ElasticSearch里面关于日期的存储方式,解决差8个小时

elasticsearch时间柱状图聚合java实现 需求:统计每天有多少条数据,以及某字段的平均值。 1. 使用DateHistogramAggregationBuilder按天统计,再嵌入aggs取平均值。 如果要对结果进行排序,在 AggregationBuilders 加上 .order(Histogram.Order.COUNT_DESC) AvgAggregationBuilder avgAggregationBuild... 阅读详情
AI摘要

本文讲解ElasticSearch中时间字段的处理方式,包括时区差异、时间格式化、日期聚合查询等关键操作,并提供Java代码示例。

在ElasticSearch里面最常用的就是时间字段了,经常会在群里看到一些小伙伴提出有关时间的问题,为什么es查询的时间跟我实际看到的时间差8个小时呢。如果我们了解了ElasticSearch底层的时间存储方式就会比较容易的理解这个问题。 

下面散仙先普及下时区的知识,想必大家也不陌生学过地理的同学都知道全球有24个时区每个时区的跨度是经度15度, 


相较于两地时间表,可以显示世界各时区时间和地名的世界时区表(World Time),就显得精密与复杂多了,通常世界时区表的表盘上会标示着全球24个时区的城市名称,但究竟这24个时区是如何产生的?过去世界各地原本各自订定当地时间,但随着交通和电讯的发达,各地交流日益频繁,不同的地方时间,造成许多困扰,于是在西元1884年的国际会议上制定了全球性的标准时,明定以英国伦敦格林威治这个地方为零度经线的起点(亦称为本初子午线),并以地球由西向东每24小时自转一周360°,订定每隔经度15°,时差1小时。而每15°的经线则称为该时区的中央经线,将全球划分为24个时区,其中包含23个整时区及180°经线左右两侧的2个半时区 
就全球的时间来看,东经的时间比西经要早,也就是如果格林威治时间是中午12时,则中央经线15°E的时区为下午1时,中央经线30°E时区的时间为下午2时;反之,中央经线15°W的时区时间为上午11时,中央经线30°W时区的时间为上午10时。以台湾为例,台湾位于东经121°,换算后与格林威治就有8小时的时差。如果两人同时从格林威治的0°各往东、西方前进,当他们在经线180°时,就会相差24小时,所以经线180°被定为国际换日线,由西向东通过此线时日期要减去一日,反之,若由东向西则要增加一日。 


几个时间名词: 
  1. GMT:格林威治标准时间 
  2. UTC:世界协调时间 
  3. DST:夏日节约时间 
  4. CST:中国标准时间 
其中GMT时间可以近似认为和UTC时间是相等的,但从精度上来说UTC时间更精确。其误差值必须保持在0.9秒以内 

CST= GMT + 8 =UTC + 8 

从上面可以看出来中国的时间是等于UTC时间+8小时,es默认存储时间的格式是UTC时间,如果我们查询es然后获取时间日期默认的数据,会发现跟当前的时间差8个小时,这其实是正常的,因为es默认存储是用的UTC时间,所以我们需要做的就是读取long型时间戳,然后重新格式化成下面的时间戳,即可获得正确的时间 :

yyyy-MM-dd HH:mm:ss 
像差8个时区的事情,最容易见到的就是,我们使用logstash收集的日志,发送到es里面,然后通过head查询就能发现不一致,但是如果我们用kibana查询,就不会发现时区问题,为什么? 因为kibana已经处理时区问题了,所以在kibana的页面显示的时间是正确的。 

此外在使用Java Client聚合查询日期的时候,需要注意时区问题,因为默认的es是按照UTC标准时区算的,所以不设置的聚合统计结果是不正确的。 

在es的DateHistogramBuilder里面有几个比较重要的参数:

field:指定按那个字段聚合  
interval:聚合的时间单位(年,季度,月,周,天,小时,分钟,秒)  
format:日期格式  
time_zone:时区指定  
offset:时间偏移量  

注意,默认不设置时区参数,es是安装UTC的时间进行查询的,所以分组的结果可能与预期不一样,所以我们要指定时区为Asia/Shanghai代表北京的时区,这样才能获取正确的聚合结果 

curl方式如下: 

GET my_index/_search?size=0  
{  
  "aggs": {  
    "by_day": {  
      "date_histogram": {  
        "field":     "ctime",  
        "interval":  "day",  
        "time_zone": "Asia/Shanghai"  
      }  
    }  
  }  
}  

Java代码如下: 

SearchRequestBuilder search = client.prepareSearch("search2017-02*").setTypes("log");  
DateHistogramBuilder dateagg = AggregationBuilders.dateHistogram("dateagg");  
dateagg.field("ctime");//聚合时间字段  
dateagg.interval(DateHistogramInterval.DAY);//按天聚合第一天的0点到第二天的0点  
dateagg.timeZone("Asia/Shanghai");//指定时区  
dateagg.offset("+8h");//默认都是从0点开始计算一天的,通过这个offset,我们可以把第一天的6点到第二天的6点当做一天来聚合  
search.addAggregation(dateagg);  

Histogram hs= search.get().getAggregations().get("dateagg");  
List<Histogram.Bucket> buckets =   (List<Histogram.Bucket>) hs.getBuckets();//获取结果  
for(Histogram.Bucket bk:buckets){  
//下面的转化,也是因为默认是UTC的时间,所以我们要获取时间戳,自己转化  
    System.out.println(new DateTime(Long.parseLong(bk.getKeyAsString()+"")).toString("yyyy-MM-dd HH:mm:ss") +"  "+bk.getDocCount());  
}  
client.close();  
上面的这个例子,基本涵盖了日期聚合核心功能,其中时区和偏移量时两个非常有用的而且需要特别注意的参数,不设置时区直接统计结果肯定是不准确的,offset偏移量这个参数,在某些时刻也是有用的,它可以自己定义一天的开始,比如设置从第一天的3点到第二天的3点为一天,默认都是从0点开始0点结束算做一天的,最后一点需要注意的是在输出打印时间的时候也要考虑转化因为默认也是UTC的时间,所以我们直接取出时间戳,自己格式化时间即可。 

官网文档: 

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html  
ES 中时间日期类型 “yyyy-MM-dd HHmmss” 的完全避坑指南 假如我们有如下索引tax,保存了一些公司的纳税或资产信息,单位为“万元”。当然这里面的数据是随意填写的。多少为数据统计的时间,当前这个例子里。索引达的含义并不重要。关键点在于字段的内容格式。我们看到date字段其中包含了多种日期的格式“yyyy-MM-dd”,“yyyy-MM-dd”还有时间戳。如果按照dynamicmapping,采取自动映射器来映射索引。我们自然而然的都会感觉字段应该是一个date类型。{"index"{}}{"date"01"中国烟草","ratal"5700000}... 阅读详情

相关推荐

mongo-日期类型/日期查询/时间查询/UTC + 8h = 北京时间new Date/ISODate

mongo-日期类型(2) 时间格式2020-01-13T16:00:00.000Z中的T和Z T表示分隔符,Z表示的是UTC。 UTC:世界标准时间,在标准时间上加上8小时,即东八区时间,也就是北京时间。 举例 北京时间:2020-01-14 00:00:00对应的国际标准时间格式为:2020-01-13T16:00:00.000Z 1、当通过mongo shell来插入日期类型数据时,使用new Date()和使用Date()是不一样的: 2、我们看:使用new Date(),插入的是.

火星男孩的分享空间 8542

ElasticSearch里面关于日期的存储方式

在ElasticSearch里面最常用的就是时间字段了,经常会在群里看到一些小伙伴提出有关时间的问题,为什么es查询的时间跟我实际看到的时间差8个小时呢。如果我们了解了ElasticSearch底层的时间存储方式就会比较容易的理解这个问题。 下面散仙先普及下时区的知识,想必大家也不陌生学过地理的同学都知道全球有24个时区每个时区的跨度是经度15度, 相较于两地时间表,可以显示世界各时区

三劫散仙 1万+

海康SDK回调PS流解析实战:从字节流到前端H264播放的完整流程

本文详细介绍了海康SDK回调PS流解析的完整流程,从字节流获取到前端H264播放的实现。涵盖SDK初始化、PS流数据结构解析、H264裸流提取、WebSocket传输及前端播放器集成等关键步骤,为视频监控系统开发提供实用指导。

weixin_29061531的博客 200

ES存储Date时间问题

时间未设置时区,相差8小时 存储时间格式化yyyy-MM-dd HH:mm:ss 自定义格式 写法总结 写法一:默认 写法二:@JsonFormat 有的文章时间太久不能用,有的不给写法,差评!

瑶山的博客 1万+

Windows环境下如何通过MCP Server实现MySQL安全连接与AI集成?

本文详细介绍了在Windows环境下如何通过MCP Server实现MySQL安全连接与AI集成。MCP Server作为大模型与MySQL之间的安全通道,提供权限控制、SSL加密和协议转换功能,显著提升查询性能。文章包含环境配置、安装指南、安全策略及实战案例,帮助开发者高效实现AI与数据库的安全交互。

hill8的博客 720

【codex教程】Codex 注册和使用教程(2026最新版)

Codex 是 OpenAI 推出的 AI 编程助手,可以帮助开发者阅读代码、修改代码、运行命令、生成测试、排查 bug、做代码审查,也可以在终端、IDE、Codex App 或网页端使用。根据 OpenAI 帮助中心,截至 2026 年 6 月,Codex 已包含在 Free、Go、Plus、Pro、Business、Edu 和 Enterprise 等 ChatGPT 方案中,但不同套餐的使用额度会有所不同。适合开发者在终端中使用。如果你想在命令行里使用 Codex,可以安装 Codex CLI。

与时俱进,开放共享 2万+

Elasticsearch中的date与时区问题

1 前言 本文主要讲解Elasticsearch中date类型数据的底层存储原理,以及对带时区日期字符串和不带时区的日期字符串如何在ES底层存储进行验证。对于直接存储Long类型时间戳,不作过多描述。 1.1 Date类型数据的存储 UTC(Universal Time Coordinated) 叫做世界统一时间,中国大陆所用的时间是东8区时间,比UTC时间超前8小时。即与 UTC 的时差是 +8 ,也就是 UTC+8。 在Elasticsearch内部,不论 date 是什么展示格式,所有date类型数据

不见其长,日有所长 1万+

使用STM输出互补SPWM波(三相各差120°)

使用STM32输出SPWM波形(三相各差120°)

hello011102的博客 7373

elasticsearch 聚合之 date_histogram 聚合

此处来简单学习一下 `elasticsearch` 的 `date_histogram`直方图聚合。它和普通的直方图`histogram`聚合差不多,但是`date_histogram`只可于 `日期或日期范围` 类型的值一起使用。

huan的学习记录 4157

ios生成海报使用dom-to-image中toPng报错isTrusted:true

主要是ios中safari浏览器解析错误,引起的报错,主要引起原因toPng会调用toSvg,toSvg直接将html标签内容通过svg中foreignObject标签直接包裹,然后转base64, 通过data:image/svg+xml;解决办法:二次生成(调用两次),判断ios or 安卓,生成第一次生成,不用参数,例如:scale: 3,在第二次生成再进行清晰度操作,避免多次生成,引起性能消耗。以上种种很多案例,使用canvase进行转换的,标签丢失,直接toPng版本的,兼容性问题。

weixin_44601570的博客 2105

无需Root!安卓模拟器+BurpSuite轻松搞定微信小程序抓包

本文详细介绍了如何在不root安卓设备的情况下,使用安卓模拟器和BurpSuite实现微信小程序抓包。通过夜神模拟器降级安卓版本、配置BurpSuite代理及安装证书等步骤,开发者可以轻松绕过微信的证书绑定,高效抓取小程序数据包。文章还提供了常见问题排查和高阶技巧,帮助开发者提升抓包效率。

weixin_29213655的博客 365

(8)Elasticsearch-mapping详解

1、Mapping简介 mapping 是用来定义文档及其字段的存储方式、索引方式的手段,例如利用mapping来定义以下内容: 哪些字段需要被定义为全文检索类型 哪些字段包含number、date类型等 格式化时间格式 自定义规则,用于控制动态添加字段的映射 例子: PUT /idx_item/ { "settings": { "index": { "number_of_shards" : "2", "number_of_replicas" : .

allensandy的博客 1717

深信服AF设置安全防护策略

防火墙设置安全防护策略,禁止用户访问指定网站

m0_64423407的博客 4838

Elastic search的日期问题

对于我们的直观感受和搜索而言呢,时间戳对于搜索倒是便利些,但是不够直观,只是一个数字而已。es的默认日期是采用的零时区,比我们少八个小时,无论是对于搜索还是直观感受,都有些不便。日期格式化为字符串后存储,比较直观,但是搜索起来就坑爹了,如果不觉得麻烦的人还望指教。无论我们以何种日期存放,elastic search的底层存放的还是时间戳,时间戳存储起来还是比较方便的。进入职场后,基本就一直在使用jdk 1.8,因此想想java 8有没有什么更好的解决方案呢?欢迎有更好解决方案的大牛前来拍砖!

m0_67403076的博客 1507

【前端圭臬】二:你知道的和不知道的 HTML

关于 HTML,说几个你可能不太关注的问题。

Evan 的博客 4758

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

MySQL-日期数据类型

YEAR 类型通常用来表示年 DATE 类型通常用来表示年、月、日 TIME 类型通常用来表示时、分、秒 DATETIME 类型通常用来表示年、月、日、时、分、秒 TIMESTAMP 类型通常用来表示带时区的年、月、日、时、分、秒 类型 名称 字节 日期格式 最小值 最大值 YEAR 年 1 YYYY或YY 1901 2155 TIME 时间 3 HH:MM:SS -838:59:59 838:59:5

zl979899的博客 1924

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Phoenix日期时间问题

Phoenix中跟时间相关的类型有TIMESTAMP,DATE和TIME,这些类型对于时区的处理逻辑是相同的,所以这里就以TIMESTAMP类型为例来说明Phoenix关于时区的处理方式。首先,我们先来看下Phoenix文档中对于TIMESTAMP类型的描述: The timestamp data type. The format is yyyy-MM-dd hh:mm:ss[.nnnnnnnnn]. Mapped to java.sql.Timestamp with an internal rep...

lzzyok的专栏 2914

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

南大通用GBase 8s数据库兼容oracle时间及日期类型简介

但要说明的是,Oracle中的date对应GBase 8s中的datetime year to second,GBase 8s中的date默认仅支持年月日,不支持时分秒,而Oracle中timestamp§则对应GBase 8s中的datetime year to fraction(min(5,p)),最多保留小数点后5位。DATE是最常用的数据类型,日期数据类型存储日期和时间信息。为每个日期值,Oracle 存储以下信息: 世纪、 年、 月、 日期、 小时、 分钟和秒。用来存储单位为年和月的时间间隔。

weixin_47390342的博客 379

Oracle 数据类型及存储方式 日期时间类型

[url]http://www.net527.cn/shujukuguanli/Oracle/2010/0623/11647.html [/url] 第三部分 日期时间类型 3.1 DATE Date类型Oralce用于表示日期和时间的数据类型。固定占用7个字节。 包括七个属性: 世纪 世纪中的年份 月份 月份中的哪一天 小时 分 秒 SQL create table test_dat...

转些好文章,促进分享。 587

Es直方图聚合--date_histogram

这允许以支持的单位的任意倍数指定固定间隔。但是,这意味着固定间隔不能表示其他单位,例如月,因为一个月的持续时间不是固定的数量。一分钟是指定时区中第一分钟的00秒和下一分钟的00秒之间的时间间隔,用于补偿任何介于其间的闰秒,因此整点后的分钟数和秒数在开始和结束时是相同的。所有天都在尽可能早的时间开始,通常是00:00:00(午夜)。它的单位只能是单数,不可是复数,比如。的关系,在有的国家,在某些时区下,一天就不一定是24个小时。单位,无论它们落在日历的哪个位置,都不会偏离。可用的单位为:分钟 (

rbx508780的博客 2986

使用 SAS 日期和时间

SAS 将日期和时间存储为一个唯一数字,这样就可以象使用其他数值变量一样在程序中使用它们: SAS 日期值代表介于 1960 年 1 月 1 日和指定日期之间的天数。SAS 可以对公元 1582 年到公元 19,900 之间的日期进行计算。1960 年 1 月 1 日之前的日期为负数;在此之后的日期为正数。 SAS 时间值代表自当日午夜 12 时算起的秒数,SAS 时间值介于 0 和

cyxlxp8411的专栏 1万+
上一篇: IP地址开启https
下一篇: syslog发送日志而docker容器接收不到的问题
方块糖
博客等级 码龄15年 44粉丝 63原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值