比较数据库的日期和时间范围与用户输入的日期和时间

时间:2013-12-28 22:05:24

标签: java sql date datetime servlets

我正在尝试处理车辆预订(使用JSP servlet)。我的数据库包含startdate,starttime,returndate,returntime。现在我为新的车辆预订插入新的日期范围和新的时间范围。我需要查询或算法天气新输入是可以接受的。 (日期范围和时间范围不应与已有的数据冲突) 我的数据库字段及其一些值:

Startdate       starttime       returndate      returntime
2013-12-10      10:00:00        2013-12-12      15:00:00
2013-12-16      09:00:00        2013-12-16      12:00:00
2013-12-16      12:15:00        2013-12-16      16:00:00    

3 个答案:

答案 0 :(得分:0)

如果您的日期和时间位于不同的字段中,请执行以下操作:

select *
  from tb_vehicle v
 where not v.id in (
    select r.vehicle_id
      from tb_reservation r
     where ((r.start_date < :input_end_date) ||
            (r.start_date = :input_end_date and r.start_time < :input_end_time))
       and
           ((r.end_date > :input_start_date) ||
            (r.end_date = :input_end_date and r.end_time > :input_start_time))
    )

此查询会返回:input_start_date - :input_start_time:input_end_date - :input_end_time期间未保留的所有车辆。

如果您可以组合日期和时间列,查询将更容易:

select *
  from tb_vehicle v
 where not v.id in (
    select r.vehicle_id
      from tb_reservation r
     where (r.start_time_stamp < :input_end_time_stamp)           
       and (r.end_time_stamp > :input_start_time_stamp))

答案 1 :(得分:0)

最简单的解决方案是将日期存储为长(毫秒),然后您之前/之后/之间的比较是简单的加/减操作。但这不会考虑时区,这可能是您在实施过多代码之前需要研究和理解的完全不同的问题。

答案 2 :(得分:0)

数据库

如果您正在使用具有复杂日期时间处理的良好数据库,例如Postgres,则数据库服务器可以通过执行查询来帮助您。也许您没有使用这样的数据库,因为您提到日期和时间是单独的字段。在复杂的数据库中,这些将是单个日期时间类型。

时区

您的问题无法解决时区问题。通常最好指定时区而不是依赖默认值。对于我下面的示例代码,我随意选择加尔各答印度(前加尔各答)时区,在UTC / GMT之前偏移5:30。

使用Joda-Time

如果你想用Java做的工作,你肯定应该避免使用捆绑的java.util.Date/Calendar类。要么使用Joda-Time库,要么使用Java 8,新的java.time.* classes(受Joda-Time启发)。

Joda-Time为您的目的提供方便的方法:间隔,持续时间和周期。 Java 8的java.time。*提供了类似的功能。

Interval类包含由一对起止DateTime对象定义的时间跨度。该类提供overlaps方法来告诉您一个区间是否与另一个区间重合。

示例代码

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );

Interval i1 = new Interval( new DateTime( "2013-12-10T10:00:00", timeZone ), new DateTime( "2013-12-12T15:00:00", timeZone ) );
Interval i2 = new Interval( new DateTime( "2013-12-16T09:00:00", timeZone ), new DateTime( "2013-12-16T12:00:00", timeZone ) );
Interval i3 = new Interval( new DateTime( "2013-12-16T12:15:00", timeZone ), new DateTime( "2013-12-16T16:00:00", timeZone ) );

Interval test1 = new Interval( new DateTime( "2011-01-01T10:00:00", timeZone ), new DateTime( "2011-01-07T10:00:00", timeZone ) ); // Note the year: 2011.
Interval test2 = new Interval( new DateTime( "2013-12-10T11:00:00", timeZone ), new DateTime( "2013-12-10T13:00:00", timeZone ) );

转储到控制台...

System.out.println( "i1: " + i1 );
System.out.println( "i2: " + i2 );
System.out.println( "i3: " + i3 );
System.out.println( "test1: " + test1 );
System.out.println( "test2: " + test2 );
System.out.println( "test1 overlaps i1: " + test1.overlaps( i1 ) );
System.out.println( "test2 overlaps i1: " + test2.overlaps( i1 ) );

跑步时......

i1: 2013-12-10T10:00:00.000+05:30/2013-12-12T15:00:00.000+05:30
i2: 2013-12-16T09:00:00.000+05:30/2013-12-16T12:00:00.000+05:30
i3: 2013-12-16T12:15:00.000+05:30/2013-12-16T16:00:00.000+05:30
test1: 2011-01-01T10:00:00.000+05:30/2011-01-07T10:00:00.000+05:30
test2: 2013-12-10T11:00:00.000+05:30/2013-12-10T13:00:00.000+05:30
test1 overlaps i1: false
test2 overlaps i1: true

使用UTC

虽然我的示例使用特定时区,但通常最好在业务逻辑和存储/数据库中使用UTC / GMT(无时区偏移)。仅转换为时区以便呈现给用户。

通过指定内置时区常量来轻松转换:DateTimeZone.UTC

DateTime dateTimeInUtc = new DateTime( DateTimeZone.UTC ); 
// - or -
DateTime nowInKolkata = new DateTime( DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeConvertedToUtc = nowInKolkata.toDateTime( DateTimeZone.UTC );