[java] How do I get a Date without time in Java?

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.

This question is related to java date

The answer is


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.


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);

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

Example:

DateUtils.truncate(new Date(), java.util.Calendar.DAY_OF_MONTH)

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()));

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.


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

Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());

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();

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();
}

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;
}

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.


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);

Is there any other way than these two?

Yes, there is.

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.


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

DateTime.now().withTimeAtStartOfDay()

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.


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!


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));

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/


// 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

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

Date d = new Date(); 
String dateWithoutTime = d.toString().substring(0, 10);

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.


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);