当前位置: 首页 > 知识库问答 >
问题:

Postgresql似乎转换了PreparedStatement的时间戳参数

西门高歌
2023-03-14

Postgresql似乎转换了PreparedStatement的timestamp参数,我使用settimestamp设置了这个参数。

“我想做的事”

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
sdf2.setTimeZone(TimeZone.getTimeZone("UTC"));
Timestamp startTime = Timestamp.valueOf(sdf.format(new Date(System.currentTimeMillis())));
Timestamp endTime = Timestamp.valueOf(sdf2.format(new Date(System.currentTimeMillis())));

PreparedStatement pstmt = conn.prepareStatement( 
 "SELECT * FROM some_table WHERE update_time BETWEEN ? AND ? "
);
pstmt.setTimestamp(1, startTime);
pstmt.setTimestamp(2, endTime);
ResultSet rs = pstmt.executeQuery();
CREATE TABLE some_table
(
mem_no      bigserial
,data   char(2)
,update_time    timestamp with time zone DEFAULT current_timestamp
,CONSTRAINT pk_some_table PRIMARY KEY (mem_no)
);

[奇怪的事]

使用调试工具,我检查了pstmt值。奇怪的是,+09:00被添加到我的参数中。

pstmt=>SELECT*FROM some_table WHERE update_time bether beather bether bether bether bether bether bether bether bether bether bether bether bether bether bether bether bether bether bether bether bether bether bether bether

DB:postgresql 9.3

共有1个答案

公瑞
2023-03-14

若要查找在某一日期发生的记录时刻的所有行,请在此SQL:
“select*FROM tbl WHERE when!<?AND when<?;”;中使用时间跨度的半开方法。

myPreparedStatement
.setObject( 
    1 , 
    LocalDate                   // Represent a date-only value, without a time-of-day and without a time zone.
    .parse( "2016-06-30" )      // Returns a `LocalDate` object.
    .atStartOfDay()             // Returns a `OffsetDateTime` object. JDBC 4.2 and later requires support for this class.
) ;

myPreparedStatement
.setObject( 
    2 , 
    LocalDate
    .parse( "2016-06-30" )
    .plusDays( 1 )              // Add a day, to get first moment of the following day.
    .atStartOfDay()
) ;
    

您的代码存在多个问题。有关更多讨论,请参见其他答案,如我的这一个。我将在这里简短,因为这已经被讨论过很多次了。

  • 只使用java.time类,而不要使用它们在采用JSR310后取代的遗留date-time类。
  • 使用半开放方法定义时间跨度,其中开始是包含的,而结束是独占的。
  • 明确您是在跟踪时刻、时间线上的特定点,还是带有一天中的时间但缺少时区上下文或从UTC偏移量的模糊日期。
  • 如果跟踪时刻,则列的数据类型必须是Timestamp(带时区)而不是(不带)。
  • 在任何给定时刻,日期(和一天中的时间)在全球各地因时区而异。
  • 某些时区中的某些日期不是从00:00开始的。始终让java.time决定一天的开始。
LocalDate startDate = LocalDate.parse( "2016-06-30" ) ;
LocalDate stopDate = startDate.plusDays( 1 ) ;
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdtStart = startDate.atStartOfDay( z ) ;
ZonedDateTime zdtStop = startDate.atStopOfDay( z ) ;
OffsetDateTime start = zdtStart.toOffsetDateTime() ;
OffsetDateTime stop = zdtStop.toOffsetDateTime() ;
String sql = "SELECT * FROM tbl WHERE when !< ? AND when < ? ; " ;  // Half-Open span-of-time where beginning is inclusive while the ending is exclusive.
myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;

检索结果。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

该结果将以UTC表示。您可以调整到所需的时区。同样的时刻,同样的时间线上的点,但不同的挂钟时间。

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

我的本地时区:GMT+9(KST)

因此,一周从周一开始,一直到下周一,但不包括下周一。午餐时间从中午12:00开始,一直持续到(但不包括)时钟敲响13:00时。一天从一天的第一个时刻开始(顺便说一句,不一定是00:00!),一直到第二天的第一个时刻,但不包括第二天的第一个时刻。研究这个答案中显示的SQL和Java,看看它是如何工作的。

 类似资料:
  • 我找不到这个问题的解决方案,我正在从firebase获取数据,其中一个字段是时间戳,看起来像这样- Swift示例(作品): 我的飞镖尝试: 并且它返回的日期/时间是错误的。 更新:

  • 返回我女巫是错误的。 但接下来的查询如下: 我看对日期

  • 本教程的重点是将来自 Yahoo finance API 的日期转换为 Matplotlib 可理解的日期。 为了实现它,我们要写一个新的函数,bytespdate2num。 def bytespdate2num(fmt, encoding='utf-8'): strconverter = mdates.strpdate2num(fmt) def bytesconverter(b)

  • 我正在尝试将日期插入我的PostgreSQL数据库。以下是我在java应用程序中解析日期的方式: 在我的PostgreSQL数据库中。我将其作为带有时区的。处理和插入它的理想方式是什么? 数据库期望的示例。

  • 这是我在申请表中得到的日期: 将psqlDate转换为joda的最佳方式是什么? [编辑] 我可以使用解析方法。它可以很好地使用时间戳,它可以使用T-分割日期和时间的信息。 这应该与良好的模式一起工作: 带有时区的PostgreSQL时间戳的正确模式是什么?

  • 下面的代码给出了2021年8月6日星期五12:16:27 GMT-0700(太平洋夏时制)的值,而不是mm/dd/yyyy hh:mm:ss。我在这里漏掉了什么?请告知