如何在postgres中的2个时间戳之间获取所有数据。

时间:2018-10-14 12:14:04

标签: java postgresql

我在postgres中有2个时间戳文件,我将这2个字段在Java中表示为Date字段。 开始时间-> 10月14日晚上10点 结束时间-> 10月14日晚上11点 如果我将值传递为“ oct 14 10.30 pm”,那么我必须所有开始时间大于我的传递值且结束时间小于我的传递值的行

2 个答案:

答案 0 :(得分:3)

tl; dr

使用半开方法>= AND <进行一段时间的处理,切勿BETWEEN

逻辑错误

  

开始时间->十月14 10 pm结束时间->十月14 11 pm…那么我必须所有开始时间大于我的传递值且结束时间小于我的传递值的行

此逻辑不正确。用这样的逻辑进行这样的每小时报告,您将永远不会报告时钟到一个小时时碰巧记录的项目。永远不会找到恰好是上午10点(10:00:00.0)或恰好上午11点(11:00:00.0)的行。

半开放

我建议一贯使用Half-Open方法来定义时间跨度。在这种方法中,开始为包含,而结束为排他。例如,小时从上午10点的第一时刻开始,一直持续到(但不包括)时钟凌晨11点。

通过这种方法,我将按小时进行一系列查询,以查找所有行。没有任何行会像您的逻辑一样消失。

SELECT * 
FROM event_
WHERE when_ >= ?
AND when_ < ?
;

换句话说,切勿在一段时间内使用BETWEEN 。请改用>= AND <逻辑。

时区

如果谈论实际时刻,谈论SQL标准列类型TIMESTAMP WITH TIME ZONE,则时区问题至关重要。

在您的示例中,您是指法国巴黎的上午10点吗?还是几个小时后,在魁北克蒙特利尔上午10点?还是几个小时前在印度加尔各答的上午10点?

在Java中,将您的条件定义为带有ZonedDateTime类的时区。

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
LocalDate ld = LocalDate.of( 2018 , 10 , 14 ) ;
LocalTime lt = LocalTime.of( 10 , 0 ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

要在UTC中查看同一时刻,请提取Instant

Instant instant = zdt.toInstant() ;

以标准ISO 8601格式生成表示其值的文本。

String output = instant.toString() ;   // Generate text in standard ISO 8601 format. 

使用兼容JDBC 4.2或更高版本的JDBC驱动程序在准备好的语句中将其传递给SQL查询。

myPreparedStatement.setObject( 1 , zdtStart ) ;
myPreparedStatement.setObject( 2 , zdtStop ) ;

关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:0)

PSQL中的

BETWEEN子句对您来说很好。

SELECT * 
FROM table 
WHERE <your_date_column> BETWEEN <Start_time> AND <END_TIME>

上面的where子句将为您提供位于指定范围之间的所有行。

只需通过传递了变量的Java代码调用此查询即可。