blanking a java.util.Date in 1.5

C

Chris Murphy

I have some code that compares java.util.Date. The dates in
question have some of their fields blanked out so that the time
portion will be irrelevant to the comparison. I am not sure of the
technique being used to 'blank out' various fields in a
java.util.Date, but I do know that the technique gives different
results in the 1.4 and 1.5 JVMs.

The last line of output in the following code under 1.4 is
Got day: [Sat Sep 25 00:00:00 EST 2004]

Under 1.5 it is
Got day: [Sat Sep 25 12:00:00 EST 2004]

Is there any way I can get them to be the same under 1.4 and 1.5?
Preferably both having the time component of [00:00:00]?

==============================BEGIN CODE

public static void main( String[] args)
{
int dateInt = 25;
int monthInt = 8;
int yearInt = 2004;
GregorianCalendar day = new GregorianCalendar();
clearCalendar( day);
Err.pr( "date using: " + dateInt);
day.set( Calendar.DATE, dateInt);
Err.pr( "month using: " + monthInt);
day.set( Calendar.MONTH, monthInt);
Err.pr( "year using: " + yearInt);
day.set( Calendar.YEAR, yearInt);

//With 1.5 get [Sat Sep 25 12:00:00 EST 2004]
//With 1.4 got [Sat Sep 25 00:00:00 EST 2004]
Err.pr( "Got day: [" + day.getTime() + "]");
}

/**
* Clears everything from the calendar arg. The intention being
* that this method can be called before the invoking code goes
* on to set only the fields that it wants to set.
*/
public static void clearCalendar( Calendar calendar)
{
calendar.clear( Calendar.DAY_OF_WEEK_IN_MONTH);
calendar.clear( Calendar.DATE);
calendar.clear( Calendar.DAY_OF_MONTH);
calendar.clear( Calendar.HOUR);
calendar.clear( Calendar.HOUR_OF_DAY);
calendar.clear( Calendar.MINUTE);
calendar.clear( Calendar.SECOND);
calendar.clear( Calendar.MILLISECOND);
//attempting fix of 12:00 being introduced, but no help
calendar.clear( Calendar.PM);
}

==============================END CODE

Thanks for any help with this.

- Chris Murphy
 
P

P.Hill

Chris said:
I have some code that compares java.util.Date. The dates in
question have some of their fields blanked out so that the time
portion will be irrelevant to the comparison.


First of all java.util.Date does not have fields. When you ask for
a toString() from a java.util.Date you actually get a SimpleDateFormat
(SDF) created which does all the right default things to use
a Calendar with a Timezone to make all the fields to make a String.
The fields are in the Calendar object.

Given all that, may I suggest that you please use your own SDF
to define what you want for a String. toString() does not have a
contract that says that have to keep giving the same representation
across various releases. They don't even have to give the same
value across different invocations of the same VM.
The last line of output in the following code under 1.4 is
Got day: [Sat Sep 25 00:00:00 EST 2004]

Under 1.5 it is
Got day: [Sat Sep 25 12:00:00 EST 2004]

Is there any way I can get them to be the same under 1.4 and 1.5?
Preferably both having the time component of [00:00:00]?

==============================BEGIN CODE

public static void main( String[] args)
{
int dateInt = 25;
int monthInt = 8;
int yearInt = 2004;
GregorianCalendar day = new GregorianCalendar();
clearCalendar( day);
Err.pr( "date using: " + dateInt);
day.set( Calendar.DATE, dateInt);
Err.pr( "month using: " + monthInt);
day.set( Calendar.MONTH, monthInt);
Err.pr( "year using: " + yearInt);
day.set( Calendar.YEAR, yearInt);

//With 1.5 get [Sat Sep 25 12:00:00 EST 2004]
//With 1.4 got [Sat Sep 25 00:00:00 EST 2004]
Err.pr( "Got day: [" + day.getTime() + "]");

Try
String FORMAT_8601 = "yyyy-MM-dd 'T' HH:mm:ss.S zzz";
SimpleDateFormat localTime = new SimpleDateFormat( FORMAT_8601 );

Err.pr( "Got day: [" + localTime.format( day ) + "]"));

