我正在尝试处理车辆预订(使用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
答案 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。
如果你想用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 / GMT(无时区偏移)。仅转换为时区以便呈现给用户。
通过指定内置时区常量来轻松转换:DateTimeZone.UTC
DateTime dateTimeInUtc = new DateTime( DateTimeZone.UTC );
// - or -
DateTime nowInKolkata = new DateTime( DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeConvertedToUtc = nowInKolkata.toDateTime( DateTimeZone.UTC );