Reputation: 29342
I have old code that uses new Date(dateString)
to parse a date string. Compiling the code produces the deprecation warning Date(java.lang.String) in java.util.Date has been deprecated
.
The javadoc unhelpfully advises me to use DateFormat.parse()
, even though the DateFormat
class does not have a static parse
method.
Now, I know how to use SimpleDateFormat
, but I want to make sure I'm getting the exact same behaviour of the deperecated Date
constructor.
Upvotes: 27
Views: 40716
Reputation: 484
To parse a date time string in ISO format you should use the DateFormat like this:
java.text.DateFormat.getDateInstance().parse(dt);
With SimpleDateFormat you need to know the format.
Upvotes: 2
Reputation: 338496
ZonedDateTime.format(
input ,
DateTimeFormatter.ofPattern(
"EEE MMM dd HH:mm:ss zzz uuuu" ,
Locale.ENGLISH
)
)
The terrible Date
and DateFormat
classes were supplanted years ago by the modern java.time classes with the adoption of JSR 310.
The constructor you reference is actually calls on the static method Date.parse
. As that documentation explains, that method takes a variety of formats. There is single point for the same behavior in java.time. However, I would doubt your app is encountering all those various format syntaxes simultaneously.
I suggest you look at the specific formats used by your actual data. Then craft a collection of DateTimeFormatter
objects to match. Note that unlike the legacy classes, the java.time classes are entirely thread-safe. So you can keep one set of formatters around for use repeatedly throughout your app and across threads.
For the formatting pattern shown in the accepted Answer, here is the equivalent in java.time using the DateTimeFormatter
class. Note that you should explicitly state your desired/expected locale rather than rely implicitly on the JVM’s current default locale.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM dd HH:mm:ss zzz uuuu" , Locale.ENGLISH ) ;
ZonedDateTime zdt = ZonedDateTime.format( input , f ) ;
You should avoid using the legacy date-time classes such as java.util.Date
wherever possible. But if you must have a Date
to interoperate with old code not yet updated to java.time, you can convert. Look to new conversions methods added to the old classes.
The misnamed java.util.Date
represents a moment in UTC. Its modern equivalent
is the java.time.Instant
class. We can extract an Instant
from our ZonedDateTime
. Then convert to a Date
.
Instant instant = zdt.toInstant() ; // Adjust from time zone to UTC.
java.util.Date d = Date.from( instant ) ; // Convert from modern class `Instant` to legacy class `Date`.
Going the other direction.
Instant instant = d.toInstant() ; // Convert from legacy class `Date` to modern class `Instant`.
ZonedDateTime zdt = instant.atZone( ZoneId.of( "Pacific/Auckland" ) ) ; // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).
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.
Where to obtain 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.
Upvotes: 1
Reputation: 29342
Here's my guess (I posted as community wiki so you can vote up if I'm right):
Date parsed;
try {
SimpleDateFormat format =
new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
parsed = format.parse(dateString);
}
catch(ParseException pe) {
throw new IllegalArgumentException(pe);
}
Upvotes: 54
Reputation: 1988
If you take a look at source of the Date.parse(String s) method that Nicolas mentions, you'll see that it will be difficult or impossible to construct a date format that exactly reproduces the behavior.
If you just want to eliminate the warning, you could put @SuppressWarnings({“deprecation”})
outside the method calling the Date(String) constructor.
If you really want to ensure future access to this behavior with future JREs, you might be able to just extract the method from the JDK sources and put it into your own sources. This would require a careful read of the source code licenses and consideration of their application to your specific project, and might not be permissible at all.
Upvotes: 4
Reputation: 272257
SimpleDateFormat is the way to go. Can I point out, however, that you may feel compelled to define one SimpleDateFormat instance and build Date objects using this. If you do, beware that SimpleDateFormat is not thread-safe and you may be exposing yourself to some potentially hard-to-debug issues!
I'd recommend taking this opportunity to look at Joda which is a much better thought-out (and thread-safe) API. It forms the basis of JSR-310, which is the new proposed Java Date API.
I understand this is a bit more work. However it's probably worthwhile given that you're having to refactor code at the moment.
Upvotes: 8
Reputation: 24759
Short answer (before further investigation) is: no, it is not equivalent. the Date(String toParse) constructor is equivalent to the parse method of the class Date (which is also deprecated)... And the javadoc of this method claims:
Note that this is slightly different from the interpretation of years less than 100 that is used in SimpleDateFormat.
If it is the only change, I guess you can go on this way.
Upvotes: 2
Reputation: 113310
DateFormat has static methods that return DateFormat instances. I don't know which one (if any) has the same behavior as Date(String s)
but here you go:
DateFormat.getInstance()
DateFormat.getDateInstance()
DateFormat.getTimeInstance()
DateFormat.getDateTimeInstance()
Upvotes: 2