programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
• Campbell Ritchie
• Jeanne Boyarsky
• Ron McLeod
• Liutauras Vilda
• Paul Clapham
Sheriffs:
• paul wheaton
• Tim Cooke
• Henry Wong
Saloon Keepers:
• Stephan van Hulst
• Tim Holloway
• Carey Brown
• Frits Walraven
• Piet Souris
Bartenders:
• Mike London

# Calendar / Date arithmetic

Ranch Hand
Posts: 34
• Number of slices to send:
Optional 'thank-you' note:
I give up. I've been working for nearly two days trying to figure out how to do a SIMPLE date comparison on a date contained within a Calendar object. Is it really that hard???
In a nutshell, all I want to know is whether the date represented in the Calendar is less, greater, or equal to the current date. The brick wall I keep hitting is that the Calendar (and Date) classes carry the time as well as the date. This is throwing off the comparison I'm trying to use.
Pleeeeze someone help me! Thanks in advance!
Rick

Ranch Hand
Posts: 185
• Number of slices to send:
Optional 'thank-you' note:

Rick Crawford
Ranch Hand
Posts: 34
• Number of slices to send:
Optional 'thank-you' note:
Shama,
Thanks so much for the reply. So the only way to determine if a Calendar/Date is equal to the current date is to convert the comparison dates to Strings, then String-compare them?
If so, this begs another question: what if I want to know the number of days actually elapsed between the dates? You can't do that with Strings, can you?
This whole thing seems bizarre to me:
Thu Oct 18 14:00:00 CDT 2001
Thu Oct 18 00:00:00 CDT 2001
As far as I'm concerned (at least for this project), these dates are equal: October 18th is = October 18th. But java doesn't think they are because of the time fields.
Is there a way to 'clear' the hours, minutes and seconds from a java Date object?
Again, thanks so much for the reply.
Rick

Ranch Hand
Posts: 15304
6
• Number of slices to send:
Optional 'thank-you' note:
What if you took the String and then created a subString of the String and captured only the month and date, That would drop the time. Then you could parse that into an Integer if you wanted.

------------------
Happy Coding,
Gregg Bolinger

Rick Crawford
Ranch Hand
Posts: 34
• Number of slices to send:
Optional 'thank-you' note:
I finally got something that seems to work. It ain't pretty but:

At least this seems to work for the date combos I've tried. I realized that I really needed something to compute elapsed days, rather than just compare a date to the current date. I read a tip from someone on jGuru that indicated you need to convert your Date into a julian date. I spoofed some code on Deja.com, plugged it in and as far as I can tell, it's working.
I still can't believe there isn't a way built into the core Java Date / Calendar objects! Oh well...
Many thanks to all who offered suggestions. God bless!
Rick <><

Wanderer
Posts: 18671
• Number of slices to send:
Optional 'thank-you' note:
It is possible to zero out the time fields of a date using the the Calendar class - it's just a bit tedious:
<pre>
public static void zeroTimeFields(Calendar cal) {
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
}
</pre>
You can also achieve a simlar effect using java.sql.Date, which differs from a java.util.Date in exactly the way you want - the time component of the date is set to zero. Here's a simple way to get the number of days since Jan 1, 1970:
<pre>
public static long toDays(java.util.Date uDate) {
java.sql.Date sDate = new java.sql.Date(uDate.getTime());
long msec = sDate.getTime();
long days = msec / MSEC_PER_DAY;
return days;
}
private static final long MSEC_PER_DAY = 24 * 60 * 60 * 1000;
</pre>
It's actually pretty simple as you see - aside from the annoying inconsistency in naming conventions between java.util and java.sql. If only java.util.Date had been named java.util.Datetime, and if java.sql.Date had used composition rather than inheritance, we might have had a clearer API. Oh well...
[This message has been edited by Jim Yingst (edited October 18, 2001).]

Rick Crawford
Ranch Hand
Posts: 34
• Number of slices to send:
Optional 'thank-you' note:
Jim,
Thanks for the help. I found another example on Deja.com that is quite similar to your suggestion. I adapted it for my use:

It appears that the tools necessary to get the job done are there; it's just so real obvious how to do it. I hope the developers of the Java language consider adding in a future release of the API some methods to the Calendar and Date objects that make date arithmetic a little easier.
Thanks again, everyone!
Rick <><
P.S. This website is FABULOUS!!!

author
Posts: 3252
• Number of slices to send:
Optional 'thank-you' note:

Originally posted by Jim Yingst:
You can also achieve a simlar effect using java.sql.Date, which differs from a java.util.Date in exactly the way you want - the time component of the date is set to zero.

Wish that were true. In fact, only valueOf() and toString() are really different from java.util.Date; the time portion is preserved. java.sql.Time has similar behaviour. As the javadoc states, it is the responsibility of the JDBC driver to ensure that the time portion of the date is set to zero. But try for yourself:
Your example will still produce a correct figure for the number of days since 1/1/1970, though, because integer division doesn't perform proper rounding.
I found it out the hard way when I tried to do date and time comparisons with Date and Time objects of my own making and the whole thing didn't work at all...
- Peter

[This message has been edited by Peter den Haan (edited October 19, 2001).]

Jim Yingst
Wanderer
Posts: 18671
• Number of slices to send:
Optional 'thank-you' note:
Thanks for the correction, Peter - I hadn't noted that. Looks like the folks who wrote java.sql.Date weren't very sure what it was supposed to do - here's part of the source, from SDK 1.3.1:
<pre>
public Date(long date) {
// If the millisecond date value contains time info, mask it out.
super(date);
}
</pre>
The problem is that while the comment talks about masking time out, the super(date) invocation does nothing of the sort - it just creates a normal Date, with time info intact. Tellingly, there is no author listed in the source for this class - looks like no one wanted to take responsibility for it.
Good point about integer rounding - it may not be "rounding" as most of us are used to, but it is well-defined by the JLS, and happens to be exactly what we need in this case. We can skip the silly java.sql.Date class and get right to the info we need:
<pre>
public static long toDays(Date date) {
long msec = date.getTime();
long days = msec / MSEC_PER_DAY;
return days;
}

private static final long MSEC_PER_DAY = 24 * 60 * 60 * 1000;
</pre>

[This message has been edited by Jim Yingst (edited October 19, 2001).]

Ranch Hand
Posts: 38
• Number of slices to send:
Optional 'thank-you' note:
After scouring these forums for help calculating elapsed days, I found an article on java world that gave me exactly what I wanted...
http://www.javaworld.com/javaworld/jw-03-2001/jw-0330-time-p3.html
I was getting inconsistencies when trying to calculate elapsed from Jan 3, 2031 to October 3, 2031 using the millisecond calculation approach (off by 1 day)
I tried attacking it using the calendar class (DAY_OF_YEAR) adding, etc, but then dealing with elapses of multiple years gave me trouble.
This approach works for me!

 Consider Paul's rocket mass heater.