Date()对象不一致。月,日和年都错了
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Date()对象不一致。月,日和年都错了相关的知识,希望对你有一定的参考价值。
现在是3/15/11,当我正在调用一个新的日期对象时:
Date now = new Date();
我得到了回报
- 月份为2(
getMonth()
), - 当天为2(
getDay()
) - 和年(
getYear()
)为111。
这个惯例有理由吗?
- 年y由整数y - 1900表示。
- 一个月由0到11的整数表示; 0是1月,1是2月,依此类推;因此11月是12月。
- 日期(月中的某天)以通常的方式由1到31的整数表示。
至于getDay()
:
返回此日期表示的星期几。返回值(0 =星期日,1 =星期一,2 =星期二,3 =星期三,4 =星期四,5 =星期五,6 =星期六)表示包含或以此时间表示的时刻开始的星期几日期对象,在本地时区中解释。
2011年3月15日实际上是星期二。
这个惯例有理由吗?
原因是它是Date指定的javadoc;看@matt b的答案。
Date
API是在JDK 1.0时代创建的,众所周知,它在许多领域都存在问题。这就是大多数Date方法被标记为Deprecated的原因。 (顺便说一句,这意味着建议您不要在新代码中使用它们!)
Calendar
API是对Date
的重大改进,但迄今为止用于处理Java中日期/时间值的最佳API是第三方Joda time API。
如果您想要Joda时间使用的示例,请查看上面的链接。在GregorianCalendar
javadocs中有一个日历用法的例子。有关日历用法的更多示例可以在this page上找到。
tl;dr
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.
…和:
.getMonthValue() // Get month number, 1-12 for January-December.
…和:
.getDayOfMonth() // Get day-of-month number, 1-31.
Details
显然你正在使用两个可怕的日期时间类别中的任何一个,java.util.Date
或java.sql.Date
。在采用JSR 310时,两者都过时了,定义了它们的替代品,即现代java.time类。
LocalDate
LocalDate
类表示没有时间且没有time zone或offset-from-UTC的仅日期值。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜过后几分钟是新的一天,而在Montréal Québec仍然是“昨天”。
如果未指定时区,则JVM会隐式应用其当前的默认时区。在运行时(!)期间,该默认值可能是change at any moment,因此您的结果可能会有所不同。最好明确指定您期望/预期的时区作为参数。如果关键,请与您的用户确认该区域。
以proper time zone name的格式指定Continent/Region
,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4字母缩写,如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
如果要使用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。同样适用于Year
和YearMonth
。
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Accessing parts of a date
java.time类使用合理的编号,1-12个月,1-7个星期几,年份编号如2019年是2019年等等。
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.
About 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.*
类。
从哪里获取java.time类?