问题描述
我想要使用日期对象的今天的日期,所以我在 System.currentTimeInMillis
构造函数中传递了 Date()
但它返回年份为 121
然后我使用了 Calendar
类,它解决了我的问题,但为什么 Date()
类一开始没有工作?
解决方法
tl;博士
仅使用 java.time 类。切勿使用旧的 Date
/Calendar
类。
java.time.LocalDate.now()
避免遗留的日期时间类
您正在使用与最早版本的 Java 捆绑在一起的糟糕的日期时间类。这些类是由不了解日期时间处理的人编写的,他们的设计选择非常糟糕。
Sun、Oracle 和 JCP 社区在几年前随着 JSR 310 的一致采用而放弃了这些类。我建议您也放弃它们。仅使用 java.time 类进行日期时间工作。
121 + 1900 = 2021
➥ 回答您的具体问题:在这些遗留类的众多问题中,年份表示为 1900 年。引用 Javadoc:
年份 y 由整数 y - 1900 表示。
因此,将 1900 添加到您的 121 年会得到 2021 年。谜团解决了。但没关系,继续使用 java.time 代替。
java.time
如果您只需要日期,不需要时间和时区,请使用 LocalDate
。
LocalDate today = LocalDate.now() ;
最好指定一个期望/预期的时区,通过它感知当前日期,而不是隐式依赖 JVM 的当前默认时区。对于任何给定时刻,日期在全球各地因时区而异,日本东京为“明天”,而美国俄亥俄州托莱多仍为“昨天”。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( z ) ;
如果您希望在特定时区看到当前时刻,请使用 ZonedDateTime
。
ZonedDateTime now = ZonedDateTime.now( z ) ;
如果您想要以 UTC 显示的当前时刻,请使用 Instant
。
Instant now = Instant.now() ;
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date
、Calendar
和 SimpleDateFormat
。
要了解更多信息,请参阅 Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为 JSR 310。
现在位于 Joda-Time 的 maintenance mode 项目建议迁移到 java.time 类。
您可以直接与您的数据库交换 java.time 对象。使用符合 JDBC driver 或更高版本的 JDBC 4.2。不需要字符串,不需要 java.sql.*
类。 Hibernate 5 和 JPA 2.2 支持 java.time。
从哪里获取 java.time 类?
-
Java SE 8、Java SE 9、Java SE 10、Java SE 11 和更高版本 - 具有捆绑实现的标准 Java API 的一部分。
- Java 9 带来了一些小功能和修复。
-
Java SE 6 和 Java SE 7
- 大部分 java.time 功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7。
-
Android
- 更高版本的 Android (26+) 捆绑了 java.time 类的实现。
- 对于早期的 Android (API desugaring 的进程带来了 subset of the java.time 最初未内置于 Android 中的功能。
- 如果脱糖不能满足您的需求,ThreeTenABP 项目会将 ThreeTen-Backport(上文提到的)适配到 Android。见How to use ThreeTenABP…。