tl;博士
LocalDate.of( 2012 , Month.JANUARY , 31 )
.plusDays( 1 )
2012-02-01
……或者……
LocalDate.of( 2012 , 1 , 31 ) // Sane numbering: 1-12 for January-December, and `2012` means year 2012.
.plusDays( 1 )
2012-02-01
java.time
Calendar 类令人困惑、笨拙且设计不佳。在它的许多问题中,这些传递单元标志的方法。幸运的是,你现在可以忘记这门课了。
Java 8 及更高版本中内置的 java.time 类现在取代了旧的日期时间类。
LocalDate
LocalDate 类表示没有时间和时区的仅日期值。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。
如果没有指定时区,JVM 会隐式应用其当前的默认时区。该默认值可能随时更改,因此您的结果可能会有所不同。最好将您想要/预期的时区明确指定为参数。
以continent/region 的格式指定proper time zone name,例如America/Montreal、Africa/Casablanca 或Pacific/Auckland。切勿使用 3-4 个字母的缩写,例如 EST 或 IST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
如果你想使用 JVM 当前的默认时区,请求它并作为参数传递。如果省略,则隐式应用 JVM 的当前默认值。最好是明确的,因为默认值可能会在任何时候在运行时被 JVM 中任何应用程序的任何线程中的任何代码更改。
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
或者指定一个日期。您可以通过数字设置月份,1 月至 12 月的编号为 1-12。
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
或者,更好的是,使用预定义的Month 枚举对象,一年中的每个月一个。提示:在整个代码库中使用这些 Month 对象,而不是仅仅使用整数,以使您的代码更具自记录性、确保有效值并提供 type-safety。
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
零件
拿着LocalDate,你可以询问它的部分。
获取日期,即“日期”,例如从 2018 年 1 月 23 日开始的23:
int dayOfMonth = ld.getDayOfMonth() ; // 1-31, depending on length of month.
获取一年中的第 n 天,从 1-365,或在闰年,从 1-366:
int dayOfYear = ld.getDayOfYear() ;
数学
在 java.time 中添加或减去天数非常简单且直观。方便的方法和时间跨度对象使代码更加清晰。
LocalDate dayLater = ld.plusDays( 1 ) ;
所以明天会是:
LocalDate tomorrow = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ).plusDays( 1 ) ;
或者,您可以表示不附加到时间线的时间跨度。对于年-月-日,请使用Period。对于小时-分钟-秒,请使用Duration。
Period p = Period.ofDays( 1 ) ;
LocalDate dayLater = ld.plus( p ) ;
请注意,java.time 使用 sane 编号,这与旧类不同。数字 2018 是 2018 年。1 月至 12 月的月份编号为 1-12。根据ISO 8601 标准,周一至周日将一周中的天数编号为 1-7。
关于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。