其他答案都是正确的,尤其是java。时间回答由干政。正如一些人提到的,应该避免使用旧的java.util.Date/。日历类,因为它们设计得很差,令人困惑,而且很麻烦。他们已经被爪哇取代了。时间类。
让我补充一些关于处理午夜和时间跨度的策略。
半开的
在日期-时间工作中,时间跨度通常使用“半开放”方法来定义。在这种方法中,开始是包容的,而结束是排外的。这可以解决问题,如果始终使用,可以更容易地推理日期时间处理。
One problem solved is defining the end of the day. Is the last moment of the day 23:59:59.999 (milliseconds)? Perhaps, in the java.util.Date class (from earliest Java; troublesome – avoid this class!) and in the highly successful Joda-Time library. But in other software, such as database like Postgres, the last moment will be 23:59:59.999999 (microseconds). But in other software such as the java.time framework (built into Java 8 and later, successor to Joda-Time) and in some database such the H2 Database, the last moment might be 23:59.59.999999999 (nanoseconds). Rather than splitting hairs, think in terms of first moment only, not last moment.
在半开放中,一天从一天的第一个时刻算起,但不包括第二天的第一个时刻。所以与其这样想:
从今天凌晨0点(今天凌晨12点)到下午12点(今晚12点)。
这样想…
从今天的第一个时刻到但不包括明天的第一个时刻:(>=今天的00:00:00.0 AND <明天的00:00:00.0)
在数据库工作中,这种方法意味着不在SQL中使用BETWEEN操作符。
一天的开始
此外,一天的第一个时刻并不总是一天中的00:00:00.0。某些时区的日光节约时间(DST),以及可能存在的其他异常情况,可能意味着一天开始的时间不同。
所以让java。time类通过调用LocalDate::atStartOfDay(ZoneId)来确定一天的开始。因此,我们必须绕过LocalDate,返回到本例代码中所示的zoneeddatetime。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime todayStart = now.toLocalDate().atStartOfDay( zoneId );
ZonedDateTime tomorrowStart = todayStart.plusDays( 1 );
注意可选的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 );
时间跨度
顺便说一下,如果你在一段时间内做了很多工作,可以看看:
持续时间
期
Interval类可以在ThreeTen-Extra项目中找到,它是java的扩展。时间框架。这个项目是未来可能添加到java.time.Interval todayMontreal = Interval的试验场。of(todayStart.toInstant(), tomorrowStart.toInstant());
关于java.time
java。时间框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期-时间类,如java.util。日期,日历和简单日期格式。
Joda-Time项目现在处于维护模式,建议迁移到java。时间类。
要了解更多,请参阅Oracle教程。搜索Stack Overflow可以找到很多例子和解释。规范是JSR 310。
你可以交换java。Time对象直接使用数据库。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要java。sql。*类。
从哪里获取java。时间类?
Java SE 8、Java SE 9、Java SE 10、Java SE 11及更高版本——带有捆绑实现的标准Java API的一部分。
Java 9增加了一些小特性并进行了修复。
Java SE 6和Java SE 7
大部分的java。时间功能在ThreeTen-Backport中向后移植到Java 6和7。
安卓
后续版本的Android捆绑实现的java。时间类。
对于早期的Android (<26), ThreeTenABP项目适应ThreeTen-Backport(如上所述)。参见如何使用ThreeTenABP....
ThreeTen-Extra项目扩展了java。额外的课程时间。这个项目是未来可能添加到java.time的一个试验场。你可以在这里找到一些有用的类,比如Interval、YearWeek、YearQuarter等等。