Rectangle 27 0

Java: Why is the Date constructor deprecated, and what do I use instead?


Calendar requires an extra object and like 8 lines more code to do the same thing which is create a Date object from what I can tell. It's confusing and seems unnecessary when you just need a Date and not a timezone adjusted variable.

The specific Date constructor is deprecated, and a Calendar should be used instead. The JavaDoc for Date describes which constructors are deprecated and how to replace them using a Calendar.

Note
Rectangle 27 0

Java: Why is the Date constructor deprecated, and what do I use instead?


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 );
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();
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

Avoid the notoriously troublesome java.util.Date & java.util.Calendar classes

  • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Part of the standard Java API with a bundled implementation.

A java.util.Date has both a date and a time portion. You ignored the time portion in your code. So the Date class will take the beginning of the day as defined by your JVMs default time zone and apply that time to the Date object. So the results of your code will vary depending on which machine it runs or which time zone is set. Probably not what you want.

If you want just the date, without the time portion, such as for a birth date, you may not want to use a Date object. You may want to store just a string of the date, in ISO 8601 format of YYYY-MM-DD. Or use a LocalDate object from Joda-Time (see below).

In this case the code for java.time is nearly identical to that of Joda-Time.

Props for actually mentioning the root cause and providing coverage of all available alternatives.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The java.util.Date, java.util.Calendar, and java.text.SimpleDateFormat classes were rushed too quickly when Java first launched and evolved. The classes were not well designed or implemented. Improvements were attempted, thus the deprecations youve found. Unfortunately the attempts at improvement largely failed. You should avoid these classes altogether. They are supplanted in Java 8 by new classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

We get a time zone (ZoneId), and construct a date-time object assigned to that time zone (ZonedDateTime). Then using the Immutable Objects pattern, we create new date-times based on the old objects same instant (count of nanoseconds since epoch) but assigned other time zone. Lastly we get a LocalDate which has no time-of-day nor time zone though notice the time zone applies when determining that date (a new day dawns earlier in Oslo than in New York for example).

Note
Rectangle 27 0

Java: Why is the Date constructor deprecated, and what do I use instead?


Calendar.set(year + 1900, month, date)

In general, the Date API only supports the modern western calendar, has idiosyncratically specified components, and behaves inconsistently if you set fields.

Notice that the year field is the number of years since 1900, so your sample code most likely won't do what you expect it to do. And that's the point.

One reason that the constructor is deprecated is that the meaning of the year parameter is not what you would expect. The javadoc says:

The Calendar and GregorianCalendar APIs are better than Date, and the 3rd-party Joda-time APIs were generally thought to be the best. In Java 8, they introduced the java.time packages, and these are now the recommended alternative.

Note
Rectangle 27 0

Java: Why is the Date constructor deprecated, and what do I use instead?


Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 1988);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1);
Date dateRepresentation = cal.getTime();

+one for providing a working solution

By saying "doesn't work well with internationalization", do you mean that for Date, you cannot assign TimeZone for it? Thanks

Just to add, this will take the default timezone in consideration. If we want to specify any other timezone, we can use Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(<timezone id>));

The java.util.Date class isn't actually deprecated, just that constructor, along with a couple other constructors/methods are deprecated. It was deprecated because that sort of usage doesn't work well with internationalization. The Calendar class should be used instead:

What Date did was parse a String, so instead we now have to substring a String which contains the year, month and day? Seems like a lot of extra hassle for something which in most cases doesn't need such complex logic and methods added to it.

Note
Rectangle 27 0

Java: Why is the Date constructor deprecated, and what do I use instead?


Similar to what binnyb suggested, you might consider using the newer Calendar > GregorianCalendar method. See these more recent docs:

Note
Rectangle 27 0

Java: Why is the Date constructor deprecated, and what do I use instead?


Most Java developers currently use the third party package Joda-Time. It is widely regarded to be a much better implementation.

Note
Rectangle 27 0

Java: Why is the Date constructor deprecated, and what do I use instead?


LocalDate localDate = LocalDate.of(1985, 1, 1);

And then if you really really need a java.util.Date, you can use the suggestions in this question.

For more info, check out the API or the tutorials for Java 8.

I came across this question as a duplicate of a newer question which asked what the non-deprecated way to get a Date at a specific year, month, and day was.

The answers here so far say to use the Calendar class, and that was true until Java 8 came out. But as of Java 8, the standard way to do this is:

Note
Rectangle 27 0

Java: Why is the Date constructor deprecated, and what do I use instead?


Calendar c = Calendar.getInstance();
c.set(2010, 2, 7); // NB: 2 means March, not February!
System.err.println(c.getTime());
Sun Mar 07 10:46:21 CET 2010
Sun Mar 07 10:57:51 CET 2010

Please note that Calendar.getTime() is nondeterministic in the sense that the day time part defaults to the current time.

Running the exact same code a couple of minutes later yields:

So, while set() forces corresponding fields to correct values, it leaks system time for the other fields. (Tested above with Sun jdk6 & jdk7)

To reproduce, try running following code a couple of times:

Note
Rectangle 27 0

Java: Why is the Date constructor deprecated, and what do I use instead?


java.util.Calendar

Date itself is not deprecated. It's just a lot of its methods are. See here for details.

Note