javacalendar

Getting wrong time after calculating difference between two Dates


I want to calculate the difference between a certain date and the current time.

 int month = 9;
 int day = 17;
 int year = 2013;

 Calendar date = new GregorianCalendar(year, month, day);

 int miliseconds= (int) (System.currentTimeMillis() - calendar.getTimeInMillis());

 System.out.println(msToString(second));

 String msToString(int ms) {
    return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")).format(new Date(ms));
 }

the output is

13091-13091/? D/GTA: 1970-01-08 15:00:20.287

I want to get the amount of days, hours,minutes and seconds remaining.

What do I wrong?


Solution

  • tl;dr

    Duration           // Represent a span-of-time on a scale of hours-minutes-seconds.
        .between (
            LocalDate  // Represent a date-only, without time-of-day, without time zone.
                .of( year , month , day )
                .atStartOfDay( ZoneId.of( "Africa/Tunis" ) )  // Returns a `ZonedDateTime`. 
                .toInstant() ,  // Extracts a `Instant` from `ZonedDateTime`, effectively adjusting from time zone to UTC. 
            Instant.now()       // Current moment as seen in UTC, offset of zero.
        )
        .toString()   // Generate text in standard ISO 8601 format.
    

    java.time

    Never use terribly-flawed legacy classes such as Date, Calendar, and SimpleDateFormat. Use only the java.time classes defined in JSR 310.

    You said:

    new GregorianCalendar(year, month, day)

    You must become aware of the time zone that is implicitly bound in that GregorianCalendar calendar. That time zone is the JVM’s current default time zone. Avoid such implicit use, as that current default can be changed at any time by any code in any thread of any app running within that JVM. Instead specify your desired/expected time zone.

    ZoneId z = ZoneId.of( "America/Edmonton" ) ;
    

    And use ZonedDateTime rather than GregorianCalendar.

    LocalDate ld = LocalDate.of( year , month , day ) ;  // Notice sane numbering: Months are 1-12 for January-December unlike the crazy legacy classes.
    ZonedDateTime startOfDayZdt = ld.atStartOfDay( z ) ;
    

    You said:

    the current time.

    So capture the current moment. Here we capture the current moment as seen in UTC, with an offset of zero hours-minutes-seconds.

    Instant now = Instant.now() ;
    

    You said:

    difference between a certain date and the current time.

    To calculate elapsed time on a scale of 24-hour-long generic days, hours, minutes, and seconds, use Duration class.

    Duration d = Duration.between( startOfDayZdt.toInstant() , now ) ;
    

    Generate text to represent that elapsed time, in standard ISO 8601 format.

    String output = d.toString() ;
    

    Avoid using clock-time format to represent a span of time. Such text is tragically ambiguous, easily misread by humans. Use ISO 8601 format instead, or generate text using the to…Part methods on Duration.