And you will learn more about what it is going on. I have displayed
the HOUR of the DAY and not the AM/PM hour.

It may be that the traditional Unix-like format used for the Date.toString()
uses HOUR (AM/PM hour) and that in 1.5 someone decided 12 (midnight or
noon) is the right way to display AM/PM hours and not 00:00 for midnight.

-Paul
 
C

Chris Murphy

Thanks for that Paul, but my problem is not with toString(), but with
the date itself (which is actually stored as a number of milliseconds
since some fixed date). Changes to the output of toString() between
1.4 and 1.5 correctly reflect the fact that something has changed. By
'something has changed' I suspect that the equals() contract is not
being kept across VM versions.

A program that I have written stores dates in a database, and these
dates were stored using 1.4. This same program will give completely
different date calculation results whether run in 1.4 or 1.5. This has
nothing to do with how the dates are formatted for toString(). I can
potentially see programs out there that work with dates previously
stored in 1.4 having similar troubles.
 
J

John B. Matthews

Thanks for that Paul, but my problem is not with toString(), but with
the date itself (which is actually stored as a number of milliseconds
since some fixed date). Changes to the output of toString() between
1.4 and 1.5 correctly reflect the fact that something has changed. By
'something has changed' I suspect that the equals() contract is not
being kept across VM versions.

A program that I have written stores dates in a database, and these
dates were stored using 1.4. This same program will give completely
different date calculation results whether run in 1.4 or 1.5. This has
nothing to do with how the dates are formatted for toString(). I can
potentially see programs out there that work with dates previously
stored in 1.4 having similar troubles.

Is it possible that the trip through the middleware & database is
truncating the time portion, say to around midnight?
 
P

P.Hill

Chris said:
Thanks for that Paul, but my problem is not with toString(), but with
the date itself (which is actually stored as a number of milliseconds
since some fixed date).

Yes, I said that. Now you have to show us where the millisecond values
are different.
Changes to the output of toString() between
1.4 and 1.5 correctly reflect the fact that something has changed.

What has changed and what makes you think it is 'correct'? You have never
established what has changed by showing us ALL formated fields on your
machine using a complete SimpleDateFormat. You show a
java.util.Date.toString(). We can't even tell if it is AM or PM,
or the same actual time or not.

