279

Continuing from Stack Overflow question Java program to get the current date without timestamp:

What is the most efficient way to get a Date object without the time? Is there any other way than these two?

// Method 1
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dateWithoutTime = sdf.parse(sdf.format(new Date()));

// Method 2
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
dateWithoutTime = cal.getTime();

Update:

  1. I knew about Joda-Time; I am just trying to avoid additional library for such a simple (I think) task. But based on the answers so far Joda-Time seems extremely popular, so I might consider it.

  2. By efficient, I mean I want to avoid temporary object String creation as used by method 1, meanwhile method 2 seems like a hack instead of a solution.

Community
  • 1
  • 1
Rosdi Kasim
  • 24,267
  • 23
  • 130
  • 154
  • 1
    Efficient? Do you need more efficiency than what's provided e.g., by method1? – Johan Sjöberg Feb 19 '11 at 10:22
  • 2
    What do you mean by "efficient"? A date is basically a typed long, you can't really do this in less memory than that. If you mean "convenient", JODA time is the way to go. – millimoose Feb 19 '11 at 10:46
  • 1
    I like method 2. Create a static method in an utility class and just use it. I've been this approach for years. – Wilson Freitas Jan 12 '12 at 14:57
  • Method 2 is not that short. You also have to catch the java.text.ParseException or throw it away. – Roberto Linares Feb 13 '13 at 22:19
  • 1
    Nitpicking on your "update 1": if it was "such a simple task", I guess Sun wouldn't have come to such horrendous and inefficient API, and you (and a lot of other people) wouldn't be asking that question at all ;-) – Flávio Etrusco Sep 04 '13 at 22:18
  • 1
    @RobertoLinares: Why does it matter that it is "not short"? Each line is **efficient**. I'm certain it is **much** faster than method 1, which involves formatting and parsing. – ToolmakerSteve Sep 06 '15 at 19:49
  • There is no such thing as a date without time. At best a date is a 24-hour period bounded ("at midnight in some timezone"). – Darrell Teague Aug 01 '17 at 18:06
  • 1
    FYI, the troublesome old date-time classes such as `java.util.Date`, `java.util.Calendar`, and `java.text.SimpleDateFormat` are now legacy, supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes. Much of the *java.time* functionality is back-ported to Java 6 & Java 7 in the [***ThreeTen-Backport***](http://www.threeten.org/threetenbp/) project. Further adapted for earlier Android in the [***ThreeTenABP***](https://github.com/JakeWharton/ThreeTenABP) project. See [*How to use ThreeTenABP…*](http://stackoverflow.com/q/38922754/642706). – Basil Bourque Aug 17 '18 at 22:10

23 Answers23

117

Do you absolutely have to use java.util.Date? I would thoroughly recommend that you use Joda Time or the java.time package from Java 8 instead. In particular, while Date and Calendar always represent a particular instant in time, with no such concept as "just a date", Joda Time does have a type representing this (LocalDate). Your code will be much clearer if you're able to use types which represent what you're actually trying to do.

There are many, many other reasons to use Joda Time or java.time instead of the built-in java.util types - they're generally far better APIs. You can always convert to/from a java.util.Date at the boundaries of your own code if you need to, e.g. for database interaction.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 90
    In enterprise applications we don't always have the option to add/use other libraries. I appreciate the pointer to Joda Time, but it's really not an answer to the original issue of getting the date portion using the standard Java. Thanks. Upvoting Chathuranga's answer. – noogrub Sep 17 '13 at 17:29
  • 5
    @noogrub: Chathugranga's answer doesn't answer the original question, which is asking about how to get a `Date` object - that answer *formats* a date to a string, which isn't the same thing. Fundamentally, asking what date a `Date` is on is a meaningless question without more information: the time zone and the calendar system you're using. – Jon Skeet Sep 17 '13 at 19:23
  • 9
    "In enterprise applications we don't always have the option to add/use other libraries". Really ? Are you suggesting you can't use 3rd party libs at all ? – Brian Agnew Mar 26 '14 at 10:31
  • 3
    @BrianAgnew noogrub's comment seems to be related to non-tech constraints, I think – Jose_GD Sep 08 '14 at 22:43
  • 3
    From today's perspective: "[Joda-Time](http://www.joda.org/joda-time/) is the de facto standard date and time library for Java prior to Java SE 8. Users are now asked to migrate to java.time (JSR-310)." – Drux Aug 28 '16 at 15:09
  • This answer is several years old - A better, more current answer by Basil below. Also - another user with limitations on 3rd-party packaged like Joda-Time. From some (but not all) of my customers, using something like Joda is DOA. OK to mentioned packages like that for people who can use them, but (beyond just this one answer on SE), people should be aware that it's not always an option. – Brick Mar 17 '17 at 16:36
  • We should give credit to the original author of Joda time who was hired by Oracle to "essentially" migrate Joda time to Java 8. Read more here http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html – Volksman May 05 '18 at 19:42
  • 1
    Can't see how this answers the OP's question. He's asking about the Date native library, this suggest to use other different library. The OP's problem has no solution with that. – moictab Aug 28 '18 at 07:52
  • @moictab: Yes, there's no solution with `Date` because `Date` represents an instant in time, not a date (despite its name). The answer states that there's no such concept as "just a date" in Date and Calendar. It then suggests using an alternative API instead. – Jon Skeet Aug 28 '18 at 09:58
  • @JonSkeet i used LocalDate in my jpa repository for getting and setting date only with no time but when i analyze the mysql table its showing time also and data type for date field is datetime why not date? Any suggestions how to do it – Salman S Dec 18 '18 at 07:21
  • @SalmanS: I suggest you ask a new question with full details. – Jon Skeet Dec 18 '18 at 07:43
79

Here is what I used to get today's date with time set to 00:00:00:

DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");

Date today = new Date();

Date todayWithZeroTime = formatter.parse(formatter.format(today));
Andrea
  • 6,032
  • 2
  • 28
  • 55
Shobbi
  • 897
  • 6
  • 9
68

You can use the DateUtils.truncate from Apache Commons library.

Example:

DateUtils.truncate(new Date(), java.util.Calendar.DAY_OF_MONTH)
Makoto
  • 104,088
  • 27
  • 192
  • 230
JoGo
  • 796
  • 5
  • 5
  • 6
    If you're going to add a new library, let it be Joda instead of Apache Commons. – Dibbeke May 20 '16 at 07:08
  • 9
    +1 @Dibbeke The difference is not just that you would be adding one library instead of another. Sometimes one doesn't want to learn a whole new library just for the trivial task of truncating the time from a date. Or doesn't want to have code that mixes Date / Calendar with Joda dates using sometimes the former and sometimes the latter. Or cannot afford / justify replacing all the well-working Date / Calendar -based code with another library for such a trivial purpose. While suggesting Joda is certainly good as it is clearly superior and simply The Right Thing, sometimes real life kicks in. – SantiBailors Jun 15 '16 at 10:56
45

tl;dr

Is there any other way than these two?

Yes, there is: LocalDate.now

LocalDate.now( 
    ZoneId.of( "Pacific/Auckland" ) 
)

java.time

Java 8 and later comes with the new java.time package built-in. See Tutorial. Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.

Similar to Joda-Time, java.time offers a LocalDate class to represent a date-only value without time-of-day and without time zone.

Note that time zone is critical to determining a particular date. At the stroke of midnight in Paris, for example, the date is still “yesterday” in Montréal.

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ) ;

