Lew said:
The problem with emphasizing what it used to do incorrectly is that it
misleads people into thinking it still does that. Date no longer has the
design purpose of using the local time zone. I guess my confusion over
your post stemmed from the lack of clarity that the comment was of only
historical significance. Given that adjustment, I see your point.
Sloppy writing. Point taken.
In very few cases is 'toString()' designed for use with real applications.
Exactly. The purpose of 'toString()' is to give a rough-and-ready
identification of an object. One should always think long and carefully
before using 'toString()' for any other purpose than that for which it is
(present tense) designed.
past tense
Several posts in this thread have mentioned that all but the most basic
methods of Date are deprecated. The OP did not ask what that meant, so I
think you are being a bit harsh to assume they don't know.
I did not intend any disrespect, but when I came to the full realization
that the OP was using deprecated constructors to create a Date instance, and
was then complaining about its behavior, the only logical conclusion I could
draw was that they did not fully grasp the meaning of "deprecated", or they
were not aware that the methods were deprecated. One last possibility that
didn't occur to me at the time, might be that they are using some API that
creates a Date for them, using the deprecated API. That could be tough to
troubleshoot.
If a person doesn't know what "deprecated" means for Java, they have a bit
more studying to do before they are ready to take a paycheck for
programming in it.
I agree, but I didn't suggest that. Sometimes a person can just have a blind
spot. If they were never hit full force with a deprecated bug, they might
not take "deprecated" seriously. In some cases, or even many cases, that
could be a benign oversight.
It sure doesn't imply that it shouldn't be. When one mentions their birth
date, it is always implicitly localized to their place of birth. If that
assumption is not accounted for, then one makes the same mistake the
original designers of the Date class made, and we see now what an
egregious error that was.
That was my point exactly. Most people who have my DOB *do not have the
locale*. In that case, they have insufficient information to convert it to a
Date.
Saying that people ignore localization, as you and the OP have done, does
not mean that it is correct to do so. In fact, my birth date, localized
to the U.S. Eastern time zone where I was born, is a day earlier than
people in New Zealand were using at that exact moment. If one were
talking about what was going on in New Zealand at the moment of my birth,
one most definitely would have to localize the time for that zone.
My whole point was that people ignore localization at their peril. By no
means did I mean to imply that it was OK.
AIUI, even those deprecated constructors and setters adjust the 'long'
value to UTC for storage in the Date object. So your statement here is
not correct. The constructor creates a Date that contains a long
representing the month/day/year at UTC.
I would have to test that. I do not believe they changed the original
behavior of the deprecated methods, which IIRC, used the default locale/time
zone to initialize the internal representation as a long *normalized to
UTC*. Furthermore, any of the other deprecated methods, and toString, IIRC,
use the default locale/time zone to reconstitute Date as a string, which
would *not* be the original month/day/year values in other time zones --
precisely the problem the OP is describing.
If that Date does not represent the "desired month/day/year as represented
in the database", it is because the OP was not being responsible for time
zones.
Anyone that messes with dates must be responsible for time zones. That's
why SQL supports the type TIMESTAMP WITH TIME ZONE. (And the OP would be
well advised to use the WITH TIME ZONE types.) Failure to be responsible
for time zones has caused major bugs on many systems for which I've been a
developer.
Endorsing the notion that one can ignore time zones is to endorse the
notion that such bugs are acceptable.
I agree violently. I hope you did not get that impression from my original
remarks, or my writing *really* must suck.
I should re-iterate, that most people who have my DOB have no idea where I
was born, so converting a DOB to a Date really is inappropriate. It is more
correctly just another factor of my identification (e.g., name, address,
DOB). As such, it has about as much relevance to time as my signature has.
If we were to insist on converting DOB-without-time-zone to a time, then we
really need another type, TIMESTAMP WITHOUT TIME ZONE, and Date would have
to carry a flag to indicate no locale/time zone for later formatting
purposes.
Incidentally, a time zone offset alone is insufficient for proper time
localization. You need a locale, because some locales have different
policies for things like daylight saving time. Furthermore, it is possible
that ones birthplace did not observe DST on their DOB. For that matter, we
might have been in a different time zone (if government moved the boundary),
or even using a different calendar. For that reason, historical dates might
better be retained as strings, and never be converted to Date objects, even
if they appear to have some of the characteristics of a date. It is unlikely
that locale databases are completely correct, even for recent dates, and
much less likely that they are correct for all places and times. Using Date
for historical data could cause errors insidiously to creep in.