Date() object inconsistency. Month, day and year are all wrong
现在是3/15/11,当我正在调用一个新的日期对象时:
我得到了回报
-
月份为2(
getMonth() ), -
当天为2(
getDay() ) -
而年份(
getYear() )为111。
这个惯例有理由吗?
直接来自班级的文件:
- A year y is represented by the integer y - 1900.
- A month is represented by an integer from 0 to 11; 0 is January, 1 is February, and so forth; thus 11 is December.
- A date (day of month) is represented by an integer from 1 to 31 in the usual manner.
至于
Returns the day of the week represented by this date. The returned value (0 = Sunday, 1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday, 5 = Friday, 6 = Saturday) represents the day of the week that contains or begins with the instant in time represented by this Date object, as interpreted in the local time zone.
2011年3月15日实际上是星期二。
Is there a reason for this convention?
原因是它是Date指定的javadoc; 看@matt b的答案。
如果您想要Joda时间使用的示例,请查看上面的链接。 在
TL;博士
1 2 3 | LocalDate // Modern class to represent a date-only value, without time-of-day, without time zone or offset-from-UTC. .now( ZoneId.of("Africa/Tunis" ) ) // Capture the current date as seen in the wall-clock time used by the people of a specific region (a time zone). .getYear() // Get year number, such as 2019 presently. |
…和:
1 | .getMonthValue() // Get month number, 1-12 for January-December. |
…和:
1 | .getDayOfMonth() // Get day-of-month number, 1-31. |
细节
显然你正在使用两个可怕的日期时间类
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,法国巴黎午夜过后几分钟是新的一天,而在魁北克蒙特利尔仍然是"昨天"。
如果未指定时区,则JVM会隐式应用其当前的默认时区。该默认值可能会在运行时(!)期间随时更改,因此您的结果可能会有所不同。最好明确指定您期望/预期的时区作为参数。如果关键,请与您的用户确认该区域。
以
1 2 | ZoneId z = ZoneId.of("America/Montreal" ) ; LocalDate today = LocalDate.now( z ) ; |
如果要使用JVM的当前默认时区,请求它并作为参数传递。如果省略,代码变得模糊不清,因为我们不确定您是否打算使用默认值,或者如果您像许多程序员一样,不知道这个问题。
1 | ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone. |
或指定日期。您可以将月份设置为一个数字,1月至12月的数字为1-12。
1 | 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. |
或者,更好的是,使用预定义的
1 | LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ; |
访问部分日期
java.time类使用合理的编号,1-12个月,1-7个星期几,年份编号如2019年是2019年等等。
1 2 3 4 | int year = ld.getYear() ; // The year, such as 2019 presently. int monthNumber = ld.getMonthValue() ; // Number of the month 1-12 for January-December. Month month = ld.getMonth() ; // Get the `Month` enum object, one of a dozen predefined objects (one for each month of the year). int dayOfMonth = ld.getDayOfMonth() ; // Get the day of the month, 1-31. |
关于java.time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如
要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要
从哪里获取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功能都被反向移植到Java 6& 7在ThreeTen-Backport。
-
Android的
- 更高版本的Android捆绑java.time类的实现。
- 对于早期的Android(<26),ThreeTenABP项目采用ThreeTen-Backport(如上所述)。请参见如何使用ThreeTenABP ....
ThreeTen-Extra项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的类,例如