我来自c#世界,所以对Java还不是很有经验。Eclipse刚刚告诉我Date已弃用:
Person p = new Person();
p.setDateOfBirth(new Date(1985, 1, 1));
为什么?应该用什么(尤其是在上述情况下)来代替呢?
我来自c#世界,所以对Java还不是很有经验。Eclipse刚刚告诉我Date已弃用:
Person p = new Person();
p.setDateOfBirth(new Date(1985, 1, 1));
为什么?应该用什么(尤其是在上述情况下)来代替呢?
当前回答
我从Java安全代码指南中得到了这个
本节中的示例广泛使用java.util.Date 一个可变API类的例子。在应用程序中是这样的 最好使用新的Java日期和时间API (Java . Time .*) 被设计为不可变的。
其他回答
由于Date构造函数已弃用,您可以尝试此代码。
import java.util.Calendar;
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 6);// for 6 hour
calendar.set(Calendar.MINUTE, 0);// for 0 min
calendar.set(Calendar.SECOND, 0);// for 0 sec
calendar.set(1996,0,26);// for Date [year,month(0 to 11), date]
Date date = new Date(calendar.getTimeInMillis());// calendar gives long value
String mConvertedDate = date.toString();// Fri Jan 26 06:00:00 GMT+05:30 1996
不推荐使用构造函数的一个原因是year形参的含义不是您所期望的。javadoc说:
从JDK 1.1版开始,由Calendar取代。设置(年+ 1900,月,日期)。
请注意,year字段是自1900年以来的年份,因此您的示例代码很可能不会执行您期望的操作。这就是重点。
一般来说,Date API只支持现代西方日历,具有特殊指定的组件,并且在设置字段时行为不一致。
Calendar和GregorianCalendar api比Date更好,而第三方Joda-time api通常被认为是最好的。在Java 8中,他们引入了Java。时间包,现在这些是推荐的替代方案。
博士tl;
LocalDate.of( 1985 , 1 , 1 )
…or…
LocalDate.of( 1985 , Month.JANUARY , 1 )
细节
java.util。日期、java.util。Calendar和Java .text. simpledateformat类在Java最初推出和发展时都是匆忙完成的。这些类没有很好地设计或实现。我们尝试了改进,因此出现了您所发现的问题。不幸的是,改进的尝试基本上失败了。你应该完全避免这些类。它们在Java 8中被新的类所取代。
代码中的问题
date包含日期部分和时间部分。您忽略了代码中的时间部分。因此,Date类将接受由JVM默认时区定义的一天的开始,并将该时间应用于Date对象。因此,代码的结果将取决于它运行的机器或设置的时区。可能不是你想要的。
如果只需要日期,而不需要时间部分,例如出生日期,则可能不希望使用date对象。您可能希望仅存储日期的字符串,以ISO 8601格式YYYY-MM-DD存储。或者使用Joda-Time中的LocalDate对象(见下文)。
乔达时间
在Java中要学习的第一件事是:避免与Java绑定的Java. util. date和Java. util. calendar类。
正如user3277382的回答中正确指出的那样,使用Joda-Time或新的java.time。*包在Java 8。
Joda-Time 2.3中的示例代码
DateTimeZone timeZoneNorway = DateTimeZone.forID( "Europe/Oslo" );
DateTime birthDateTime_InNorway = new DateTime( 1985, 1, 1, 3, 2, 1, timeZoneNorway );
DateTimeZone timeZoneNewYork = DateTimeZone.forID( "America/New_York" );
DateTime birthDateTime_InNewYork = birthDateTime_InNorway.toDateTime( timeZoneNewYork );
DateTime birthDateTime_UtcGmt = birthDateTime_InNorway.toDateTime( DateTimeZone.UTC );
LocalDate birthDate = new LocalDate( 1985, 1, 1 );
转储到控制台…
System.out.println( "birthDateTime_InNorway: " + birthDateTime_InNorway );
System.out.println( "birthDateTime_InNewYork: " + birthDateTime_InNewYork );
System.out.println( "birthDateTime_UtcGmt: " + birthDateTime_UtcGmt );
System.out.println( "birthDate: " + birthDate );
运行时……
birthDateTime_InNorway: 1985-01-01T03:02:01.000+01:00
birthDateTime_InNewYork: 1984-12-31T21:02:01.000-05:00
birthDateTime_UtcGmt: 1985-01-01T02:02:01.000Z
birthDate: 1985-01-01
java.time
在本例中是java代码。时间与约达时间几乎相同。
我们得到一个时区(ZoneId),并构造一个分配给该时区的日期-时间对象(zoneeddatetime)。然后使用Immutable Objects模式,基于旧对象的相同瞬间(epoch以来的纳秒计数)创建新的日期时间,但分配了其他时区。最后,我们得到一个LocalDate,它没有时间,也没有时区,但请注意,在确定日期时,时区适用于该日期(例如,奥斯陆的新一天比纽约的黎明早)。
ZoneId zoneId_Norway = ZoneId.of( "Europe/Oslo" );
ZonedDateTime zdt_Norway = ZonedDateTime.of( 1985 , 1 , 1 , 3 , 2 , 1 , 0 , zoneId_Norway );
ZoneId zoneId_NewYork = ZonedId.of( "America/New_York" );
ZonedDateTime zdt_NewYork = zdt_Norway.withZoneSameInstant( zoneId_NewYork );
ZonedDateTime zdt_Utc = zdt_Norway.withZoneSameInstant( ZoneOffset.UTC ); // Or, next line is similar.
Instant instant = zdt_Norway.toInstant(); // Instant is always in UTC.
LocalDate localDate_Norway = zdt_Norway.toLocalDate();
关于java.time
java。时间框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期-时间类,如java.util。日期,日历和简单日期格式。
要了解更多,请参阅Oracle教程。搜索Stack Overflow可以找到很多例子和解释。规范是JSR 310。
Joda-Time项目现在处于维护模式,建议迁移到java。时间类。
你可以交换java。Time对象直接使用数据库。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要java。sql。*类。Hibernate 5和JPA 2.2支持java.time。
从哪里获取java。时间类?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation. Java 9 brought some minor features and fixes. Java SE 6 and Java SE 7 Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport. Android Later versions of Android (26+) bundle implementations of the java.time classes. For earlier Android (<26), the latest Android tooling enables a process known as API desugaring to provide a subset of the java.time functionality not originally built into Android. If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
我偶然发现这个问题是一个新问题的重复,该问题询问在特定的年、月和日获得日期的非弃用方法是什么。
到目前为止,这里的答案是使用Calendar类,这在Java 8出现之前是正确的。但是从Java 8开始,这样做的标准方法是:
LocalDate localDate = LocalDate.of(1985, 1, 1);
如果你真的需要java。util。约会,你可以使用这个问题中的建议。
要了解更多信息,请查看Java 8的API或教程。
类似于binnyb的建议,您可以考虑使用较新的Calendar > GregorianCalendar方法。请看这些最新的文档:
http://download.oracle.com/javase/6/docs/api/java/util/GregorianCalendar.html