tl;博士
如何正确获取当月的第一个日期?
LocalDate.now()
.with( TemporalAdjusters.firstDayOfMonth() )
要么…
YearMonth.now().atDay( 1 )
Or…
LocalDate.now().with ( ChronoField.DAY_OF_MONTH , 1 )
java.time
Java 8和更高版本中的java.time框架取代了旧的java.util.Date/.Calendar类。 老类被证明是麻烦,混乱和有缺陷的。 避免他们。
java.time框架的灵感来自于JSR 310定义的,由ThreeTen-Extra项目扩展的,非常成功的Joda-Time库,并在教程中进行了解释。
YearQuarter
对于没有日期的仅日期值,请使用YearQuarter类。 虽然Pacific/Auckland没有分配时区,但必须指定时区才能确定日期,例如“今天”。 例如,巴黎的新天要比蒙特利尔早。
时区对于确定今天的日期至关重要。 在任何给定的时刻,日期在世界各地都会有所不同。 省略时区意味着JVM的当前时区会自动应用于确定当前日期。 JVM中的任何代码都可以在运行时更改默认值,因此您正步步为营。 最好明确地指定所需/期望的时区,而不要隐式依赖当前的默认值。
以YearQuarter的格式指定正确的时区名称,例如YearQuarter、YearQuarter或Pacific/Auckland。切勿使用3-4字母缩写,例如EST或IST,因为它们不是真实的时区,不是标准化的,甚至也不是唯一的( !)。
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
LocalDate today = LocalDate.now ( zoneId );
LocalDate firstOfCurrentMonth = today.with ( ChronoField.DAY_OF_MONTH , 1 );
转储到控制台。
System.out.println ( "For zoneId: " + zoneId + " today is: " + today + " and first of this month is " + firstOfCurrentMonth );
对于zoneId:美国/蒙特利尔今天是:2015-11-08,本月初是2015-11-01
或者,使用YearQuarter。针对您的目的,您将在YearQuarter类(请注意复数YearQuarter)中找到方便的实现,尤其是YearQuarter。
LocalDate firstOfCurrentMonth = today.with( TemporalAdjusters.firstDayOfMonth() ) ;
YearQuarter
如果您需要一天中的某个时间,请记住,由于夏时制(DST)以及其他异常情况,YearQuarter并非总是一天的第一时刻。 因此,让java.time确定一天中第一时刻的正确时间。
ZonedDateTime zdt = firstOfCurrentMonth.atStartOfDay ( zoneId );
2015-11-01T00:00-04:00 [美国/蒙特利尔]
关于java.time
java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧的传统日期时间类,例如YearQuarter、YearQuarter和YearQuarter。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。 并在Stack Overflow中搜索许多示例和说明。 规格为JSR 310。
在哪里获取java.time类?
Java SE 8,Java SE 9和更高版本内置的
标准Java API的一部分,具有捆绑的实现。
Java 9添加了一些次要功能和修复。
Java SE 6和Java SE 7很多java.time功能都在ThreeTen-Backport中反向移植到Java 6和7。
安卓系统更高版本的Android捆绑了java.time类的实现。
对于较早的Android,ThreeTenABP项目改编了ThreeTen-Backport(如上所述)。 请参阅如何使用ThreeTenABP…。
ThreeTen-Extra项目使用其他类扩展了java.time。 该项目为将来可能在java.time中添加内容提供了一个试验场。 您可能会在这里找到一些有用的类,例如YearQuarter、YearQuarter、YearQuarter等。