Why is my Java Calendar.setTime() sporadically setting wrong times? - java

Using this code below, I noticed that sometimes the date gets formatted incorrecty. And to make it even more weird, sometimes timeStamp will have the right date, and timeStampCopy will have the wrong date, and visa versa.
public static Timestamp method(String date, DateFormat dateFormat) throws Exception {
// date is always "2017-02-17"
// original
GregorianCalendar gCal = new GregorianCalendar();
gCal.setTime(dateFormat.parse(date));
Timestamp timeStamp = new Timestamp(gCal.getTimeInMillis());
// copy
GregorianCalendar gCalCopy= new GregorianCalendar();
gCalCopy.setTime(dateFormat.parse(date));
Timestamp timeStampCopy = new Timestamp(gCalCopy.getTimeInMillis());
if (!timeStamp.toString().contains("2017-02-17"))
System.out.println(timeStamp.toString());
if (!timeStampCopy.toString().contains("2017-02-17"))
System.out.println(timeStampCopy.toString());
return timeStamp;
}
I'm not sure what could be causing it but I tried this using a Date object and am having the same issues. I thought it could be a parsing issue but since it's doing the same thing twice I'm not sure.
Below are some of the values that I'm getting:
timeStamp is: 2017-02-17 00:00:00.0
timeStampCopy is: 1700-02-17 00:00:00.0

