tl;博士
ZoneId z = ZoneId.of( "America/Montreal" ); // A date only has meaning within a specific time zone. At any given moment, the date varies around the globe by zone.
LocalDate ld =
givenJavaUtilDate.toInstant() // Convert from legacy class `Date` to modern class `Instant` using new methods added to old classes.
.atZone( z ) // Adjust into the time zone in order to determine date.
.toLocalDate(); // Extract date-only value.
LocalDate today = LocalDate.now( z ); // Get today’s date for specific time zone.
LocalDate kwanzaaStart = today.withMonth( Month.DECEMBER ).withDayOfMonth( 26 ); // Kwanzaa starts on Boxing Day, day after Christmas.
LocalDate kwanzaaStop = kwanzaaStart.plusWeeks( 1 ); // Kwanzaa lasts one week.
Boolean isDateInKwanzaaThisYear = (
( ! today.isBefore( kwanzaaStart ) ) // Short way to say "is equal to or is after".
&&
today.isBefore( kwanzaaStop ) // Half-Open span of time, beginning inclusive, ending is *exclusive*.
)
半开
日期时间工作通常采用“半开放”方法来定义时间跨度。开头是inclusive,而结尾是exclusive。因此,从星期一开始的一周一直持续到但不包括下一个星期一。
java.time
Java 8 及更高版本带有内置的java.time 框架。取代了旧的麻烦类,包括java.util.Date/.Calendar 和SimpleDateFormat。受到成功的 Joda-Time 图书馆的启发。由 JSR 310 定义。由 ThreeTen-Extra 项目扩展。
Instant 是 UTC 时间线上的一个时刻,分辨率为纳秒级。
Instant
将您的 java.util.Date 对象转换为 Instant 对象。
Instant start = myJUDateStart.toInstant();
Instant stop = …
如果通过 JDBC 从数据库中获取 java.sql.Timestamp 对象,convert to java.time.Instant 以类似的方式。 java.sql.Timestamp 已采用 UTC,因此无需担心时区。
Instant start = mySqlTimestamp.toInstant() ;
Instant stop = …
获取当前时刻进行比较。
Instant now = Instant.now();
使用 isBefore、isAfter 和 equals 方法进行比较。
Boolean containsNow = ( ! now.isBefore( start ) ) && ( now.isBefore( stop ) ) ;
LocalDate
也许您只想使用日期,而不是时间。
LocalDate 类表示仅日期值,没有时间和时区。
LocalDate start = LocalDate.of( 2016 , 1 , 1 ) ;
LocalDate stop = LocalDate.of( 2016 , 1 , 23 ) ;
要获取当前日期,请指定时区。在任何给定时刻,今天的日期因时区而异。例如,巴黎的新一天比蒙特利尔更早。
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
我们可以使用isEqual、isBefore和isAfter方法进行比较。在日期时间工作中,我们通常使用半开方法,其中时间跨度的开始是包含,而结束是独占。
Boolean containsToday = ( ! today.isBefore( start ) ) && ( today.isBefore( stop ) ) ;
Interval
如果您选择将ThreeTen-Extra 库添加到您的项目中,您可以使用Interval 类来定义时间跨度。该类提供了测试间隔 contains、abuts、encloses 或 overlaps 是否为其他日期时间/间隔的方法。
Interval 类适用于 Instant 对象。 Instant 类代表UTC 时间线上的时刻,分辨率为nanoseconds(最多九 (9) 位小数)。
我们可以通过指定时区来将LocalDate 调整为特定时刻,即一天的第一时刻,从而得到ZonedDateTime。从那里我们可以通过提取Instant 来返回UTC。
ZoneId z = ZoneId.of( "America/Montreal" );
Interval interval =
Interval.of(
start.atStartOfDay( z ).toInstant() ,
stop.atStartOfDay( z ).toInstant() );
Instant now = Instant.now();
Boolean containsNow = interval.contains( now );
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
从哪里获得java.time 类?
ThreeTen-Extra 项目扩展了 java.time 并添加了其他类。该项目是未来可能添加到java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。