14

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!

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Yossale
  • 14,165
  • 22
  • 82
  • 109
  • I had a quick google for this, can't believe there is no built in method for just grabbing the date. Seems like an obvious method or property to have. Not used Java in a while though. – PeteT May 06 '09 at 13:42
  • http://stackoverflow.com/questions/227007/resetting-the-time-part-of-a-timestamp-in-java Addresses the same problem. – ScArcher2 May 06 '09 at 13:44

11 Answers11

26

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
  • 11,410
  • 5
  • 57
  • 74
18

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,421,763
  • 867
  • 9,128
  • 9,194
  • 23
    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 May 06 '09 at 13:29
  • 8
    @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 May 06 '09 at 13:52
  • 4
    I only clicked on this question to see if anyone had suggested Joda Time yet (really!). :D – Michael Myers May 06 '09 at 14:07
  • 1
    How can that be that so many people knows so much about the "best way" to get the current date or time, and no article exists in SO to summarize this knowledge in a simple question "How to get Date and Time in Java?" with a single and protected answer stating how to get Date and Time with standard Java API, and in comment a reference to JodaTime... instead learners like me are moved around with no clear answer... just a suggestion. – mins May 22 '14 at 09:53
  • @Approachingminimums: I suspect it's partly because the *exact* answer will depend on the exact requirements. But starting off by moving to Joda Time or Java 8's java.time API is always a good bet... – Jon Skeet May 22 '14 at 09:54
  • Unfortunately I'm still with Java 7. Not sure the best approach for me to learn Java would be to use an external library. What would be the best way with standard APIs to print "Today is May 22, 2014 and it is 12:02"? – mins May 22 '14 at 10:02
  • @Approachingminimums: Always in a fixed locale? Always using a fixed format? In what time zone? These are the kinds of questions you need to ask yourself - and that's precisely why there isn't a one-size-fits-all answer. If you have a specific situation which you *don't* believe is answered elsewhere, ask a new question (but probably link to questions that are similar without helping you, as evidence that you really have looked first...) – Jon Skeet May 22 '14 at 10:04
  • Here it is: http://stackoverflow.com/questions/23804371/how-to-print-at-the-console-today-is-may-22-2014-and-it-is-204-pm – mins May 22 '14 at 10:35
10

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
  • 196,001
  • 113
  • 385
  • 569
9

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
  • 342,105
  • 78
  • 482
  • 720
  • 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 May 06 '09 at 13:27
  • 6
    No, you have NOT tried this. HOUR is the wrong field, use HOUR_OF_DAY! – Michael Borgwardt May 06 '09 at 13:39
4

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

Steve K
  • 19,408
  • 6
  • 52
  • 50
2

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Also, quoted below is a notice from the home page of Joda-Time:

Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.

Solution using java.time, the modern Date-Time API:

The modern Date-Time API has many types which truly represent a date or time or date-time in a specific timezone. You can choose from the following options as per your specific requirement:

  1. If you are looking for a type that represents a date without a timezone, you can use LocalDate.now. The good news is that its variant, LocalDate#now(ZoneId) returns the current date from the system clock in the specified time-zone.
  2. If you are looking for an object that represents a date without a timezone, and with time units set to zero, you can call LocalDate#atStartOfDay on the object obtained with Option#1.
  3. If you are looking for an Instant representing the Date-Time object obtained with Option#2, you can attach this object with ZoneId.of("Etc/UTC") using LocalDateTime#atZone to obtain a ZonedDateTime and convert the same into an Instant using ZonedDateTime#toInstant.

Demo:

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        LocalDate todayInSystemTz = LocalDate.now();
        System.out.println(todayInSystemTz);

        LocalDate todayInIndia = LocalDate.now(ZoneId.of("Asia/Kolkata"));
        System.out.println(todayInIndia);

        LocalDateTime todayInSystemTzWithZeroTimeUnits = todayInSystemTz.atStartOfDay();
        System.out.println(todayInSystemTzWithZeroTimeUnits);

        ZonedDateTime todayInUtcWithZeroTimeUnits = todayInSystemTzWithZeroTimeUnits.atZone(ZoneId.of("Etc/UTC"));
        System.out.println(todayInUtcWithZeroTimeUnits);

        Instant instant = todayInUtcWithZeroTimeUnits.toInstant();
        System.out.println(instant);

        // Can I represent the obtained Instant in India?
        System.out.println(instant.atZone(ZoneId.of("Asia/Kolkata")));

        // Can I represent the obtained Instant in New York?
        System.out.println(instant.atZone(ZoneId.of("America/New_York")));
    }
}

Output:

2021-06-20
2021-06-20
2021-06-20T00:00
2021-06-20T00:00Z[Etc/UTC]
2021-06-20T00:00:00Z
2021-06-20T05:30+05:30[Asia/Kolkata]
2021-06-19T20:00-04:00[America/New_York]

ONLINE DEMO

The Z in the output is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).

For any reason, if you need to convert this object of Instant to an object of java.util.Date**, you can do so as follows:

Date date = Date.from(instant);

Learn more about the modern Date-Time API from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

** A java.util.Date object simply represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). Since it does not hold any timezone information, its toString function applies the JVM's timezone to return a String in the format, EEE MMM dd HH:mm:ss zzz yyyy, derived from this milliseconds value. To get the String representation of the java.util.Date object in a different format and timezone, you need to use SimpleDateFormat with the desired format and the applicable timezone e.g.

Date date = new Date();

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);

sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String strDateNewYork = sdf.format(date);

sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String strDateUtc = sdf.format(date);
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
1

I know this is a very old question, no longer active, but it came to be on the top when I searched Google.

While all advise is very good, I can't believe no one simply answered:

Date date = new Date(System.currentTimeMillis());
System.out.println(date);

Which returns effectively, today's date.

zorman2000
  • 19
  • 1
  • what you printed is the full timestamp. sometime what you need is only the date in a specific hour (for sorting, for example). Secondly, Date is a very complex issue - it depends on localization, on light saving hours, and so on. If you'll read the thread, you'll get a hunch about the complexity of the issue. – Yossale Jun 26 '13 at 17:27
1

...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
  • 3,068
  • 2
  • 19
  • 30
1

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
  • 2,787
  • 1
  • 18
  • 10
0

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
  • 152
  • 1
  • 6
  • If you'd look carefully , you'd see I've tried this - and it has unexpected results – Yossale May 06 '09 at 13:26
  • @Yossale: You were using Calendar.HOUR when Calendar.HOUR_OF_DAY is more appropriate. – OscarRyz May 06 '09 at 13:30
  • 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 May 06 '09 at 13:41
0

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.

  • 2
    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 May 06 '09 at 13:42
  • +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 May 06 '09 at 14:12
  • And that is, IIRC, a legacy owed to some POSIX standard. – Michael Borgwardt May 06 '09 at 14:46