DateTime does not match itself after unserialization

As you can see below, after serialization and unserializing, you get DateTime instances that are supposedly different:

scala> import org.joda.time.DateTime import org.joda.time.DateTime scala> val a = new DateTime() a: org.joda.time.DateTime = 2014-01-08T19:00:08.883+02:00 scala> val b = DateTime.parse(a.toString()) b: org.joda.time.DateTime = 2014-01-08T19:00:08.883+02:00 scala> a == b res0: Boolean = false 

According to AbstractInstant javadoc , equals "compares this object with the specified object for equality based on the millisecond moment, timeline, and time zone." So this should not be? What am I missing?

+6
source share
4 answers

Here is the only correct answer found by our own testing:

 DateTime a = new DateTime(); // uses default time zone System.out.println(a); // 2014-01-08T19:38:00.696+01:00 DateTime b = DateTime.parse(a.toString()); System.out.println(b); // 2014-01-08T19:38:00.696+01:00 System.out.println(a.getChronology()); // ISOChronology[Europe/Berlin] System.out.println(b.getChronology()); // ISOChronology[+01:00] System.out.println(a.equals(b)); // false!!! 

I assumed that in Scala, comparison with == really means comparison with equals (), as indicated in his comment by @ aris1348880, so I replaced the operator in the translation with java code, respectively.

Thus, the reason for the unsuccessful equality () - the comparison is obvious: this is the identifier of the time zone that is incorrectly printed in the toString() method of DateTime a . I consider this a bug in JodaTime because toString() should always print the entire state of the object's immutable value. By the way, in this detail the old java.util.Date even worse! Well, since the work is around, you can use the JodaTime formatting mechanism to print correctly. A.

 System.out.println( DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'['ZZZ']'").print(a)); // Output: 2014-01-08T19:38:00.696[Europe/Berlin] 

To make the behavior more understandable:

The DateTime constructor uses the default time zone (in my Europe / Berlin test). Its toString () method prints the offset instead, not the real timezone (this is a problem).

The DateTime-parse () method uses, according to the JodaTime documentation, ISODateTimeFormat # dateTimeParser () , which again can only analyze offsets, but in this code it was also using only biased information, and not with a real time zone, otherwise parsing would stop with an exception.

In both cases, DateTime instances are created in different ways with different time zones / offsets and, therefore, with different chronologies. Thus, equals () - the result at first glance is amazing, but understandable.

+11
source

I discovered the problem on GitHub, here is the author's answer :

Once upon a time, I chose the format toString DateTime, and I missed including the full state of the value type. As a result, two objects look as if they are equal (toString), but they are not. It was a mistake, as it caused such confusion. Unfortunately, it cannot be fixed.

The parsing behavior is also unsuccessful, as it focuses too much on bias and not enough in the time zone (since ISO-8601 does not process time zone identifiers). Again, it's too late to make a change here.

+4
source

I don't have org.joda.time.DateTime, but I just tried the test with java.util.Date.

You should try the following:

 val a = new DateTime() val b = new DateTime(a.getMillis()) a == b 

I also tried this:

 import org.joda.time.DateTime; public class TestDateTime { public static void main(String[] args) { DateTime a = new DateTime(); System.out.println(a.toString()); DateTime b = DateTime.parse(a.toString()); System.out.println(b.toString()); System.out.println(a.equals(b)); } } 

and this is the result:

 2014-01-08T19:05:52.182+01:00 2014-01-08T19:05:52.182+01:00 false 

And the problem is that equals of DateTime fail due to different time zones. I think it is wrong to accept the equivalence of two DateTime instances created this way.

When serializing and deserializing java.util.Date, a long (wrapped value) is not passed to a string.

+3
source

== will compare the link, equals() compares the values. Try a.equals(b)

Send a message: What is the difference between == vs equals () in Java?

-1
source

All Articles