Date()对象不一致。月,日和年都错了

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Date()对象不一致。月,日和年都错了相关的知识,希望对你有一定的参考价值。

现在是3/15/11,当我正在调用一个新的日期对象时:

Date now = new Date();

我得到了回报

  • 月份为2(getMonth()),
  • 当天为2(getDay()
  • 和年(getYear())为111。

这个惯例有理由吗?

答案

直接从the class's documentation

  • 年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.Datejava.sql.Date。在采用JSR 310时,两者都过时了,定义了它们的替代品,即现代java.time类。

LocalDate

LocalDate类表示没有时间且没有time zoneoffset-from-UTC的仅日期值。

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜过后几分钟是新的一天,而在Montréal Québec仍然是“昨天”。

如果未指定时区,则JVM会隐式应用其当前的默认时区。在运行时(!)期间,该默认值可能是change at any moment,因此您的结果可能会有所不同。最好明确指定您期望/预期的时区作为参数。如果关键,请与您的用户确认该区域。

proper time zone name的格式指定Continent/Region,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用2-4字母缩写,如ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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。同样适用于YearYearMonth

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.DateCalendarSimpleDateFormat

要了解更多信息,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规格是JSR 310

现在在Joda-Timemaintenance mode项目建议迁移到java.time班。

您可以直接与数据库交换java.time对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

(c)2006-2024 SYSTEM All Rights Reserved IT常识