其他答案是正确的,尤其是arganzheng的java.time答案。如前所述,您应该避免使用旧的java.util.Date/.Calendar类,因为它们的设计不良,令人困惑且麻烦。它们已被java.time类取代。
让我添加有关处理午夜和时间跨度的策略的注释。
半开
在日期时间工作中,通常使用“半开放”方法定义时间跨度。在这种方法一开始是包容性的,而结局是独家。这样可以解决问题,如果持续使用,则可以更轻松地进行日期时间处理的推理。
解决的一个问题是定义一天的结束时间。是一天的最后时刻23:59:59.999
(毫秒)吗?也许是在java.util.Date类中(最早的Java;麻烦的是-避免使用此类!),以及在非常成功的Joda-Time库中。但是在其他软件(例如Postgres这样的数据库)中,最后一刻将是23:59:59.999999
(微秒)。但是在其他软件中,例如java.time框架(内置在Java 8和更高版本中,是Joda-Time的继承者)和某些数据库(例如H2数据库)中,最后一刻可能是23:59.59.999999999
(纳秒)。不要一头雾水,而应该只考虑第一刻,而不要考虑最后一刻。
在半开放式中,一天从一天的第一天开始,一直到(但不包括)第二天的第一天。因此,与其这样思考:
…从今天凌晨00:00(今早凌晨)到12:00 pm(今晚午夜)。
……这样想……
从今天的第一刻开始直到但不包括明天的第一刻:
(> = 00:00:00.0
今天AND < 00:00:00.0
明天)
在数据库工作中,这种方法意味着不使用SQL中的BETWEEN
运算符。
一天的开始
此外,一天的第一时刻并不总是一天中的时间00:00:00.0
。某些时区的夏时制(DST)以及其他异常情况可能意味着一天中开始的时间不同。
因此,让java.time类通过调用来确定一天的开始LocalDate::atStartOfDay( ZoneId )
。因此,我们必须绕过这个过程,LocalDate
然后再回到ZonedDateTime
本示例代码中可以看到的位置。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime todayStart = now.toLocalDate().atStartOfDay( zoneId );
ZonedDateTime tomorrowStart = todayStart.plusDays( 1 );
请注意传递了optional ZoneId
。如果省略,则会隐式应用JVM的当前默认时区。最好是明确的。
时区对于日期时间工作至关重要。该问题和其他一些答案可能存在缺陷,因为它们没有自觉地处理时区。
兑换
如果必须使用java.util.Date或.Calendar,请查找添加到这些旧类中的新转换方法。
java.util.Date utilDate = java.util.Date.from( todayStart.toInstant() );
java.util.GregorianCalendar gregCal = java.util.GregorianCalendar.from( todayStart );
时间跨度
顺便说一句,如果您要花费大量时间进行大量工作,请查看:
Duration
Period
Interval
该Interval
班在发现ThreeTen-额外的项目,扩展到java.time框架。该项目是将来可能向java.time添加内容的试验场。
Interval todayMontreal = Interval.of( todayStart.toInstant() , tomorrowStart.toInstant() );
关于java.time
该java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.Date
,Calendar
,和SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*
在哪里获取java.time类?
该ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。