date数据写入ES的时区问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了date数据写入ES的时区问题相关的知识,希望对你有一定的参考价值。

参考技术A 最初往es中写入的时间为时间戳,但是ES中该字段写入的值所代表的时间要比实际的时间戳所代表的时间滞后8小时。



原因是ES中存储的时间是UTC时间,而我想让时间戳表达的时间是东8区(UTC +08:00)的时间,但是时间戳本身是没有时区的概念的,所以不能去存时间戳,而是去存一个带有时区信息的时间字符串,ES会隐式转换,把ES认为是date类型的字符串直接转为date类型。

更改如下:

Java - 日期时区转换

【中文标题】Java - 日期时区转换【英文标题】:Java - Date timezone conversion 【发布时间】:2019-10-24 22:53:00 【问题描述】:

我正在尝试将 JSON 对象转换为日期并将其写入数据库。但是,将日期转换为 EST 的代码不起作用。将日期转换为 EST 的最佳方法是什么?

JSON 条目

"custom_date_1": "2019-05-19","

转换代码

int id;
Date trainingDate;

SimpleDateFormat format = new SimpleDateFormat("DD-MM-YY", Locale.US);
TimeZone tz = TimeZone.getTimeZone("EST");
format.setTimeZone(tz);

logger.info("custom_date_1: ", object.getString("custom_date_1"));

 try 
      id= Integer.parseInt(object.getString("employee_number"));
      trainingDate = format.parse(object.getString("custom_date_1"));

      //Still says GMT
      logger.info("trainingDate: ", trainingDate);

       map.put("employee_number", id);
       map.put("custom_date_1", trainingDate);
    catch (ParseException e) 
       e.printStackTrace();
   

日志声明

2019-06-10 14:00:00,226 INFO custom_date_1: 2019-05-19
2019-06-10 14:00:00,226 INFO trainingDate: Sun Dec 30 05:00:00 GMT 2018

【问题讨论】:

当您有一个没有时间的日期时,在特定时区要求它有什么意义? 任何日期都是特定时区中的同一日期。所以你可以用LocalDate.parse(date);把它转换成日期? 当您说“EST”时,您的真正意思是“东部标准时间”(纽约冬季观察到的 UTC 偏移量),还是您的意思是“纽约时区”?如果是前者,则表示为UTC+5;如果是后者,表示为America/New_York。 (“EST”实际上是前者)。 我建议你不要使用DateSimpleDateFormatTimeZone。那些课程设计糟糕且过时,尤其是中间的课程出了名的麻烦。而是使用来自java.time, the modern Java date and time API 的LocalDate(乍一看,在我看来你不需要任何其他类)。 @P.Soutzikevich 不,不是重复的。 That Question 是关于时间的日期,而这个问题似乎是关于仅日期的(虽然不清楚)。 【参考方案1】:

tl;博士

myPreparedStatement.setObject(       // In JDBC 4.2 and later, exchange *java.time* objects with your database. Use `PreparedStatement` to avoid SQL Injection attacks. 
    … ,                              // Specify which `?` placeholder to replace in your SQL statement. 
    LocalDate.parse( "2019-05-19" )  // Parse your standard ISO 8601 formatted input string as a date-only value represented in the `LocalDate` class. 
) 

详情

“custom_date_1”:“2019-05-19”,

您的输入字符串是标准的ISO 8601 格式。 java.time 类在解析/生成字符串时默认使用这些标准格式。所以不需要指定格式模式。

LocalDate ld = LocalDate.parse( "2019-05-19" ) ;

时区在这里无关紧要。所以你的问题很混乱。

我正在尝试将 JSON 对象转换为日期并将其写入数据库。

截至JDBC 4.2,我们可以与数据库交换java.time 对象。您在数据库中为这个仅日期值(没有时间和没有时区)的列应该是类似于标准 SQL 类型DATE 的类型。

myPreparedStatement.setObject( … , ld ) ;

检索。

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;

【讨论】:

【参考方案2】:

从 Java 8 开始,您应该使用 LocalDateLocalDateTime,因此您可以使用进行时区转换

LocalDateTime.atZone(ZoneId zoneId)

例如

LocalDateTime date = LocalDateTime.parse("2019-06-10T12:00:00"); 
ZonedDateTime date2 = date.atZone(ZoneId.systemDefault());

【讨论】:

以上是关于date数据写入ES的时区问题的主要内容,如果未能解决你的问题,请参考以下文章

elasticsearch数据早8小时Or晚8小时,你知道为什么吗,附解决方案

Java - 日期时区转换

PHP date() 与时区?

Logstash 时区问题导至数据被写进错误的 ES 索引的解决方法

时区java项目new date()时间和服务器时间(数据库)不一致

Oracle 将带有时区的 TIMESTAMP 转换为 DATE