views:

338

answers:

6
+2  Q: 

Get Previous Day

Possible Duplicate:
How to determine the date one day prior to a given date in Java?

If I have a Java.Util.Date object, what is the best way to get an object representing the 24 hours in the past of it?

+1  A: 

Switch to Calendar objects, they are 100% easier to do things like this on.

Gandalf
A: 

subtract 1000*60*60*24 from the time and create a new date.

Date yesterday = new Date(d.getTime() - (1000*60*60*24));
This will yield the wrong result during daylight savings time switches
Michael Borgwardt
actually, the Calendar would be wrong. The question was 24 hours in the past, not yesterday at the same time.
Almost certainly the question itself was wrong, i.e. the OP did not think of this special case - and it disagrees on this point with the title "get previous day"
Michael Borgwardt
+12  A: 

Using Java 1.6 java.util.Calendar.add:

public static Date subtractDay(Date date) {

    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.add(Calendar.DAY_OF_MONTH, -1);
    return cal.getTime();
}

Others suggest using Joda Time, which is currently JSR 310, and should later be included in Java itself.

Jared Oberhaus
I'd remove the method context - it doesn't add anything and makes me cringe for it's lack of flexibility.
Michael Borgwardt
looking forward to this in 1.6...dates have always been a bugbear of mine in Java
miguel
A: 
    int dayInMs = 1000 * 60 * 60 * 24;
    Date previousDay = new Date(olddate.getTime() - dayInMs);

Personally if there are a lot of time/date calculations, I'd go with Joda-time.

Blake Pettersson
Bad code, which will be 1 hour off on daylight savings time switches
Michael Borgwardt
As you yourself noted in the comments above, Nathaniel is probably unaware of the difference, so he needs to rething what he actually means.
Michael Borgwardt
I see... I gave more weight for the text ("24 hours") instead of the title ("previous day").
Carlos Heuberger
+1  A: 

It may not be applicable to your situation, but... JodaTime is a much simpler API for date/time calculations than the standard Date and Calendar classes in java.util.

Nat
A: 

The important thing to remember is that the Date class should represent any points in time whilst the Calendar class is used to manipulate those points in time. Last of all, SimpleDateFormat will represent them as Strings.

So, the best way is to use the Calendar class to calculate the new Date for you. This will ensure that any vagaries (Daylight Saving, Leap Years and the like) are accounted for.

I'm assuming that you don't really want to find '24 Hours previous' but actually do want a new Date instance representing 'this time yesterday' - either way, you can ask the Calendar instance for a Date 24Hours prior to another or 1 Day prior.

The Daylight savings is a great example. The UK 'sprang forward' on the 26th March 2009. So, 1 day prior to 3.00a.m. on the 26.Mar.2009 should yield 3.00a.m. 25.Mar.2009 but 24 Hrs prior will yield 2.00a.m.

public class DateTests extends TestCase {
  private static String EXPECTED_SUMMER_TIME = "2009.Mar.29 03:00:00";
  private static String EXPECTED_SUMMER_TIME_LESS_DAY = "2009.Mar.28 03:00:00";
  private static String EXPECTED_SUMMER_TIME_LESS_24_HRS = "2009.Mar.28 02:00:00";
  private static String EXPECTED_SUMMER_TIME_LESS_FURTHER_24_HRS = "2009.Mar.27 02:00:00";

  public void testSubtractDayOr24Hours() {

    SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MMM.dd HH:mm:SS");

    Calendar calendar = Calendar.getInstance();

    // Create our reference date, 3.00 a.m. on the day the clocks go forward (they 'went' forward at 02.00)
    calendar.clear();
    calendar.set(2009, 2, 29, 3, 0);

    Date summerTime = calendar.getTime(); // Sun Mar 29 03:00:00 BST 2009
    String formattedSummerTime = formatter.format(summerTime);
    calendar.add(Calendar.DAY_OF_MONTH, -1);

    // Our reference date less 'a day'
    Date summerTimeLessADay = calendar.getTime(); // Sat Mar 28 03:00:00 GMT 2009
    String formattedSummerTimeLessADay = formatter.format(summerTimeLessADay);

    // reset the calendar instance to the reference day
    calendar.setTime(summerTime);

    // Our reference date less '24 hours' (is not quite 24 hours)
    calendar.add(Calendar.HOUR, -24);
    Date summerTimeLess24Hrs = calendar.getTime(); // Sat Mar 28 02:00:00 GMT 2009
    String formattedSummerTimeLess24Hrs = formatter.format(summerTimeLess24Hrs);

    // Third date shows that taking a further 24 hours from yields expected result
    calendar.add(Calendar.HOUR, -24);
    Date summerTimeLessFurther24Hrs = calendar.getTime(); // Fri Mar 27 02:00:00 GMT 2009
    String formattedSummerTimeLessFurther24Hrs = formatter.format(summerTimeLessFurther24Hrs);

    // reset the calendar once more to the day before
    calendar.setTime(summerTimeLess24Hrs);

    // Take a 'day' from the Sat will yield the same result as date 03 because Daylight Saving is not a factor
    calendar.add(Calendar.DAY_OF_MONTH, -1);
    Date summerTimeLessFurtherDay = calendar.getTime(); // Fri Mar 27 02:00:00 GMT 2009
    String formattedSummerTimeLessFurtherDay = formatter.format(summerTimeLessFurtherDay);

    assert(formattedSummerTime.equals(EXPECTED_SUMMER_TIME));
    assert(formattedSummerTimeLessADay.equals(EXPECTED_SUMMER_TIME_LESS_DAY));
    assert(formattedSummerTimeLess24Hrs.equals(EXPECTED_SUMMER_TIME_LESS_24_HRS));

    assert(formattedSummerTimeLessFurther24Hrs.equals(EXPECTED_SUMMER_TIME_LESS_FURTHER_24_HRS));

    // This last test proves that taking 24 hors vs. A Day usually yields the same result
    assert(formattedSummerTimeLessFurther24Hrs.equals(formattedSummerTimeLessFurtherDay));

  }
}

For testing date functions, wwwdot-timeanddate-dot-com is a great resource.