69

I have a class Movie in it i have a start Date, a duration and a stop Date. Start and stop Date are Date Objects (private Date startDate ...) (It's an assignment so i cant change that) now I want to automatically calculate the stopDate by adding the duration (in min) to the startDate.

By my knowledge working with the time manipulating functions of Date is deprecated hence bad practice but on the other side i see no way to convert the Date object to a calendar object in order to manipulate the time and reconvert it to a Date object. Is there a way? And if there is what would be best practice

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
Samuel
  • 18,286
  • 18
  • 52
  • 88
  • 4
    If you're working with dates a lot, I find Joda Time to be far better than Java's Date and Calendar classes: http://joda-time.sourceforge.net/ – Michael Williamson Apr 28 '10 at 08:09
  • 3
    People handing out assignments covering Date/Calendar should be punished. :-) If I were in your position, I would use the sane API added in JAVA 7. – soc Apr 28 '10 at 09:08
  • Similar Question: [Converting a Date object to a calendar object](http://stackoverflow.com/q/6185966/642706) – Basil Bourque Aug 20 '16 at 18:07

8 Answers8

101

What you could do is creating an instance of a GregorianCalendar and then set the Date as a start time:

Date date;
Calendar myCal = new GregorianCalendar();
myCal.setTime(date);

However, another approach is to not use Date at all. You could use an approach like this:

private Calendar startTime;
private long duration;
private long startNanos;   //Nano-second precision, could be less precise
...
this.startTime = Calendar.getInstance();
this.duration = 0;
this.startNanos = System.nanoTime();

public void setEndTime() {
        this.duration = System.nanoTime() - this.startNanos;
}

public Calendar getStartTime() {
        return this.startTime;
}

public long getDuration() {
        return this.duration;
}

In this way you can access both the start time and get the duration from start to stop. The precision is up to you of course.

Lars Andren
  • 8,601
  • 7
  • 41
  • 56
  • 1
    Java's date/time implementation is so shitty that I'm not sure what's worse - keeping JodaTime - even though time computation is a very small part of my app's overall functionality - or switching to Date/Calendar and spending hours wading through the half-assed mess that should've been a well-implemented, solid component. – Melllvar Nov 22 '15 at 06:34
  • @Melllvar So true. Now you have a third alternative: the *java.time* classes built into Java 8 and later. For Java 6 & 7, much of the *java.time* functionality has been back-ported in the *ThreeTen-Backport* project. For earlier Android, see the *ThreeTenABP* project. As for *Joda-Time*, that project is now in maintenance mode, designating *java.time* as its officially successor, its creator Stephen Colebourne having led both projects. – Basil Bourque Jul 17 '18 at 15:28
29
Calendar tCalendar = Calendar.getInstance();
tCalendar.setTime(date);

date is a java.util.Date object. You may use Calendar.getInstance() as well to obtain the Calendar instance(much more efficient).

Bozhidar Batsov
  • 55,802
  • 13
  • 100
  • 117
  • 1
    `Calendar.getInstance()` returns a [locale-specific](http://stackoverflow.com/questions/6905288/getting-current-datetime-using-calendar-getinstance-vs-new-gregoriancalendar) `Calendar` implementation, so it's usually preferable. – hotshot309 Dec 15 '11 at 16:19
6

Calendar.setTime()

It's often useful to look at the signature and description of API methods, not just their name :) - Even in the Java standard API, names can sometimes be misleading.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
6

You don't need to convert to Calendar for this, you can just use getTime()/setTime() instead.

getTime(): Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.

setTime(long time) : Sets this Date object to represent a point in time that is time milliseconds after January 1, 1970 00:00:00 GMT. )

There are 1000 milliseconds in a second, and 60 seconds in a minute. Just do the math.

    Date now = new Date();
    Date oneMinuteInFuture = new Date(now.getTime() + 1000L * 60);
    System.out.println(now);
    System.out.println(oneMinuteInFuture);

The L suffix in 1000 signifies that it's a long literal; these calculations usually overflows int easily.

polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
2

tl;dr

Instant stop = 
    myUtilDateStart.toInstant()
                   .plus( Duration.ofMinutes( x ) ) 
;

java.time

Other Answers are correct, especially the Answer by Borgwardt. But those Answers use outmoded legacy classes.

The original date-time classes bundled with Java have been supplanted with java.time classes. Perform your business logic in java.time types. Convert to the old types only where needed to work with old code not yet updated to handle java.time types.

If your Calendar is actually a GregorianCalendar you can convert to a ZonedDateTime. Find new methods added to the old classes to facilitate conversion to/from java.time types.

if( myUtilCalendar instanceof GregorianCalendar ) {
    GregorianCalendar gregCal = (GregorianCalendar) myUtilCalendar; // Downcasting from the interface to the concrete class.
    ZonedDateTime zdt = gregCal.toZonedDateTime();  // Create `ZonedDateTime` with same time zone info found in the `GregorianCalendar`
end if 

If your Calendar is not a Gregorian, call toInstant to get an Instant object. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.

Instant instant = myCal.toInstant();

Similarly, if starting with a java.util.Date object, convert to an Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Instant instant = myUtilDate.toInstant();

Apply a time zone to get a ZonedDateTime.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

To get a java.util.Date object, go through the Instant.

java.util.Date utilDate = java.util.Date.from( zdt.toInstant() );

For more discussion of converting between the legacy date-time types and java.time, and a nifty diagram, see my Answer to another Question.

Duration

Represent the span of time as a Duration object. Your input for the duration is a number of minutes as mentioned in the Question.

Duration d = Duration.ofMinutes( yourMinutesGoHere );

You can add that to the start to determine the stop.

Instant stop = startInstant.plus( d ); 

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 java.time.

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?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

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.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

something like

movie.setStopDate(movie.getStartDate() + movie.getDurationInMinutes()* 60000);
Xorty
  • 18,367
  • 27
  • 104
  • 155
0

Here is a full example on how to transform your date in different types:

Date date = Calendar.getInstance().getTime();

    // Display a date in day, month, year format
    DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
    String today = formatter.format(date);
    System.out.println("Today : " + today);

    // Display date with day name in a short format
    formatter = new SimpleDateFormat("EEE, dd/MM/yyyy");
    today = formatter.format(date);
    System.out.println("Today : " + today);

    // Display date with a short day and month name
    formatter = new SimpleDateFormat("EEE, dd MMM yyyy");
    today = formatter.format(date);
    System.out.println("Today : " + today);

    // Formatting date with full day and month name and show time up to
    // milliseconds with AM/PM
    formatter = new SimpleDateFormat("EEEE, dd MMMM yyyy, hh:mm:ss.SSS a");
    today = formatter.format(date);
    System.out.println("Today : " + today);
  • The troublesome date-time classes used here (`Date`, `Calendar`) are now legacy, supplanted years ago by the modern *java.time* classes. – Basil Bourque Jul 17 '18 at 15:17
0

Extension for converting date to calendar in Kotlin.

fun Date?.toCalendar(): Calendar? {
    return this?.let { date ->
        val calendar = Calendar.getInstance()
        calendar.time = date
        calendar
    }
}
kulikovman
  • 333
  • 4
  • 8