【问题标题】:Date time in java from SQL来自SQL的Java中的日期时间
【发布时间】:2018-09-24 02:30:00
【问题描述】:

我有这段代码

while(activecheck.next()){
    Date status;
    String vincheck;
    Date curr = new Date();
    int datecheck;
    status = activecheck.getDate(8);
    vincheck = activecheck.getString(2);
    String update = "UPDATE Auctions SET status = '"+inactive+"' WHERE vin = '"+vincheck+"'";
    datecheck = status.compareTo(curr);

    if(datecheck < 0){  
        stmt6.executeUpdate(update);
    }
}

它遍历一个 mysql 表来检查无效的投标。我正在尝试检查 sql 行中列出的日期和时间是否已超过当前时间。但是,每当我这样做时,似乎只是在比较日期,而不是时间。这可能是什么原因?

这是我使用的格式:yyyy-MM-dd HH:mm:ss`

【问题讨论】:

  • 您的查询容易受到 sql 注入。您应该使用准备好的语句。
  • 我们是否有理由更新 RBAR(逐行逐行)?而不仅仅是一举搞定...UPDATE Auctions SET status = 'inactive' WHERE col8 &lt; NOW() AND ... 无论在 activecheck cursor query ...中使用什么标准
  • 感谢您的关注,但这只是一个学校项目
  • @spencer7593 不,没有理由,我只是个菜鸟,不知道我可以那样做

标签: java mysql date jsp time


【解决方案1】:

tl;博士

if( 
    myResultSet.getObject( … , Instant.class )  // Retrieve `Instant` (a moment in UTC) from database using JDBC 4.2 or later.
               .isBefore( Instant.now() )       // Comparing to the current moment captured in UTC.
)
{ 
    … 
}

java.util.Datejava.sql.Date

您可能会混淆这对不幸命名错误的类。第一个是日期与时间类型,以 UTC 为单位。第二种是仅日期类型。实际上,第二个 假装 是仅日期类型,但实际上将时间设置为 00:00:00。更糟糕的是,第二个继承自第一个,但文档指示我们忽略这一事实。

令人困惑?是的。这些糟糕的类设计得很糟糕。避开他们。

java.time

您正在使用非常麻烦的旧日期时间类,这些类在几年前已被 java.time 类取代。

Instant

java.util.Date 类已替换为 java.time.InstantInstant 类代表UTC 时间线上的时刻,分辨率为nanoseconds(最多九 (9) 位小数)。

LocalDate

java.sql.Date 类已替换为 java.time.LocalDateLocalDate 类表示没有时间和时区的仅日期值。

JDBC 4.2

从 JDBC 4.2 及更高版本开始,您可以直接与数据库交换 java.time 类。无需再次使用 java.sql 或 java.util 日期时间类型。

提示:养成始终使用PreparedStatement 的习惯,以避免SQL Injection 的风险。习惯了就不用再工作了。

Instant instant = Instant.now() ;  // Capture the current moment in UTC.
myPreparedStatement.setObject( … , instant ) ;

和检索。

Instant instant = myResultSet.getObject( … , Instant.class ) ;

智能对象,而不是哑字符串

这是我使用的格式:yyyy-MM-dd HH:mm:ss`

存储在数据库中的日期时间值没有“格式”。这些值由一些与我们无关的内部定义的机制存储。它们是 not 字符串(也就是说,不在任何严肃的数据库中)。

您的数据库和 Java 日期时间对象可以解析一个表示日期时间值的字符串来创建该值。他们可以生成一个字符串来表示该值。但是字符串和日期时间值是不同的和分开的,不应该混为一谈。

使用 java.time 对象与您的数据库交换日期时间值,而不仅仅是字符串,就像您对数据库理解的数字和其他数据类型一样。仅使用字符串来传达文本值。

比较

要将检索到的值与当前时刻进行比较,请使用 Instant 类的 isBeforeisAfterequals 方法。

Instant now = Instant.now() ;
…
Instant instant = myResultSet.getObject( … , Instant.class ) ;
boolean isPast = instant.isBefore( now ) ;
if ( isPast ) { 
    … 
}

关于java.time

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

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

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

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

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    【解决方案2】:

    您应该使用称为 Timestamp 的类型而不是日期。这样您将涵盖日期和当前时间

      Timestamp timestamp = new Timestamp(System.currentTimeMillis());
    

    【讨论】:

    • 更好的是,使用InstantInstant.now()activecheck.getObject(8, Instant.class),最后使用if (status.isBefore(curr))。或者可能是LocalDateTime,具体取决于数据库列的数据类型。
    • 是的,这当然取决于数据库列中的类型。 @OleV.V.
    • 仅供参考,麻烦的 java.sql.Timestamp 类在几年前被现代 java.time 类取代,特别是 Instant
    猜你喜欢
    • 2016-04-02
    • 2021-04-21
    • 2014-05-22
    • 2011-03-23
    • 2017-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多