Java: Why Is the Date Constructor Deprecated, and What Do I Use Instead

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

tl;dr

LocalDate.of( 1985 , 1 , 1 )

…or…

LocalDate.of( 1985 , Month.JANUARY , 1 )

Details

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 you’ve found. Unfortunately the attempts at improvement largely failed. You should avoid these classes altogether. They are supplanted in Java 8 by new classes.

Problems In Your Code

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 JVM’s 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).

Joda-Time

First thing to learn in Java: Avoid the notoriously troublesome java.util.Date & java.util.Calendar classes bundled with Java.

As correctly noted in the answer by user3277382, use either Joda-Time or the new java.time.* package in Java 8.

Example Code in 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 );

Dump to console…

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

When run…

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

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

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 object’s 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).

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


About java.time

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.

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

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

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

  • 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….

Table of which java.time library to use with which version of Java or Android

Java's Date(...) constructor is deprecated; what does that mean?

Deprecated literally means disapproved of, but a more accurate translation would be retired. Deprecated means this method is still usable, but you should not use it. It will gradually be phased out. There is a new method to do the same thing. Deprecated methods are marked with a special Javadoc comment:

/**
*@deprecated Please now use newMethod()
*@see newMethod()
*/

Use:

  • Calendar.set(year + 1900, month, date, hrs, min)

or

  • GregorianCalendar(year + 1900, month, date, hrs, min).

As suggested by the API documentation.

java.util.Date(int,int,int) deprecated

What's the non-deprecated way to do this?

Java 8 to the rescue:

LocalDate localDate = LocalDate.of(2015, 3, 2);

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.

The Date(String) is deprecated

Use a DateFormat.parse method to convert a String to Date

String string = "January 2, 2010";
DateFormat format = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH);
Date date = format.parse(string);
System.out.println(date);

In your case it will be something like this

DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
Date date = format.parse(geoState.getString("fireTime"));
temp.setFireTime(date);

Java - Date constructor accepts a Date String, But deprecated. Tried alternatives, but no luck

Your parsing pattern is wrong. It does not match the date string representation. The MMM denotes a 3-letter localized month abbreviation, while you have 2-digit month number in your actual date, you need MM. You've also slashes / as date/month/year separator and not -. For the AM/PM marker you also need an a afterwards so that the right hh can be parsed.

This should work:

SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a"); 

For an explanation of those patterns, read the SimpleDateFormat javadoc.


I believe that your concrete functional requirement is to convert the given date string as specified by the pattern MM/dd/yyyy hh:mm:ss a into another date string format, as specified by the pattern MMM-dd-yyyy hh:mm:ss. In that case, you should then have two SimpleDateFormat instances, one which parses the string in the given pattern to a Date and another which formats the parsed Date to the given pattern. This should do what you want:

String inputDate = "07/28/2011 11:06:37 AM";
Date date = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a").parse(inputDate);
String outputDate = new SimpleDateFormat("MMM-dd-yyyy HH:mm:ss").format(date);
System.out.println(outputDate); // Jul-28-2011 11:06:37

Note that I changed hh in output to be HH because it would otherwise end up in 1-12 hour representation without an AM/PM marker. The HH represents it as 0-23 hour.

new Date(year,month,day) is deprecated

Wrong class

You are using a terrible date-time class that is now legacy. Supplanted years ago by the modern java.time classes.

LocalDate

For a date-only value without time-of-day and without time zone, use LocalDate.

LocalDate localDate = LocalDate.of( 1995 , 1 , 5 ) ;

Generate text in standard ISO 8601 format YYYY-MM-DD.

String output = localDate.toString() ;

Design your class to hold a LocalDate rather than a Date.

public class Employee 
{
private String givenName, surName ;
LocalDate whenHired ;

// Constructor
public Employee( String givenName , String surName , LocalDate whenHired )
{

}

}

Example usage.

Employee alice = new Employee( "Alice" , "Anderson" , LocalDate.of( 1995 , Month.JANUARY , 4 ) ) ;

Octal literal

new Date(1995,01,04)

Do not start a literal integer with a zero unless you mean octal (base 8) rather than decimal (base 10).

Java Date object constructor for getting string is deprecated

So, you look at the Javadoc for the deprecated method which specifies:

Deprecated. As of JDK version 1.1, replaced by DateFormat.parse(String s).

You then look up DateFormat.parse and proceed accordingly. You probably want to create a SimpleDateFormat - or better still, use Joda Time which is a much better date/time API.

When a method is deprecated, it's always a good idea to give an indication of what existing code should be migrated to, and ideally why the old method was deprecated. Follow this guidance when you deprecate your own methods... and whenever you try to use a deprecated method, check the documentation to see if it suggests a better alternative.

The parameterized constructors of the java.util.Date class are deprecated. What is the alternative?

Note: this answer was written in 2009. Since then, java.time has become the preferred date/time API in Java.


Ideally, use Joda Time instead. It's an infinitely superior API to the built-in one. You'd then want to choose between LocalDateTime and DateTime depending on your exact requirements (it's a complicated area - I'm not going to try to summarise in a sentence or two, but the docs do a good job).

If absolutely necessary, use a java.util.Calendar and convert that to a Date when you need to.

Are java.util.Date and java.util.Calendar deprecated?

Short answer: The new API java.time is way better than the old world with java.util.Date and java.util.Calendar. So yes, the new API should be preferred in new code.

For a quick overview: Once I had written a comparison of features in table form for various date-time-libraries. There is almost no feature which java.time is missing but exists in the old world:

  • configurable gregorian/julian cutover
  • printing based on the class FieldPosition (used in Swing-component FormattedTextField)

About deprecation: Although most parts of java.util.Date are deprecated since Java 1.1, the class itself (and java.util.Calendar, too) are not officially deprecated, just declared as de facto legacy. The support of the old classes is still important for the goal of backwards compatibility with legacy code. So Oracle will probably not stop the support at any time in the future. But maybe Oracle will apply more sophisticated deprecation strategies.

Future development: It is interesting that the release of Java-8 has not only incorporated a completely new date/time-API (java.time) but also seen some few enhancements to java.util.Calendar, for example Calendar.Builder or SHORT_STANDALONE etc. Well, I can only speculate but this also seems to indicate that Oracle is not willing to stop the support of the old API in the near future.



Related Topics



Leave a reply



Submit