You say that you are sharing the DateFormat instance between threads.
According to the Javadoc:
Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.
Note that this refers to external synchronization of access to the DateFormat instance, not the method. Making the method synchronized would only fix this problem if there are no other uses of the DateFormat instance.
You can either:
Explicitly synchronize around all code using the DateFormat instance (it is worth adding an #GuardedBy annotation to the variable, in order to document that you expect a lock to be held before using it);
Change the variable type to ThreadLocal<DateFormat> (and initialize the shared variable appropriately), which ensures that each thread has its own copy of the DateFormat.
The latter approach has lower contention, because each thread can proceed independent of the others. It also means that you can't accidentally omit the synchronization.
But, there are better libraries for handling dates and times, which were designed with the hindsight of problems like DateFormat's lack of thread safety. In Java 8, there is the java.time API; for earlier versions of Java, there is Jodatime.

The Answer by Turner is correct and should be accepted.
java.time is thread-safe
The java.time classes solve this problem by using immutable objects and making them inherently thread-safe.
LocalDate ld = LocalDate.of( "2017-02-17" );
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ld.atStartOfDay( z );
Generate a string in standard ISO 8601 format by calling toString. For other formats, use DateTimeFormatter class. Search Stack Overflow for many examples and discussions. No worries about threads, all thread-safe.
For a value in UTC, extract an Instant.
Instant instant = zdt.toInstant() ;
No need to use java.sql.Timestamp. Modern JDBC drivers can handle the java.time types via toObject and setObject methods. For older drivers convert using new methods added to the old classes.
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
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.

Related

How to check a null sql date in java

I am developing a hospital management system for an assignment.I want to view patient details and display "not discharged" if the column date_of_discharge is null.I'm using mysql as database.Do I want to convert sql date to java util date before checking it null?
NULL is nothing
Do I want to convert … before checking it null?
No.
As others commented, NULL means “nothing at all”. A NULL is the same across all data types. So no need to convert, cast, or parse when simply asking if the value is NULL or not.
Instead of checking not null,can I directly check whether it is null
Yes. Use IS NULL or IS NOT NULL.
SELECT * FROM patient WHERE date_of_discharge IS NULL ;
…or…
SELECT * FROM patient WHERE date_of_discharge IS NOT NULL ;
Avoid NULLs
display "not discharged" if the column date_of_discharge is null.
Following Dr. Chris Date’s advice, I avoid using NULL wherever possible, as if it were the work of the devil (which it may be!).
Instead, assign a certain value of your own arbitrary choosing to signify no-value-yet-assigned. Perhaps the epoch reference date of Unix time and other systems: the first moment of 1970 in UTC, 1970-01-01T00:00Z.
In Java, we have available as pre-defined constants: LocalDate.EPOCH and Instant.EPOCH.
Never cast between java.util.Date & java.sql.Date
convert sql date to java util date before checking it null
No, never cast between these types. You should ignore the fact that java.sql.Date inherits from java.util.Date. By inheriting, the java.sql.Date actually carries a time-of-day. Yet java.sql.Date portrays itself as representing a date-only value without time-of-day and without time zone — but this is only a pretense. As a workaround, to fulfill that pretense, that time-of-day is set to midnight of some time zone. But the java.util.Date always represents a moment in UTC. So by casting, you will inadvertently be mixing in the effect of some time zone.
Confusing? Yes. This is a terribly bad design, an awful hack, and is one of many reasons to avoid these old legacy date-time classes. Use java.time classes instead.
JDBC 4.2
As of JDBC 4.2 we can directly exchange java.time objects with the database. Use PreparedStatement::setObject and ResultSet::getObject methods.
The java.sql.Date class that pretends to hold a date-only value is supplanted by the java.time.LocalDate. The LocalDate class actually does hold only a date, without a time-of-day and without a time zone.
LocalDate localDate = myResultSet.getObject( … , LocalDate.class ) ;
…and…
myPreparedStatement.setObject( … , localDate ) ;
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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?
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 adds 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 bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

How to manually set the Daylight Saving (DST) shift date in Java

My country changed the the Daylight Saving shift date from "October 21" to "November 4" and we need to apply this in our back-end.
The appropriate solution is to update the Operating System configuration, but we have restrictions to do so (legacy dependencies). We are looking for a workaround.
Is it possible to use code and change the DST shift date programmatically?
GregorianCalendar gc = new GregorianCalendar();
gc.setTimeInMillis(0);
gc.set(2018, Calendar.OCTOBER, 21, 0, 0, 0);
gc.setTimeZone(TimeZone.getTimeZone("Brazil/East"));
XMLGregorianCalendar xml = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
System.out.println("XML Date: " + xml.toString());
Output must be -03:00:
XML Date: 2018-10-21T01:00:00.000-02:00
OS irrelevent
Your operating system configuration is irrelevant. Most Java implementations by default pick up their initial default time zone from the host OS upon launch. But the definition of the time zones is stored within the Java implementation.
Java time zone updater
So you need to update the time zone definitions within your Java implementation. Most implementations use the tz database also known as tzdata.
For the Oracle-branded Java implementation, Oracle provides the Timezone Updater Tool. That landing page has an as-of date of 2018-08, so perhaps your time zone’s changes have been included. But I suggest you investigate more closely to verify.
For other implementations, check with the vendor. They may have provided an updated version of the JVM to include the fresh tzdata. Or perhaps they too provide an updater tool. Or perhaps you can replace the tzdata file manually.
Avoid mangling zone with code
I strongly suggest you avoid trying to make artificial adjustments to the offset yourself in code. You will likely get it wrong. Date-time work in surprisingly tricky and confusing.
But if you insist, firstly avoid the terrible old legacy date-time classes such as GregorianCalendar & Calendar & Date. These were supplanted years ago by JSR 310. If you must interoperate with old code not yet updated to java.time, do your work in the modern classes and then at the end convert via new methods added to the old classes.
Use the modern the java.time classes, specifically:
Instant (for a moment in UTC)
OffsetDateTime (for a moment with an offset-from-UTC of hours-minutes-seconds but no time zone)
ZonedDateTime (for a moment in a particular time zone)
You can search Stack Overflow for many existing examples and explanations using these classes. You should focus on OffsetDateTime, ZoneOffset (rather than ZoneId), and Instant since you must avoid ZonedDateTime if your know your tzdata file to be outdated.
Same moment, different wall-clock time
OffsetDateTime::withOffsetSameInstant​
OffsetDateTime odt = OffsetDateTime.parse( "2018-10-21T01:00:00.000-02:00" ) ;
ZoneOffset offset = ZoneOffset.ofHours( -3 ) ;
OffsetDateTime odt2 = odt.withOffsetSameInstant​( offset ) ; // Same moment, same point on the timeline, different wall-clock time.
odt.toString(): 2018-10-21T01:00-02:00
odt2.toString(): 2018-10-21T00:00-03:00
In that example, both odt and odt2 represent the same simultaneous moment, the same point on the timeline. If you extract an Instant (a value in UTC), your results will be the same moment. Only their wall-clock time is different.
Instant instant1 = odt.toInstant() ; // Adjust to UTC.
Instant instant2 = odt2.toInstant() ;
boolean sameMoment = instant1.equals( instant2 ) ;
instant1.toString(): 2018-10-21T03:00:00Z
instant2.toString(): 2018-10-21T03:00:00Z
sameMoment = true
The Z on the end means UTC, an offset-from-UTC of zero, +00:00. The Z is pronounced “Zulu”. Defined by the ISO 8601 standard.
Different moment, same wall-clock time
OffsetDateTime::withOffsetSameLocal​
In contrast, you may want to force the time-of-day thereby representing a different moment. For that, use withOffsetSameLocal method. Be very aware that you are changing the meaning of data, you are moving to another point on the timeline.
OffsetDateTime differentMomentButSameTimeOfDay = odt. withOffsetSameLocal( offset ) ;
differentMomentButSameTimeOfDay.toString(): 2018-10-21T01:00-03:00
Extract the instant to see we have a different moment.
Instant differentInstant = differentMomentButSameTimeOfDay.toInstant() ;
differentInstant.toString(): 2018-10-21T04:00:00Z
Notice the 4 AM UTC versus 3 AM UTC seen above. This moment here occurs an hour after the moment above. Two different points on the timeline.
Do not attempt this work until you fully comprehend the concept of points on the timeline, and changing between points being entirely different than adjusting offsets. Practice extensively before doing real work. Half-hearted guessing will land you in a world of hurt and headache.
And, as I suggested above, your time would be much better spent installing updated tzdata files rather than hacking these offsets.
Live code
See all the code above run live at IdeOne.com.
Update tzdata everywhere
For best results, you should be updating the tzdata (or equivalent) in all these various places:
Your operating systems
Your JVMs
Your database engines, such as Postgres
Any libraries bundling their own time zone info (ex: Joda-Time)
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 process of API desugaring brings 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….
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.

GregorianCalendar Class in Java

I am trying to get current time in other time zone. I used this code for this:
GregorianCalendar calender = new
GregorianCalendar(TimeZone.getTimeZone("Asia/Bangkok"));
System.out.println(calender.getTime());
But, when I am running this code, this code provides the current time in CET as the time in my local machine is in CET.
I am confused. Then why there is scope to provide a TimeZone in constructor?
Ahh, the joys of the Java Date/Time API ...
What you want (aside from a better API, such as Joda Time) is a DateFormat. It can print dates in a time zone you specify. You don't need Calendar for that.
dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Bangkok"));
dateFormat.format(new Date());
Calendar is for time manipulations and calculations. For example "set the time to 10 AM". Then it needs the timezone.
When you are done with these calculations, then you can get the result by calling calendar.getTime() which returns a Date.
A Date is essentially a universal timestamp (in milliseconds since 1970, with no timezone information attached or relevant). If you call toString on a Date it will just print something in your default timezone. For more control, use DateFormat.
What you are doing right now is:
Getting a calendar in Bangkok time zone
get the Date object for this time( which is in ms since some date January 1, 1970, 00:00:00 GMT)
print out this Date in your timezone (Date.toString())
You should use a Formatter class to get the result you want. e.g. SimpleDateFormat
An alternative solution would be to use a less confusing Date/Time library. e.g. JodaTime or the new java.time package of Java8
tl;dr
ZonedDateTime.now( ZoneId.of( "Asia/Bangkok" ) )
java.time
The legacy date-time classes you are using are simply terrible, flawed in design and in implementation, built by people who did not understand date-time handling. Avoid those classes entirely.
Use only the modern java.time classes defined in JSR 310.
ZoneId z = ZoneId.of( "Asia/Bangkok" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
Generate text in standard ISO 8601 format, wisely extended to append the name of the time zone in square brackets.
String output = zdt.toString() ;
For other formats, use DateTimeFormatter as seen on hundreds of other Questions and Answers.
See this code run live at IdeOne.com.
2020-02-15T12:27:31.118127+07:00[Asia/Bangkok]
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.
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 adds 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 bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

Java Dates - What's the correct class to use?

So the whole Java Date/Calendar/GregorianCalendar thing is obviously a joke. What's the right Date class to use?
Edit: Building an SDK for third parties on Android where the application needs to provide a date
More Edit: Things that make this so obviously a joke:
99% of Date is deprecated
Date's Year is offset from 1900
Date's Month is zero-indexed while day is one-indexed
Dates are mutable
You're supposed to use a Calendar to create a date...
... except you really have to use a GregorianCalendar
Do a significant percent of developers want to use a different calendar?
Calendar.getTime() returns a Date
There's no Date math (like how far apart are two dates in years)
Messing with milliseconds since epoch doesn't count
You can't chain parts together to get an expression (like the date one year ago today)
Probably more stuff
Joda-Time. Even on Android.
If you want to stick to Java SE classes, it depends on what you're trying to do.
Edit: You keep changing your question. Date and Calendar.
Avoid the legacy date-time classes
So the whole Java Date/Calendar/GregorianCalendar thing is obviously a joke.
Yes, the old date-time classes bundled with the earliest versions of Java are an awful mess. Badly designed, clumsy attempts at improvements, many hacks.
But to be fair, those classes were a valiant effort in addressing a surprisingly tricky topic that the entire information industry has ignored for decades. Based on prior work at Taligent and IBM, the authors of those classes at least made an attempt where virtually all other programming languages, platforms, and tools take a pass with only the barest minimum of support for date-time handling.
Fortunately we now have the industry-leading java.time classes (JSR 310) built into Java 8 and later. These were inspired by the success of the Joda-Time project. Indeed both efforts were led by the same man, Stephen Colebourne.
java.time
Every single one of your bullet items of complaint is rectified by using java.time instead.
99% of Date is deprecatedInstant replaces java.util.Date. AFAIK, nothing is deprecated in java.time in Java 8 & Java 9.
Date's Year is offset from 1900Years have sane numbering in java.time, 2018 is the year 2018.
Date's Month is zero-indexed while day is one-indexedMonths have sane numbering in java.time, 1-12 for January-December. Even better, the Month enum provides objects to represent each month of the year rather than a mere integer number. So you get valid values, type-safety, and self-documenting code.
Dates are mutableVirtually all of java.time is immutable. Any calls to alter some aspect of a java.time object returns a new and distinct object. Even constructors are hidden, with static factory methods used instead.
You're supposed to use a Calendar to create a date...ZonedDateTime replaces java.util.Calendar.
... except you really have to use a GregorianCalendarZonedDateTime replaces java.util.GregorianCalendar too. The java.time framework uses interfaces mostly for internal-use only, encouraging apps to use only the concrete classes. This was a design decision specific to the needs of java.time as a framework and does not mean you should the same in your apps.
Do a significant percent of developers want to use a different calendar?Yes. Other calendaring systems are used by many people around the globe. The java.time framework provides for this via the Chronology interface and AbstractChronology class. The default chronology is IsoChronology following the ISO 8601 standard used generally in the West. In Java 8 & 9, other bundled chronologies include Thai Buddhist, Hijrah (Islamic), Minguo (Taiwan), and Japanese Imperial. Third-parties may implement others. In the ThreeTen-Extra project, you’ll find additional chronologies for Accounting (proleptic 52/53-week per US IRS Publication 538 and the International Financial Reporting Standards), the British Julian-Gregorian cutover, Coptic (Christian Egypt), Discordian (Erisian), Ethiopic, International Fixed (Cotsworth plan, the Eastman plan), proleptic Julian, Pax, and Symmetry010 & Symmetry454. If only someone would implement the French Republican Calendar.
Calendar.getTime() returns a DateJust use Instant as your basic building-block class in java.time, always representing a moment in UTC with a resolution of nanoseconds. The other types such as OffsetDateTime & ZonedDateTime can convert back-and-forth with Instant.
There's no Date math (like how far apart are two dates in years)The java.time classes have many convenient plus…/minus… methods. Furthermore, java.time provides powerful TemporalAduster implementations as well as enabling you to write your own. Also look to the ChronoUnit::between method, such as ChronoUnit.YEARS.between( thisLocalDate , that LocalDate ).
Messing with milliseconds since epoch doesn't countLook to Instant::toEpochMilli and Instant.ofEpochMilli if you must use count-from-epoch, but certainly not advisable. Better to use java.time objects and ISO 8601 strings to represent date-time values.
You can't chain parts together to get an expression (like the date one year ago today)The java.time classes are definitely designed for call-chaining. Example: LocalDate.now( ZoneId.of( "Europe/Paris" ) ).minusYears( 1 ).getDayOfWeek().getDisplayName( TextStyle.FULL , Locale.FRANCE ) > dimanche. Sometimes appropriate, but don’t go nuts with it — that’s my advice.
Probably more stuffYes many more problems with the old legacy classes. You will find java.time to be a radical departure from the old stuff, thoroughly modern and well-designed, a gigantic improvement.
One of the other problem areas is exchanging date-time values with a database. Note that with a JDBC driver compliant with JDBC 4.2 or later (JSR 221), you can avoid the date-time related java.sql classes such as java.sql.Timestamp classes. Those old classes are related to the troublesome old legacy classes, and are no longer needed.
myPreparedStatement.setObject( … , instant ) ;
…and…
Instant instant = myResultSet.getObject( … , Instant.class ) ;
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The "right" date type totally depends on your application; however, java.util.Calendar is generally accepted as the replacement for java.util.Date as it provides more functionality (especially regarding extraction of individual date elements like year, month, etc). In reality, Date can be much easier to use for certain situations (and is the one used by Java's own DateFormat classes), so it's a judgement call.
It's not difficult to convert between the two so I would pick one and stick with it consistently for your API. If I were to pick one I'd use Date because it's the simplest, IMHO.

A non-deprecated exact equivalent of Date(String s) in Java?

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.
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);
}
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.
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.
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()
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.
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.
tl;dr
ZonedDateTime.format(
input ,
DateTimeFormatter.ofPattern(
"EEE MMM dd HH:mm:ss zzz uuuu" ,
Locale.ENGLISH
)
)
java.time
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).
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.
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 adds 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 bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

Categories

Resources