3

I am trying to write some code to correctly set an expiration date given a certain date.

For instance this is what i have.

    Date lastSignupDate = m.getLastSignupDate();
    long expirationDate = 0;
    long milliseconds_in_half_year = 15778463000L;
    expirationDate = lastSignupDate.getTime() + milliseconds_in_half_year; 
    Date newDate = new Date(expirationDate);

However, say if i the sign up date is on 5/7/2011 the expiration date output i get is on 11/6/2011 which is not exactly half of a year from the given date. Is there an easier way to do this?

thunderousNinja
  • 3,510
  • 9
  • 37
  • 49

6 Answers6

4

I would use the Calendar class - the add method will do this kind of thing perfectly.

http://download.oracle.com/javase/6/docs/api/java/util/Calendar.html

    Date date = new Date();
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.add(Calendar.MONTH, 6);

            java.util.Date expirationDate = cal.getTime();

    System.err.println(expirationDate);
planetjones
  • 12,469
  • 5
  • 50
  • 51
  • thank you im guna try this. i cant also convert a calender object to a date object correct? something like this should work: Date t = new Date(cal.getTime().getTime()); – thunderousNinja May 07 '11 at 15:36
  • Yes you can. When you get a Calendar instance back from Calendar.getInstance() that's set to now. I thought your Date might be coming from somewhere else though. The call in my code, cal.getTime(), returns a Date object which represents 6 months in the future - so yes you can convert. – planetjones May 07 '11 at 15:39
2

tl;dr

java.time.LocalDate.of( 2011 , Month.MAY , 7 )
    .plusMonths( 6 )
    .toString()

2011-11-07

java.time

You are using date-time values, so you must account for issues such as time zones, anomalies, and leap year. But you only want a date without a time-of-day and without a time zone, so much easier if you use a date-only class rather than a date-with-time class.

The modern approach uses java.time rather than the troublesome legacy date-time classes.

if i the sign up date is on 5/7/2011 the expiration date output i get is on 11/6/2011 which is not exactly half of a year from the given date

The LocalDate class represents a date-only value without time-of-day and without time zone.

LocalDate ld = LocalDate.of( 2011 , Month.MAY , 7 ) ;

You can do math with the java.time classes. Look for plus… and minus… methods.

LocalDate sixMonthsLater = ld.plusMonths( 6 ) ;

Or pass the amount of time.

Period p = Period.ofMonths( 6 ) ;
LocalDate sixMonthsLater = ld.plus( p ) ;

See this code run live at IdeOne.com.

2011-05-07

2011-11-07


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
2

Here's a simple suggestion using joda-time:

DateTime dt = new DateTime(lastSignupDate);
dt = dt.plusDays(DateTimeConstants.MILLIS_PER_DAY * 365 / 2);
// you can also use dt.plusDays(364 / 2);

You can also use a Calendar:

Calendar c = Calendar.getInstance();
c.setTime(lastSignupDate);
c.add(Calendar.MILLISECOND, MILLIS_PER_DAY * 365 / 2);
// or c.add(Calendar.DAY_OF_YEAR, 364 / 2);
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 1
    FYI, the [Joda-Time](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), with the team advising migration to the [java.time](http://docs.oracle.com/javase/9/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jan 23 '18 at 03:03
0

Do you really need an expiration-date, which is accurate to the millisecond?

I would implement it as 6 Months from x.

Jan. 1 => Jul 1
Sep. 28=> Feb 28
Sep. 29=> Feb 28
Sep. 30=> Feb 28
Oct. 1=>  Mar 1

Maybe you like to be generous, and say 'Mar 1' for 'Sep 29 and 30' too.

user unknown
  • 35,537
  • 11
  • 75
  • 121
0

Here's an example of using Date with TimeUnit that's a little more readable:

long year = TimeUnit.MILLISECONDS.convert(365, TimeUnit.DAYS);
Date expiry = new Date(System.currentTimeMillis() + year);
System.out.println(expiry);

Shame it doesn't have year and day, look at GregorianCalendar or Jodatime for a better API.

Jonathan Holloway
  • 62,090
  • 32
  • 125
  • 150
0
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(new Date().getTime());
// 10 minutes expiration time
calendar.add(calendar.MINUTE, 10);
// prints 10 minutes ahead time  
System.out.println(new Date(calendar.getTime().getTime()));
Navin Kumar
  • 3,393
  • 3
  • 21
  • 46
  • I strongly recommend you don’t use `Calendar` and `Date`. Those classes are poorly designed and long outdated. Instead use [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). See [the answer by Basil Bourque](https://stackoverflow.com/a/48393601/5772882) for the good solution. – Ole V.V. Jul 28 '22 at 14:33