tags:

views:

1972

answers:

9

I need today's date - and zero anything else (" 05/06/08 00:00:00 ")

I've tried

Calendar calendar = Calendar.getInstance(); 
calendar.set(Calendar.HOUR, 0);        
Date date1 = calendar.getTime();                             
System.out.println(date1);

Run: (This is seriously messed up)

If the hour on the computer is < 12:00 at noon : Sun Mar 08 00:44:39 IST 2009

If the hour on the computer is > 12:00 at noon : Sun Mar 08 12:46:53 IST 2009

So I gave this up.

All the Date's setters are deprecated (except the epoch time) - so I don't want to use them either

The only thing I could think of is

Calendar calendar = Calendar.getInstance();  
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
String sDate = dateFormat.format(calendar.getTime());
Date today = dateFormat.parse(sDate);

But this is such a lame code I can't bring myself to write it.

Any other option?

Thanks!

+9  A: 

The time component is not just hours (and Calendar.HOUR is, as you have noticed, AM/PM). You need to set all of the time fields to 0: HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND.

Michael Borgwardt
And as you can see , I've tried this , but it doesn't work (if zeroing "HOUR" alone causes different results based on the server time , what good will the rest do?)
yossale
No, you have NOT tried this. HOUR is the wrong field, use HOUR_OF_DAY!
Michael Borgwardt
+15  A: 

My standard advice for Java date/time questions: don't use java.util.{Calendar,Date}. Use Joda Time. That way you can represent a date as a date (with no associated time zone), instead of a date/time. Or you could use a DateMidnight if that's what you want to represent. (Be careful of combinations of time zone and date where there is no midnight though...)

What do you need to use the Date with? If you can get away with changing to use Joda throughout, that's great. Otherwise, you can use Joda to do what you want and then convert to milliseconds (and then to java.util.Date) when you really need to.

(Michael's solution when using Date/Calendar is fine if you really want to stick within a broken API... but I can't overstate how much better Joda is...)

Jon Skeet
+1 JodaTime is how java time SHOULD have been implemented
basszero
SO Rule # 1: If the question is about java dates, somebody will suggest Joda Time. Rule # 2: If the question is about javascript, somebody will suggest jquery. Any others?
Paul Tomblin
@Paul: SO Rule # 3: If the question is about regular expressions, somebody will break out the "now you have two problems" quote. Rule # 4: If the question is about programming books, we'll get the same list of books we always get.
Bill the Lizard
I only clicked on this question to see if anyone had suggested Joda Time yet (really!). :D
Michael Myers
A: 

Why the string manipulation?

Can you not just set the values you need on the Calendar object before converting to a Date using getTime()?

Kurley
If you'd look carefully , you'd see I've tried this - and it has unexpected results
yossale
@Yossale: You were using Calendar.HOUR when Calendar.HOUR_OF_DAY is more appropriate.
OscarRyz
Yeah, I need to read more carefully, for some reason I only saw the last part of your question. On a side note, I'd also recommend Joda Time, though always be careful in which order you manipulate the fields of the date or you can get unexpected problems in February.
Kurley
+12  A: 

I use this:

public static Date startOfDay(Date date) {
   Calendar dCal = Calendar.getInstance();
   dCal.setTime(date);
   dCal.set(Calendar.HOUR_OF_DAY, 0);
   dCal.set(Calendar.MINUTE, 0);
   dCal.set(Calendar.SECOND, 0);
   dCal.set(Calendar.MILLISECOND, 0);

   return dCal.getTime();
 }
Damo
+4  A: 

See Apache's commons-lang DateUtils.truncate()

Steve K
+8  A: 

You should use HOUR_OF_DAY instead of HOUR and combine it with MINUTE and SECOND also.

import java.util.Calendar;
import static java.util.Calendar.HOUR_OF_DAY;
import static java.util.Calendar.MINUTE;
import static java.util.Calendar.SECOND;
import static java.util.Calendar.MILLISECOND;

public class Today { 
    public static void main( String [] args ) { 
        Calendar cal = Calendar.getInstance();
        cal.set( HOUR_OF_DAY, 0 );
        cal.set( MINUTE, 0 );
        cal.set( SECOND, 0 );
        cal.set( MILLISECOND, 0 );
        System.out.println( cal.getTime() );
    }
}

The results you are getting are due to HOUR is used to AM/PM while HOUR_OF_DAY is 24 hrs.

HOUR_OF_DAY:

*Field number for get and set indicating the hour of the day. HOUR_OF_DAY is used for the 24-hour clock. E.g., at 10:04:15.250 PM the HOUR_OF_DAY is 22.*

HOUR:

Field number for get and set indicating the hour of the morning or afternoon. HOUR is used for the 12-hour clock (0 - 11). Noon and midnight are represented by 0, not by 12. E.g., at 10:04:15.250 PM the HOUR is 10.

OscarRyz
A: 

Another vote for JodaTime.

java.util.Date and Calendar are so bad they are broken. (And SimpleDateFormat is rubbish too!)

For what it's worth, Java 7 will include a new date time library based strongly around JodaTime.

I get tired of hearing this repeated mindlessly. Date and Calendar are NOT broken, nor is SimpleDateFormat. They lack some features (such as the concept of a timeless date), and the API makes some simple tasks more complex than necessary, but most of the complexity is there because dates simply ARE that complex and difficult to get right!
Michael Borgwardt
+1 to Michael's comment - it's not broken (Because it produces correct results), it's just infuriatingly tedious to use. JodaTime is much nice r to use - even though it takes a while to get used to the different concepts that the API introduces.The only thing that can concievably be seen as broken in the Java data time API - IMHO - is the fact that January is represented by zero. This drives me absolutely mad.
belugabob
And that is, IIRC, a legacy owed to some POSIX standard.
Michael Borgwardt
+1  A: 

As mentioned above you should use

Calendar.HOUR_OF_DAY

As opposed to

Calendar.HOUR

Also you need to clear out the other fields (Calendar.MINUTE, Calendar.SECOND, and Calendar.MILLISECOND) by setting them to zero.

Sorry there's no easy way here. A pain, and that's why they're working on a new API for Java 7 I believe based on Joda Time.

Clinton
A: 

...or you can do it the hacker way:

long MS_PER_DAY = 86400000L;
Date dateTime=new Date();
long offset = TimeZone.getDefault().getOffset(dateTime.getTime());
Date date= new Date(((dateTime.getTime()+offset)/MS_PER_DAY)*MS_PER_DAY-offset);
stenix