Let's look at the millisecond values and see what they look like.
That is a simple change to your code. (Sorry, I'm busy today and
don't have a 1.5 installed). Please extend your sample application
to show all formated fields and the binary value. Then we'll have
something to chew on.
A program that I have written stores dates in a database, and these
dates were stored using 1.4. This same program will give completely
different date calculation results whether run in 1.4 or 1.5.

By the way the conversion from the DB is the contract of the JDBC driver
not the contract of Calendar or Date. As John pointed out there may be
some change there also. For example, how does your DB store dates? With
no TZ information or without.
This has
nothing to do with how the dates are formatted for toString().

That is how you are claiming things are different. I just want to
see the rest of the date to see the whole story of how they are different.
I can
potentially see programs out there that work with dates previously
stored in 1.4 having similar troubles.

First, we have to identify where the difference is.

-Paul
 
C

Chris Murphy

Is it possible that the trip through the middleware & database is
truncating the time portion, say to around midnight?

No. If you run the code in 1.4 then 1.5, you get different toString()
results, so it has nothing to do with 'middleware & database'. There
is definitely a toString() difference, so Paul was right in saying
'forget the formatting, the underlying date has not changed'. I
verified this by substituting day.getTime() with
day.getTime().getTime().

//getTime()
//With 1.5 get [Sat Sep 25 12:00:00 EST 2004]
//With 1.4 got [Sat Sep 25 00:00:00 EST 2004]
//getTime().getTime()
//With 1.5 got [1096034400000]
//With 1.4 got [1096034400000]
Err.pr( "Got day: [" + day.getTime().getTime() + "]");

As you can see from the comments, the underlying date produced does
not change with the JDK version, just the String representation of it.

However, I think you are onto something with the 'middleware &
database'. Maybe the O/R mapping that is being used does something
like store dates as Strings. I know it converts java.util.Date into
its own type. I think this is where I will have to look now.

thankyou - Chris
 
T

Tor Iver Wilhelmsen

//With 1.5 get [Sat Sep 25 12:00:00 EST 2004]
//With 1.4 got [Sat Sep 25 00:00:00 EST 2004]

Looks like 1.5 formatting uses timezone information; however, from
what I can tell, Australia spans GMT+8 to GMT+10; Are you in New
Zealand or any other islands in the GMT+12 timezone?

http://www.travel.com.hk/region/timezone.htm
//With 1.5 got [1096034400000]
//With 1.4 got [1096034400000]

The timestamp long does not use timezones, but is GMT/UTC.
 
C

Chris Murphy

I am in Adelaide at the moment, but the computer I am using is has its
TZ set to Sydney time. Not sure I see how the TZ affects the results.
Wouldn't everyone get the same results from the code snippet I put
out, no matter which TZ they had their computer set to?

- Chris
 
C

Chris Murphy

Chris said:
Hi Paul,

The program I have (I wrote it, and use it) rosters a load of people
to monthly shifts. When I did the roster for October on 1.5 it came
out wrong. When I reverted back to 1.4 it came out as expected. Thus
to me I still have a problem, but it is time to look at other
potential causes. The fact that the formatting has changed from 1.4 to
1.5 may have been a red-herring, but it may still be part of the
problem. After all 'something must' have changed with
java.util.Date between 1.4 and 1.5. My next step will be to examine
the O/R mapping and DB side of things. java.util.Date are stored in
Hypersonic with JDOGenie used as O/R mapping.


Hmm, are you columns actual TIMESTAMPS or DATE ?
Does it store in the DB with TZ information? Can you see the values?
Some DBs don't save TZ information, so you need to tell it what TZ to
use when converting to a java.util.Date.

3:00 PM + a time zone => various binary Date values.
In jdbc 2.0 they added a call getDate( index, Calendar );
so you could tell it what timezone
http://java.sun.com/j2se/1.4.2/docs/api/java/sql/ResultSet.html#getDate(int, java.util.Calendar)


Let me know what you find. I'm curious.
-Paul



Hi Paul,

Sorry taken so long to get back.

I haven't needed to review the problem as it seems to have "fixed
itself". What I think the problem was was that for backing up and
restoring data I was using XMLEncoder/XMLDecoder. I may have exported
in 1.4 and imported back in 1.5. As the only way that XMLEncoder
stores anything is as a String, the toString() call on a
java.util.Date may have been to blame. It is even more complicated
than this as how it actually gets stored when XML encoded is as a
za.co.hemtech.jdo.common.sco.Date. I think its about time I went to a
more durable backup solution!

Answering your questions now. I haven't needed to have much to do with
the DB as JDO takes all that away. Anyway looking at the columns of
the tables that have been created, they are all TIMESTAMPs.

From what you are saying I might have needed to find out whether, and
if whether how, the O/R mapping (JDOGenie) uses the JDBC getDate(
index, Calendar) on the DB (Hypersonic) when retrieving the data from
a TIMESTAMP column, or what other mechanism it uses. Thankfully I
don't need to do this.

Some of your insights will help me with Dates generally with another
problem that I have, which is what happens to the roster when I change
the TZ on my computer (it stuff it up!). I am currently rostering
people in Sydney from Adelaide, yet have found the need to keep my
computer on the Sydney time zone! This is a problem I will actually
have to get to, but it doesn't need to be fixed right now.

Thanks for your help - Chris Murphy

-----Original Message-----
From: P.Hill & E.Goodall [mailto:[email protected]]
Sent: Friday, 24 September 2004 8:48 AM
To: Chris Murphy
Subject: Re: the Date post
 
C

Chris Murphy

The last line of the blanking method had this line:

calendar.clear( Calendar.PM);

And it should have been this:

calendar.clear( Calendar.AM_PM);

What was happening was that the Calendar.AM_PM 'field' was not being
cleared. This meant that before noon a 'cleared date' would return
with 00:00:00 as the time component. After noon it would become
12:00:00.

The result was that completely different rosters (for that was what
the application was doing) were coming out depending on what time of
day it was!

So in the end the cause of the problem was a silly error, and possibly
had nothing to do with version 1.4 or 1.5 of Java.

- Chris Murphy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top