Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculating a day given a Date

Tags:

java

date

From a given Date I need to calculate midnight of its day. Here's what I came up with. It's so ugly that I figure there must be a better way.

private Date day(Date creation) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(creation);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTime();
}

Suggestions?

Kent

like image 829
Kent Beck Avatar asked May 31 '09 00:05

Kent Beck


People also ask

How do I calculate days from a date in Excel?

The Excel DAYS function returns the number of days between two dates. With a start date in A1 and end date in B1, =DAYS(B1,A1) will return the days between the two dates.


5 Answers

You should consider the built-in date API obselete. Instead use the Joda date and time API.

Here's a drop-in replacement for your method.

private Date day(Date creation) {
    return new DateMidnight(creation).toDate();
}

Here's a simple test:

public static void main(String[] args) {
    final Date creation = new Date();
    final Date midnight = new Foobar().day(creation);
    System.out.println("creation = " + creation);
    System.out.println("midnight = " + midnight);
}

The output is:

creation = Sun May 31 10:09:38 CEST 2009    
midnight = Sun May 31 00:00:00 CEST 2009
like image 143
Steve McLeod Avatar answered Oct 02 '22 23:10

Steve McLeod


JODA might have a better solution, at the cost of another dependency on a library. I'm looking at its DateMidnight property. I'm sorry that I can't answer more authoritatively, but I'm not a JODA user myself.

like image 29
duffymo Avatar answered Oct 02 '22 21:10

duffymo


If you're looking for local time, that's the best you're going to get. And although you may consider it ugly, there's (potentially) a lot going on behind the scenes.

If you want midnight UTC, the following will work:

public static void main(String[] argv)
throws Exception
{
    final long MILLIS_PER_DAY = 24 * 3600 * 1000L;

    long midnightUTC = (System.currentTimeMillis() / MILLIS_PER_DAY) * MILLIS_PER_DAY;
}

Edit: I really don't recommend using local dates in "production" code. They cause more trouble than they're worth -- consider a person on the US west coast who suddenly finds his/her "day" trimmed by 3 hours because an east coast computer has a different idea of midnight.

like image 36
kdgregory Avatar answered Oct 02 '22 23:10

kdgregory


JODA is the way to go if you have serious calendar needs, at least until JSR-310 gets into the JDK (1.7 maybe, if not 1.8).

That being said, there are a couple of things that could be done to make this code a little nicer.

import static java.util.Calendar.*;

...

private static final List<Integer> TIME_FIELDS = 
    Arrays.asList(HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND);

private Date day(Date creation) {
     Calendar c = getInstance();
     c.setTime(creation);
     for(int field : TIME_FIELDS) c.set(field, 0);
     return c.getTime();
}

That won't win any performance awards. You could do a standard for loop relying on the specific field values (the Calendar class has a FIELD_COUNT field kind of implying you can do something like that) but that risks issues across JDK implementations and between versions.

like image 41
Yishai Avatar answered Oct 02 '22 21:10

Yishai


Using the date4j library :

DateTime start = dt.getStartOfDay();
like image 28
John Avatar answered Oct 02 '22 23:10

John