By default, java.time uses the ISO 8601 standard in generating a string representation of a date or date-time value. (Another similarity with Joda-Time.) So simply call toString() to generate text like 2015-05-21.

String output = today.toString() ; 

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • @ToolmakerSteve Getting the date always involves a time zone. But the trick is that if you fail to specify a time zone, **your JVM’s current default time zone** is automatically applied in determining the date. On top of that, the JVM’s current default time zone can change *at any moment*! Any code in any thread of any app within the JVM can call [`TimeZone.setDefault`](http://docs.oracle.com/javase/8/docs/api/java/util/TimeZone.html#setDefault-java.util.TimeZone-) during runtime and immediately affect all other code running in that JVM. Moral of the Story: Always specify a time zone. – Basil Bourque Sep 06 '15 at 21:38
25

The most straightforward way:

long millisInDay = 60 * 60 * 24 * 1000;
long currentTime = new Date().getTime();
long dateOnly = (currentTime / millisInDay) * millisInDay;
Date clearDate = new Date(dateOnly);
Roman
  • 64,384
  • 92
  • 238
  • 332
  • 6
    For me, this is currently: "Sat Feb 19 **01**:00:00 CET 2011". If you want to use that, then only with UTC. – Chris Lercher Feb 19 '11 at 10:53
  • 5
    Isn't line 3 `long dateOnly = (currentTime / millisInDay) * millisInDay;` the same as writing `long dateOnly = currentTime;` ? – Chris Mar 16 '13 at 11:46
  • 6
    It's not, because of integer math. Think of it more like Math.floor(currentTime / millisInDay) * millisInDay. He's effectively setting the time to 00:00:00 that way. – Blank Jun 22 '13 at 16:11
  • 3
    This solution is probably fine for most application, but be warned the assumption that a day has 60 * 60 * 24 * 1000 is not always true. You can for instance have leap seconds in some days. – Pierre-Antoine Dec 20 '15 at 13:34
  • You consider this straight forward and transparent? – Elemental May 18 '16 at 10:18
  • 2
    This is arguably the most obtuse and not recommended way over other 1 and 2-line clear and concise methods. – Darrell Teague Aug 01 '17 at 18:04
23

The standard answer to these questions is to use Joda Time. The API is better and if you're using the formatters and parsers you can avoid the non-intuitive lack of thread safety of SimpleDateFormat.

Using Joda means you can simply do:

LocalDate d = new LocalDate();

Update:: Using java 8 this can be acheived using

LocalDate date = LocalDate.now();
rajadilipkolli
  • 3,475
  • 2
  • 26
  • 49
Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • The new java.time package in Java 8 also offers a `LocalDate` class similar to Joda-Time. – Basil Bourque Jun 18 '14 at 07:14
  • 1
    Ideally you would pass a `DateTimeZone` to that LocalDate constructor. Determining the current date depends on time zone, as Paris begins a new date earlier than Montréal. If you omit the time zone, your JVM's default time zone is applied. Usually better to specify than rely on default. – Basil Bourque Jun 18 '14 at 07:17
10

This is a simple way of doing it:

Calendar cal = Calendar.getInstance();
SimpleDateFormat dateOnly = new SimpleDateFormat("MM/dd/yyyy");
System.out.println(dateOnly.format(cal.getTime()));
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Glen
  • 155
  • 1
  • 9
7

It does not make sense to talk about a date without a timestamp with regards to the Date routines in the standard java runtime, as it essentially maps down to a specific millisecond and not a date. Said millisecond intrinsically has a time of day attached to it which makes it vulnerable to timezone problems like Daylight Savings Time and other calendar adjustments. See Why is subtracting these two times (in 1927) giving a strange result? for an interesting example.

If you want to work with dates instead of milliseconds, you need to use something else. For Java 8 there is a new set of methods providing exactly what you ask for. For Java 7 and earlier use http://www.joda.org/joda-time/

Community
  • 1
  • 1
Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
  • 3
    Note: Those approaches saying "the date at midnight" does not handle daylight savings time and multiple timezones well. – Thorbjørn Ravn Andersen Feb 19 '11 at 10:38
  • I confirm it, I was incrementing dates by one day in my app, and learned about this with a bug report from users in a timezone with DST (my country does not use DST). In the day DST begins my app adds 11 hours instead of 12. Perhaps using noon as the hour for a "no time" date is better? – Jose_GD Sep 08 '14 at 22:47
  • 1
    @Jose_GD It is at best still a hack. You might find https://www.youtube.com/watch?v=-5wpm-gesOY entertaining. – Thorbjørn Ravn Andersen Sep 08 '14 at 23:18
  • @ Thorbjorn, you're right, just wanted to avoid JodaTime because adding a library for just one feature sound overkill for me. I knew about that video, funny indeed. – Jose_GD Sep 09 '14 at 11:31
  • Errata for my first comment: my app added 23 hours instead of 24 – Jose_GD Sep 09 '14 at 11:32
  • @Jose_GD time handling is one of the cases where adding a library to get it right is a very good idea. And your "add 24 hours to noon repeatedly" would fail in the case in the video where they skipped a day to get on the other side of the date line. – Thorbjørn Ravn Andersen Sep 09 '14 at 12:21
  • Ok, but don't you think that's a "very-edgy-case" for time handling? How often does that change happen? Also, I wonder how JodaTime handles that edge case – Jose_GD Sep 09 '14 at 13:14
  • 1
    @Jose_GD The point was that there is an actual real life use case that in which your approach would be considered a bug. If you found one, there might be more... I do not know how Joda handles this, but you could have a look. Also note that Java 8 brings a new date-time library (based on the experiences with Joda) which you may want to look into. – Thorbjørn Ravn Andersen Sep 10 '14 at 07:01
5
// 09/28/2015
System.out.println(new SimpleDateFormat("MM/dd/yyyy").format(Calendar.getInstance().getTime()));

// Mon Sep 28
System.out.println( new Date().toString().substring(0, 10) );

// 2015-09-28
System.out.println(new java.sql.Date(System.currentTimeMillis()));

// 2015-09-28
// java 8
System.out.println( LocalDate.now(ZoneId.of("Europe/Paris")) ); // rest zones id in ZoneId class
blueberry0xff
  • 3,707
  • 30
  • 18
4

Definitely not the most correct way, but if you just need a quick solution to get the date without the time and you do not wish to use a third party library this should do

    Date db = db.substring(0, 10) + db.substring(23,28);

I only needed the date for visual purposes and couldn't Joda so I substringed.

Bamz
  • 136
  • 1
  • 3
4

If all you want is to see the date like so "YYYY-MM-DD" without all the other clutter e.g. "Thu May 21 12:08:18 EDT 2015" then just use java.sql.Date. This example gets the current date:

new java.sql.Date(System.currentTimeMillis());

Also java.sql.Date is a subclass of java.util.Date.

BigMac66
  • 1,528
  • 5
  • 19
  • 35
3

Use LocalDate.now() and convert into Date like below:

Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());
Sahil Chhabra
  • 10,621
  • 4
  • 63
  • 62
  • 1
    The JVM’s current default time zone can change at any moment during runtime. Any code in any thread of any app within the JVM can call [`TimeZone.setDefault`](https://docs.oracle.com/javase/9/docs/api/java/util/TimeZone.html#setDefault-java.util.TimeZone-). Your code is calling `ZoneId.systemDefault` twice, the first is implicit in `LocalDate.now()` and the second is explicit with `atStartOfDay`. In between those two moments at runtime, the current default zone could change. I suggest capturing the zone into a variable, and pass to both methods. – Basil Bourque Feb 28 '18 at 20:55
3

Well, as far as I know there is no easier way to achieve this if you only use the standard JDK.

You can, of course, put that logic in method2 into a static function in a helper class, like done here in the toBeginningOfTheDay-method

Then you can shorten the second method to:

Calendar cal = Calendar.getInstance();
Calendars.toBeginningOfTheDay(cal);
dateWithoutTime = cal.getTime();

Or, if you really need the current day in this format so often, then you can just wrap it up in another static helper method, thereby making it a one-liner.

Aniket Kulkarni
  • 12,825
  • 9
  • 67
  • 90
Enduriel
  • 111
  • 3
3

What about this?

public static Date formatStrictDate(int year, int month, int dayOfMonth) {
    Calendar calendar = Calendar.getInstance();
    calendar.set(year, month, dayOfMonth, 0, 0, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTime();
}
vitiello.antonio
  • 323
  • 3
  • 12
2

If you need the date part just for echoing purpose, then

Date d = new Date(); 
String dateWithoutTime = d.toString().substring(0, 10);
Manish Singh
  • 5,848
  • 4
  • 43
  • 31
2

If you just need the current date, without time, another option is:

DateTime.now().withTimeAtStartOfDay()
  • 1
    The Question asked for no time-of-day. Your result is a date-time object which does indeed have a time-of-day, that time being `00:00:00` usually (may vary by time zone for anomalies such as [DST](https://en.wikipedia.org/wiki/Daylight_saving_time)). So, as other Answers note, the `LocalDate` class is more appropriate, from Joda-Time (assuming you are referencing Joda-Time – which you should be noting explicitly when citing classes not bundled with Java). – Basil Bourque Aug 22 '16 at 22:42
2

Yo can use joda time.

private Date dateWitoutTime(Date date){
 return new LocalDate(date).toDate()
}

and you call with:

Date date = new Date();
System.out.println("Without Time = " + dateWitoutTime(date) + "/n  With time = " + date);
bobsbeenjamin
  • 193
  • 3
  • 8
Jesús Sánchez
  • 705
  • 11
  • 16
1

The most straigthforward way that makes full use of the huge TimeZone Database of Java and is correct:

long currentTime = new Date().getTime();
long dateOnly = currentTime + TimeZone.getDefault().getOffset(currentTime);
TomWolk
  • 968
  • 10
  • 13
1

Here is a clean solution with no conversion to string and back, and also it doesn't re-calculate time several times as you reset each component of the time to zero. It also uses % (modulus) rather than divide followed by multiply to avoid the double operation.

It requires no third-party dependencies, and it RESPECTS THE TIMEZONE OF THE Calender object passed in. This function returns the moment in time at 12 AM in the timezone of the date (Calendar) you pass in.

public static Calendar date_only(Calendar datetime) {
    final long LENGTH_OF_DAY = 24*60*60*1000;
    long millis = datetime.getTimeInMillis();
    long offset = datetime.getTimeZone().getOffset(millis);
    millis = millis - ((millis + offset) % LENGTH_OF_DAY);
    datetime.setTimeInMillis(millis);
    return datetime;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Brent Larsen
  • 1,042
  • 8
  • 10
1

Check out Veyder-time. It is a simple and efficient alternative to both java.util and Joda-time. It has an intuitive API and classes that represent dates alone, without timestamps.

lonerook
  • 99
  • 3
0

Prefer not to use third-party libraries as much as possible. I know that this way is mentioned before, but here is a nice clean way:

  /*
    Return values:
    -1:    Date1 < Date2
     0:    Date1 == Date2
     1:    Date1 > Date2

    -2:    Error
*/
public int compareDates(Date date1, Date date2)
{
    SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");

    try
    {
        date1 = sdf.parse(sdf.format(date1));
        date2 = sdf.parse(sdf.format(date2));
    }
    catch (ParseException e) {
        e.printStackTrace();
        return -2;
    }

    Calendar cal1 = new GregorianCalendar();
    Calendar cal2 = new GregorianCalendar();

    cal1.setTime(date1);
    cal2.setTime(date2);

    if(cal1.equals(cal2))
    {
        return 0;
    }
    else if(cal1.after(cal2))
    {
        return 1;
    }
    else if(cal1.before(cal2))
    {
        return -1;
    }

    return -2;
}

Well, not using GregorianCalendar is maybe an option!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
hehe
  • 227
  • 5
  • 15
0

I just made this for my app :

public static Date getDatePart(Date dateTime) {
    TimeZone tz = TimeZone.getDefault();
    long rawOffset=tz.getRawOffset();
    long dst=(tz.inDaylightTime(dateTime)?tz.getDSTSavings():0);
    long dt=dateTime.getTime()+rawOffset+dst; // add offseet and dst to dateTime
    long modDt=dt % (60*60*24*1000) ;

    return new Date( dt
                    - modDt // substract the rest of the division by a day in milliseconds
                    - rawOffset // substract the time offset (Paris = GMT +1h for example)
                    - dst // If dayLight, substract hours (Paris = +1h in dayLight)
    );
}

Android API level 1, no external library. It respects daylight and default timeZone. No String manipulation so I think this way is more CPU efficient than yours but I haven't made any tests.

Elloco
  • 235
  • 2
  • 9
0

We can use SimpleDateFormat to format the date as we like. here is a working example below:-

SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
System.out.println(dateFormat.format(new Date())); //data can be inserted in this format function

Output:

15/06/2021
Bathri Nathan
  • 1,101
  • 2
  • 13
  • 17
  • We can also not. The `SimpleDateFormat` class is a notorious troublemaker of a class, so we should avoid it. – Ole V.V. Jun 15 '21 at 16:12