Fog Creek Software
g
Discussion Board




Why doesn't Java have an immutable Date class?

Before I go and write my own, anybody know of any reasons why Sun didn't include an immutable Date class?  Are there special pitfalls which caused them to make Date and Calendar mutable?  Links to any articles from Sun itself would be most useful.

T. Norman
Saturday, September 27, 2003

I was just reading about this the other day. Sun realizes that it was a mistake to make them mutable, but is not going to fix it. 

Quote is from: http://developer.java.sun.com/developer/community/chat/JavaLive/2003/jl0729.html

> Josh Bloch: I wish I could say that we plan to
> rework Date, but we don't. This is clearly one
> class that we got wrong; it never should have
> been mutable. But it's so widely used that it's
> too late to rework it. Sometimes you just have
> to live with your mistakes:(

Joe Blandy
Saturday, September 27, 2003

I'm curious: how is this a problem?

Alyosha`
Saturday, September 27, 2003

Joe, excellent link.  Thanks.

Aloysha, here is a link describing the usefulness of immutability:
http://www-106.ibm.com/developerworks/java/library/j-jtp02183.html

T. Norman
Sunday, September 28, 2003

But if you and everyone on your team really agrees the Date class ought to be mutable, can't you get all the benefits of an immutable class by simply ***agreeing nobody will modify any existing instances of the Date class***?
  Granted, it's not theoretically sound because there might be some renegade team member who forgets the agreement and modifies a Date object without telling anyone--but on the other hand, if he feels the need to do that, then it implies that maybe there is value in having a mutable Date class after all.

Anon. Coward
Sunday, September 28, 2003

We could agree not to mutate any Date instances, but that would create additional work of policing and reviewing to prevent it from happening.  Nobody here and now would do it deliberately, but there are non-obvious ways in which it could happen inadvertently, and 2-3 years from now a different set of programmers could create subtle bugs in the system by (deliberately or ignorantly) introducing mutable Date behavior into a system that was expecting immutability.

It's much better to create an immutable class and let the compiler prevent the problems.  Someone who needs mutable Dates can still use the original Date class.  I just wished Sun would have done it so I wouldn't have to do it, and there would be a standard for it.

Although I see why Sun won't make the existing Date immutable, because that would obviously disrupt existing bodies of code, I don't see why they couldn't create a new class that holds a date which is immutable.  Sort of like the immutable String and its mutable cousin StringBuffer.

T. Norman
Sunday, September 28, 2003

Forgive my ignorance -- I'm a .Net developer and have never coded a line of Java in my life...  But, if this is a problem, can't you just subclass the Date object and create your own immutable Date class?

Robert Jacobson
Monday, September 29, 2003

Subclassing could be done, but it presents a problem because all the setXXX methods would be inherited.  Which means I'd have to override those methods to throw an exception.  It might work, but could create unexpected problems when passed to a library that does anything with dates, or when it is serialized across a network.

Not subclassing would allow the setXXX methods to be absent, but because the system libraries and third-party libraries won't recognize our self-written class, we'll have to write something like a getDateCopy() method to create a standard Date object and we would have to call it whenever a standard Date needs to be passed to a library.  That defeats one of the benefits of immutablility -- the benefit of not having to make copies of an object when it is passed outside of private scope.

Had Sun included an immutable date class as a standard part of the language, there wouldn't be any problems with libraries not recognizing it or throwing unexpected exceptions because they called setXXX for whatever reason.

T. Norman
Monday, September 29, 2003

The recommended solution is to make  defensive copy of the date object when providing it to another object.

Rather than return the internal date object, which the client might accidentally alter, you make a copy of the object and then return that.

Ged Byrne
Monday, September 29, 2003

A simple solution is to create your own Date class that is immutable.  Only one member (a long for the actual date value in millis), and whatever utility methods you need, delegated to those in java's Date class where appropriate/necessary.  Such a class could easily contain a toDate() method to get a 'disposable' Date instance reflecting the same long date value.

Monad
Monday, September 29, 2003

--
But, if this is a problem, can't you just subclass the Date object and create your own immutable Date class?
--

That is a good solution, but object purists always want to make things harder than necessary in the quest for the "right design".

NathanJ
Monday, September 29, 2003

"That is a good solution, but object purists always want to make things harder than necessary in the quest for the "right design". "

It's not a good solution because the subclass doesn't honor the contract established in its superclass.  This defeats the ability of the compiler to detect violations of the immutability requirement, deferring it to runtime detection instead. 

Hackers always want to make things more confusing and riskier than necessary in the quest for the "quick implementation"

so there :P
Monday, September 29, 2003

Dates in Java suck anyway.  To use them correctly, you almost always have to use a Calendar object.  Your best bet for immutable is to pass around a long which is the result of Date.getTime().  All java.utilDate and it's progeny provide is labeling of the intention.

Other annoyances java.sqlDate has no default contrstuctor, leaving you to have to refere to both java.util.Date and java.sql.Date.  java.sql.Date just chops off the time info to be SQL compliant.  You want the seconds, use timestamp.  Ah lovely.  Who cam up with that.

Just about everyhting on java.util.Date has been deprecated, it should be failry easy to make it immutable.  All they have to do is deprecate setTime and guess what, there are no methods left that change it.  Remove em all in 1.6 or later.

What I would like to see is a new class that acts like a Calendar object, but is immutable.

Adam
Monday, September 29, 2003

> But, if this is a problem, can't you just subclass the Date object and create your own immutable Date class?

In Refactoring, Martin Fowler recommends using a wrapper class (NOT a subclass). It contains a Date internally, and of course can be easily converted to and from a "normal" Date. And of course you can make it immutable.

If I remember correctly, all the Date/Calendar code was contributed by IBM from the Taligent project. Javasoft needed to grow the Java libraries rapidly, and so they let this abortion in, and have probably regretted it ever since.

Portabella
Monday, September 29, 2003

--
It's not a good solution because the subclass doesn't honor the contract established in its superclass. 
--

It is a good solution if you want to use your immutable dates in the same places as existing Date classes. The ImmutableDate class can throw an exception when someone tries to change its value. This solution will work for many problems.

The wrapper class provides more flexibility at the cost of a little extra work when you need access to the java.util.Date object itself.

Creating an immutable Date object from scratch is (IMO) overkill for most problems.

NathanJ
Monday, September 29, 2003

Looks like I'm going to have to write my own class, without inheriting from the standard Date.  It won't be "from scratch", since it would either wrap a standard Date or a long which can be used to create a Date when needed.

Subclassing is DOA because if the constructor or serializer of the original Date class calls any of the public setXXX methods, subclassing will not work if an exception is thrown on any of those methods.  In addition, third-party libraries won't know that they aren't supposed to call the setXXX methods, since they would only see it as a standard Date.

Sun really screwed up with this one. They have java.util.Date, java.sql.Date, Timestamp, Calendar, DateFormat and still none of them do what you really want without you having to go through gyrations.

T. Norman
Monday, September 29, 2003

Just a few points to note:

1)  The compiler won't allow an overriding method to introduce a new exception.

2)  All of the update methods for the Date object have been deprecated.  You will get  a warning at compile time not to use them.

3) Of couse the Date object is a statement of intent.  That is what Type is all about.  Since when was a long immutable?

Ged Byrne
Tuesday, September 30, 2003

1) The compiler won't object to unchecked exceptions, like the OperationNotSupportedException that would be thrown if subclassing was used.

2) The setTime(long) is not deprecated.

3)  A long is not immutable as such, but for practical purposes it is because it is passed by copy and not by reference, as all primitives are.

T. Norman
Tuesday, September 30, 2003

Oops, I meant UnsupportedOperationException.

T. Norman
Tuesday, September 30, 2003

T Norman,

Sorry about that.  Must have more sleep before posting.

Then I would remember Runtime exceptions.

Then I would remember that sure you can change a long, but your not dealing with a reference to an objects private memeber.

They didn't replicate setTime.  What are they playing at?

Giving it more thought, what Java needs is a mechanism for making any object immutable, like Ruby's 'freeze' or C++'s static.

Ged Byrne
Tuesday, September 30, 2003

I think you mean C++'s "const", not "static". And in truth, "const" is one of those "better in theory than in practice" things like checked exceptions.

Brad Wilson (dotnetguy.techieswithcats.com)
Tuesday, September 30, 2003

I'm not on good form am I.  Yes, const.

Freeze works well in Ruby, I'll stick to that one.

Is it that const is just a bad idea, or is it just applied badly?

Ged Byrne
Wednesday, October 1, 2003

> Is it that const is just a bad idea, or is it just applied badly?

I second the question!

I thought that the language (mis)-design of C++ made it extremely difficult to implement const correctly, whereas it might be very straightforward in other languages.

Portabella
Wednesday, October 1, 2003

const is one of those things that's hard and/or tedious to get right, and it can be casted away. Making a method const or non-const changes its signature, so it can be a breaking change for things already linked to you.

Brad Wilson (dotnetguy.techieswithcats.com)
Friday, October 3, 2003

"const" and checked exceptions aren't hard to get right when you design with them. Adding these elements after the fact is certainly a painful exercise.

Brian
Thursday, March 25, 2004

*  Recent Topics

*  Fog Creek Home