由于java中的时区问题,未拾取数据

由于java中的时区问题,未拾取数据,java,Java,我的代码中有一个日期/时间计算时区的问题。 我也需要你的建议。下面是场景 我的应用程序必须从hbase数据库中拾取数据。此数据将根据hbase中的表中的日期搜索条件选取。该表有一个用于筛选的日期-时间列 现在,填充此表中数据的另一个应用程序是插入GMT时区格式的datetime(这是该团队所说的)。应用程序部署在位于EST时区的服务器上。我从用户那里得到一个输入日期(没有时间成分),我需要将其转换为GMT时区。但目前的情况是,当我进行转换时,一些数据没有在EST时区中被拾取。相同的数据在我的本地

我的代码中有一个日期/时间计算时区的问题。 我也需要你的建议。下面是场景

我的应用程序必须从hbase数据库中拾取数据。此数据将根据hbase中的表中的日期搜索条件选取。该表有一个用于筛选的日期-时间列

现在,填充此表中数据的另一个应用程序是插入GMT时区格式的datetime(这是该团队所说的)。应用程序部署在位于EST时区的服务器上。我从用户那里得到一个输入日期(没有时间成分),我需要将其转换为GMT时区。但目前的情况是,当我进行转换时,一些数据没有在EST时区中被拾取。相同的数据在我的本地时区列表中被拾取。我已经在本地和远程服务器中部署的代码中完成了到GMT的转换。下面的示例

数据出现在表中的日期:2013-03-15 01:30:30

用户输入的数据:2013-03-15(无时间成分)。我特别添加了时间组件

添加时间组件后的日期:开始日期-2013-03-15 00:00:00,结束日期-2013-03-15 23:59:59

我在IST时区(UTC+5:30)。因此,转换为GMT的开始日期和结束日期都是

开始日期转换为GMT-2013-03-1418:30:56

结束日期转换为格林尼治标准时间-2013-03-15 18:30:56

现在,由于用户提供的日期2013-03-15 01:30:30落在上述范围内,表中的数据将被拉入该时区

在EST(UTC-5:00)中的远程服务器中部署了相同的代码

开始日期转换为GMT-2013-03-15 05:00:56

结束日期转换为格林尼治标准时间-2013-03-16 05:00:56

现在,由于用户提供的数据2013-03-15 01:30:30不在此范围内,因此数据不会被提取

我不确定如何处理这种情况,以使计算在时区之间保持一致。因为测试人员说数据应该在不同的时区之间保持一致。但正如你所看到的,GMT转换已经完成,但日期被两个时区的偏移量抵消了,数据也没有被调出。 如果你能让我知道如何处理这将是很大的帮助


我没有在这里输入任何代码,因为它是在线时区的标准代码,在大多数情况下都是相同的。

这取决于您在这里尝试实现的目标

如果您确实希望将输入解释为本地时间,并将其转换为GMT以检查数据库,那么结果实际上是一致的,反过来想想问题,如果您将HBase中的每个日期神奇地转换为本地时间,您会得到哪些记录

如果用户输入的日期实际上是TZ特定的,那么同一个日期“文本”返回不同的结果是很自然的,因为两个用户实际上指的是两个不同的时间点

另一方面,如果您需要提供相同输入的用户获得完全相同的结果,那么您需要假设输入已经在某个一致的TZ中,例如,始终在UTC(或您的情况下为GMT)

基本上,您需要决定的是:

用户提供的输入是否特定于用户的TZ?或者它总是在同一时刻,在特定的时间?IST,EST,GMT,由你决定

如果你做出这样的决定,你的结果将是一致的。

tl;博士 使用半开放查询逻辑:

选择*
来自tbl
什么时候>=?什么时候<?——半开放逻辑,其中开始是包含的,而结束是独占的。
;
具有两个参数的查询:

  • 一天的开始时刻
  • 第二天开始时刻
在现代java中使用java.time类:

myPreparedStatement.setObject(  
    1 , 
    LocalDate.parse( "2013-03-15" )         // Represent entire day as a `LocalDate` object.
        .atStartOfDay(                      // Determine first moment of that date in a particular time zone, which may or may not be 00:00:00.
            ZoneId.of( "Asia/Kolkata" ) 
        )                                   // Returns a `ZonedDateTime` object. Your JDBC driver should be able to handle that smartly. If not, extract a `Instant` object in UTC by calling `ZonedDateTime::toInstant()`.
) ; 


myPreparedStatement.setObject( 
    2 , 
    LocalDate.parse( "2013-03-15" )        
        .plusDays( 1 )                     // Move to the following day.
        .atStartOfDay( 
            ZoneId.of( "Asia/Kolkata" ) 
        )
) ; 
检索时,调整到任何所需的时区

myResultSet.getObject( … , Instant.class)  // Extract a `Instant` object from selected row.
    .atZone(                               // Apply a `ZoneId` to get a `ZonedDateTime` object.
        ZonedId.of( "America/Montreal" )
    )
服务器默认时区无关 服务器当前的默认时区应该与您的编程无关。您应该通过各种日期-时间方法的可选参数指定所需/预期时区

顺便说一下,
Locale
也一样:显式指定,而不是隐式依赖当前默认值

在我看来,这些论点应该是必要的,而不是随意的。似乎很多程序员忽视了时区和语言环境的问题

java.time 现代方法使用java.time类

使用符合JDBC 4.2或更高版本的JDBC驱动程序,您可以直接与数据库交换java.time类型

在UTC中使用
Instant
片刻。对于没有时间和时区的日期,请使用
LocalDate

LocalDate ld = LocalDate.parse( "2013-03-15" ) ;
要搜索包含一整天范围内某个时刻的数据库记录,我们需要确定当天的第一个时刻和次日的第一个时刻。然后我们做一个半开放的查询,其中开始是包含的,而结束是独占的

不要假设一天从00:00:00开始。夏时制(DST)等异常意味着一天可能在其他时间开始,如01:00:00。我们需要一个时区

大陆/地区
的格式指定,例如,或
太平洋/奥克兰
。切勿使用3-4个字母的缩写,如
EST
IST
,因为它们不是真正的时区,也不是标准化的,甚至不是唯一的(!)

第二天。调用
LocalDate::plusDays
移动到第二天

ZonedDateTime zdtStop = ld.plusDays( 1 ).atStartOfDays( z ) ;
如果您希望看到与UTC墙上时钟时间相同的时刻,请提取一个
瞬间
。该类表示时间线上的一个时刻,分辨率为(小数点的九(9)位)

您的SQL应该如下所示:

String sql = "SELECT * FROM tbl WHERE when >= ? AND when < ? ;" ; // Half-open logic, where beginning is inclusive while the ending is exclusive.
和检索

Instant instant = myResultSet.getObject( "when" , Instant.class ) ;
如果你想通过挂钟的镜头来观察同一时刻,那么你就要使用时间
String sql = "SELECT * FROM tbl WHERE when >= ? AND when < ? ;" ; // Half-open logic, where beginning is inclusive while the ending is exclusive.
myPreparedStatement.setObject( 1 , start ) ; // You can exchange java.time object with JDBC 4.2 or later.
myPreparedStatement.setObject( 2 , stop ) ; 
Instant instant = myResultSet.getObject( "when" , Instant.class ) ;
ZonedDateTime zdt = instant.atZone( ZoneId.of( "America/New_York" ) ) ;