¿Cómo encontrar la duración de la diferencia entre dos fechas en java?

103

Tengo dos objetos de DateTime , que necesitan encontrar la duración de su diferencia ,

Tengo el siguiente código pero no estoy seguro de cómo continuar para obtener los resultados esperados de la siguiente manera:

Ejemplo

      11/03/14 09:30:58
      11/03/14 09:33:43
      elapsed time is 02 minutes and 45 seconds
      -----------------------------------------------------
      11/03/14 09:30:58 
      11/03/15 09:30:58
      elapsed time is a day
      -----------------------------------------------------
      11/03/14 09:30:58 
      11/03/16 09:30:58
      elapsed time is two days
      -----------------------------------------------------
      11/03/14 09:30:58 
      11/03/16 09:35:58
      elapsed time is two days and 05 mintues

Código

    String dateStart = "11/03/14 09:29:58";
    String dateStop = "11/03/14 09:33:43";

    Custom date format
    SimpleDateFormat format = new SimpleDateFormat("yy/MM/dd HH:mm:ss");

    Date d1 = null;
    Date d2 = null;
    try {
        d1 = format.parse(dateStart);
        d2 = format.parse(dateStop);
    } catch (ParseException e) {
        e.printStackTrace();
    }

    // Get msec from each, and subtract.
    long diff = d2.getTime() - d1.getTime();
    long diffSeconds = diff / 1000 % 60;
    long diffMinutes = diff / (60 * 1000) % 60;
    long diffHours = diff / (60 * 60 * 1000);
    System.out.println("Time in seconds: " + diffSeconds + " seconds.");
    System.out.println("Time in minutes: " + diffMinutes + " minutes.");
    System.out.println("Time in hours: " + diffHours + " hours.");
J888
fuente
5
Eche un vistazo a Joda Time, que ha incorporado soporte para esto.
Erik Pragt
1
qué pasa con su código, solo necesita algunos ajustes para lograr la salida requerida, intentemos
Abubakkar
Primero encuentre la diferencia en horas, con el resto encuentre la diferencia en minutos y luego en segundos.
NINCOMPOOP
1
@PeterLawrey He proporcionado diferentes ejemplos
J888
1
@aquestion duplicación significa dos preguntas que esperan los mismos resultados, el resultado esperado de esta pregunta es diferente al que proporcionó.
Tim Norman

Respuestas:

68

prueba lo siguiente

{
        Date dt2 = new DateAndTime().getCurrentDateTime();

        long diff = dt2.getTime() - dt1.getTime();
        long diffSeconds = diff / 1000 % 60;
        long diffMinutes = diff / (60 * 1000) % 60;
        long diffHours = diff / (60 * 60 * 1000);
        int diffInDays = (int) ((dt2.getTime() - dt1.getTime()) / (1000 * 60 * 60 * 24));

        if (diffInDays > 1) {
            System.err.println("Difference in number of days (2) : " + diffInDays);
            return false;
        } else if (diffHours > 24) {

            System.err.println(">24");
            return false;
        } else if ((diffHours == 24) && (diffMinutes >= 1)) {
            System.err.println("minutes");
            return false;
        }
        return true;
}

fuente
20
Esta respuesta ignora las zonas horarias que definen el comienzo y el final de los días. Esta respuesta ignora el horario de verano y otras anomalías que significan que un día no siempre dura 24 horas. Vea las respuestas correctas que usan las bibliotecas Joda-Time o java.time.
Basil Bourque
3
Como ha señalado Basil, esta respuesta es incorrecta. Da un número incorrecto de días si la fecha de finalización se produce durante el horario de verano, pero la fecha de inicio no.
Dawood ibn Kareem
191

La conversión de diferencia de fecha podría manejarse de una mejor manera usando la clase incorporada de Java, TimeUnit . Proporciona métodos de utilidad para hacer eso:

Date startDate = // Set start date
Date endDate   = // Set end date

long duration  = endDate.getTime() - startDate.getTime();

long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds(duration);
long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(duration);
long diffInHours = TimeUnit.MILLISECONDS.toHours(duration);
long diffInDays = TimeUnit.MILLISECONDS.toDays(duration);
Shamim Ahmmed
fuente
2
Alternativamente long diffInSeconds = TimeUnit.SECONDS.convert (duración, TimeUnit.MILLSECONDS);
gerardw
3
Esta es la mejor respuesta.
Angel Cuenca
2
Apoyo esa moción; Esta respuesta es la mejor.
Mushy
3
Sin dependencia de una biblioteca de terceros.
crmepham
Hola, en primer lugar, muchas gracias por su respuesta corta y agradable, estoy enfrentando un problema en su solución, como si tengo dos fechas 06_12_2017_07_18_02_PM y otra es 06_12_2017_07_13_16_PM, obtengo 286 segundos en su lugar, debería obtener solo 46 segundos
Siddhpura Amit
44

Usar la biblioteca Joda-Time

DateTime startTime, endTime;
Period p = new Period(startTime, endTime);
long hours = p.getHours();
long minutes = p.getMinutes();

Joda Time tiene un concepto de intervalo de tiempo:

Interval interval = new Interval(oldTime, new Instant());

Un ejemplo más de diferencia de fecha

Un enlace más

o con Java-8 (que integró conceptos de Joda-Time)

Instant start, end;//
Duration dur = Duration.between(start, stop);
long hours = dur.toHours();
long minutes = dur.toMinutes();
MayurB
fuente
2
Esta debería ser la respuesta aceptada. Joda Time es el camino a seguir
Bizmarck
La única forma segura de manejar adecuadamente las zonas horarias, los cambios de luz del día, etc.
Newtopian
Solo un pequeño error tipográfico: quiso decir "finalizar" no "detener" en su segunda línea ("Duración dur = Duration.between (start, stop);").
Mohamad Fakih
12

Así es como el problema se puede resolver en Java 8 al igual que la respuesta de shamimz.

Fuente: http://docs.oracle.com/javase/tutorial/datetime/iso/period.html

LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);

Period p = Period.between(birthday, today);
long p2 = ChronoUnit.DAYS.between(birthday, today);

System.out.println("You are " + p.getYears() + " years, " + p.getMonths() + " months, and " + p.getDays() + " days old. (" + p2 + " days total)");

El código produce una salida similar a la siguiente:

You are 53 years, 4 months, and 29 days old. (19508 days total)

Tenemos que usar LocalDateTime http://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html para obtener diferencias de horas, minutos y segundos.

Johnkarka
fuente
Es muy parecido a la forma Joda-Time respondida por MayurB. joda-time.sourceforge.net
johnkarka
1
Su enlace a Joda-Time es antiguo. URL actual es joda.org/joda-time
Basil Bourque
LocalDate no almacena la hora y la zona horaria. Se mantiene solo día-mes-año. ver docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
Shamim Ahmmed
Esto no toma en consideración el tiempo. La pregunta del OP tenía segundos, minutos y horas.
mkobit
7
Date d2 = new Date();
Date d1 = new Date(1384831803875l);

long diff = d2.getTime() - d1.getTime();
long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000);
int diffInDays = (int) diff / (1000 * 60 * 60 * 24);

System.out.println(diffInDays+"  days");
System.out.println(diffHours+"  Hour");
System.out.println(diffMinutes+"  min");
System.out.println(diffSeconds+"  sec");
mkobit
fuente
Hola, en primer lugar, muchas gracias por su respuesta corta y agradable, estoy enfrentando un problema en su solución, como si tengo dos fechas 06_12_2017_07_18_02_PM y otra es 06_12_2017_07_13_16_PM, obtengo 286 segundos en su lugar, debería obtener solo 46 segundos
Siddhpura Amit
6

Puedes crear un método como

public long getDaysBetweenDates(Date d1, Date d2){
return TimeUnit.MILLISECONDS.toDays(d1.getTime() - d2.getTime());
}

Este método devolverá el número de días entre los 2 días.

Vishal Kumar
fuente
5

Como escribe Michael Borgwardt en su respuesta aquí :

int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) )

Tenga en cuenta que esto funciona con fechas UTC, por lo que la diferencia puede ser un día libre si observa las fechas locales. Y lograr que funcione correctamente con las fechas locales requiere un enfoque completamente diferente debido al horario de verano.

Hombre fantasma
fuente
1
No es buena idea multiplicar estos valores manualmente. Más bien use la clase Java TimeUnit para hacer eso.
Shamim Ahmmed
2
Lo que dices sobre las fechas locales no es cierto. El método getTime (), según API doc Devuelve el número de milisegundos desde el 1 de enero de 1970, 00:00:00 GMT representado por este objeto Date. Si dos números tienen la misma unidad, es seguro sumarlos y restarlos.
Ingo
1
Si. Es seguro, pero el código no está limpio, ya que Java proporciona una forma estándar de manejar esto.
Shamim Ahmmed
1
Además de proporcionar un enlace a una respuesta, debe citar claramente las palabras que ha copiado de otros.
Brad Larson
3

En Java 8, se puede hacer de DateTimeFormatter, DurationyLocalDateTime . Aquí hay un ejemplo:

final String dateStart = "11/03/14 09:29:58";
final String dateStop = "11/03/14 09:33:43";

final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendValue(ChronoField.MONTH_OF_YEAR, 2)
        .appendLiteral('/')
        .appendValue(ChronoField.DAY_OF_MONTH, 2)
        .appendLiteral('/')
        .appendValueReduced(ChronoField.YEAR, 2, 2, 2000)
        .appendLiteral(' ')
        .appendValue(ChronoField.HOUR_OF_DAY, 2)
        .appendLiteral(':')
        .appendValue(ChronoField.MINUTE_OF_HOUR, 2)
        .appendLiteral(':')
        .appendValue(ChronoField.SECOND_OF_MINUTE, 2)
        .toFormatter();

final LocalDateTime start = LocalDateTime.parse(dateStart, formatter);
final LocalDateTime stop = LocalDateTime.parse(dateStop, formatter);

final Duration between = Duration.between(start, stop);

System.out.println(start);
System.out.println(stop);
System.out.println(formatter.format(start));
System.out.println(formatter.format(stop));
System.out.println(between);
System.out.println(between.get(ChronoUnit.SECONDS));
mkobit
fuente
3

Me funcionó, puedo intentarlo con esto, espero que sea de ayuda. Avíseme si tiene alguna inquietud.

Date startDate = java.util.Calendar.getInstance().getTime(); //set your start time
Date endDate = java.util.Calendar.getInstance().getTime(); // set  your end time

long duration = endDate.getTime() - startDate.getTime();


long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds(duration);
long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(duration);
long diffInHours = TimeUnit.MILLISECONDS.toHours(duration);
long diffInDays = TimeUnit.MILLISECONDS.toDays(duration);

Toast.makeText(MainActivity.this, "Diff"
        + duration + diffInDays + diffInHours + diffInMinutes + diffInSeconds, Toast.LENGTH_SHORT).show(); **// Toast message for android .**

System.out.println("Diff" + duration + diffInDays + diffInHours + diffInMinutes + diffInSeconds); **// Print console message for Java .**
Tarit Ray
fuente
1
long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds (duración);
Keshav Gera
2

Este es el código:

        String date1 = "07/15/2013";
        String time1 = "11:00:01";
        String date2 = "07/16/2013";
        String time2 = "22:15:10";
        String format = "MM/dd/yyyy HH:mm:ss";
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date fromDate = sdf.parse(date1 + " " + time1);
        Date toDate = sdf.parse(date2 + " " + time2);

        long diff = toDate.getTime() - fromDate.getTime();
        String dateFormat="duration: ";
        int diffDays = (int) (diff / (24 * 60 * 60 * 1000));
        if(diffDays>0){
            dateFormat+=diffDays+" day ";
        }
        diff -= diffDays * (24 * 60 * 60 * 1000);

        int diffhours = (int) (diff / (60 * 60 * 1000));
        if(diffhours>0){
            dateFormat+=diffhours+" hour ";
        }
        diff -= diffhours * (60 * 60 * 1000);

        int diffmin = (int) (diff / (60 * 1000));
        if(diffmin>0){
            dateFormat+=diffmin+" min ";
        }
        diff -= diffmin * (60 * 1000);

        int diffsec = (int) (diff / (1000));
        if(diffsec>0){
            dateFormat+=diffsec+" sec";
        }
        System.out.println(dateFormat);

y la salida es:

duration: 1 day 11 hour 15 min 9 sec
AYRM1112013
fuente
2

con referencia a la actualización de respuesta de shamim, aquí hay un método que realiza la tarea sin usar ninguna biblioteca de terceros. Simplemente copie el método y use

public static String getDurationTimeStamp(String date) {

        String timeDifference = "";

        //date formatter as per the coder need
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        //parse the string date-ti
        // me to Date object
        Date startDate = null;
        try {
            startDate = sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        //end date will be the current system time to calculate the lapse time difference
        //if needed, coder can add end date to whatever date
        Date endDate = new Date();

        System.out.println(startDate);
        System.out.println(endDate);

        //get the time difference in milliseconds
        long duration = endDate.getTime() - startDate.getTime();

        //now we calculate the differences in different time units
        //this long value will be the total time difference in each unit
        //i.e; total difference in seconds, total difference in minutes etc...
        long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds(duration);
        long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(duration);
        long diffInHours = TimeUnit.MILLISECONDS.toHours(duration);
        long diffInDays = TimeUnit.MILLISECONDS.toDays(duration);

        //now we create the time stamps depending on the value of each unit that we get
        //as we do not have the unit in years,
        //we will see if the days difference is more that 365 days, as 365 days = 1 year
        if (diffInDays > 365) {
            //we get the year in integer not in float
            //ex- 791/365 = 2.167 in float but it will be 2 years in int
            int year = (int) (diffInDays / 365);
            timeDifference = year + " years ago";
            System.out.println(year + " years ago");
        }
        //if days are not enough to create year then get the days
        else if (diffInDays > 1) {
            timeDifference = diffInDays + " days ago";
            System.out.println(diffInDays + " days ago");
        }
        //if days value<1 then get the hours
        else if (diffInHours > 1) {
            timeDifference = diffInHours + " hours ago";
            System.out.println(diffInHours + " hours ago");
        }
        //if hours value<1 then get the minutes
        else if (diffInMinutes > 1) {
            timeDifference = diffInMinutes + " minutes ago";
            System.out.println(diffInMinutes + " minutes ago");
        }
        //if minutes value<1 then get the seconds
        else if (diffInSeconds > 1) {
            timeDifference = diffInSeconds + " seconds ago";
            System.out.println(diffInSeconds + " seconds ago");
        }

        return timeDifference;
// that's all. Happy Coding :)
    }
Tarun Kumar
fuente
1

Resolví el problema similar usando un método simple recientemente.

public static void main(String[] args) throws IOException, ParseException {
        TimeZone utc = TimeZone.getTimeZone("UTC");
        Calendar calendar = Calendar.getInstance(utc);
        Date until = calendar.getTime();
        calendar.add(Calendar.DAY_OF_MONTH, -7);
        Date since = calendar.getTime();
        long durationInSeconds  = TimeUnit.MILLISECONDS.toSeconds(until.getTime() - since.getTime());

        long SECONDS_IN_A_MINUTE = 60;
        long MINUTES_IN_AN_HOUR = 60;
        long HOURS_IN_A_DAY = 24;
        long DAYS_IN_A_MONTH = 30;
        long MONTHS_IN_A_YEAR = 12;

        long sec = (durationInSeconds >= SECONDS_IN_A_MINUTE) ? durationInSeconds % SECONDS_IN_A_MINUTE : durationInSeconds;
        long min = (durationInSeconds /= SECONDS_IN_A_MINUTE) >= MINUTES_IN_AN_HOUR ? durationInSeconds%MINUTES_IN_AN_HOUR : durationInSeconds;
        long hrs = (durationInSeconds /= MINUTES_IN_AN_HOUR) >= HOURS_IN_A_DAY ? durationInSeconds % HOURS_IN_A_DAY : durationInSeconds;
        long days = (durationInSeconds /= HOURS_IN_A_DAY) >= DAYS_IN_A_MONTH ? durationInSeconds % DAYS_IN_A_MONTH : durationInSeconds;
        long months = (durationInSeconds /=DAYS_IN_A_MONTH) >= MONTHS_IN_A_YEAR ? durationInSeconds % MONTHS_IN_A_YEAR : durationInSeconds;
        long years = (durationInSeconds /= MONTHS_IN_A_YEAR);

        String duration = getDuration(sec,min,hrs,days,months,years);
        System.out.println(duration);
    }
    private static String getDuration(long secs, long mins, long hrs, long days, long months, long years) {
        StringBuffer sb = new StringBuffer();
        String EMPTY_STRING = "";
        sb.append(years > 0 ? years + (years > 1 ? " years " : " year "): EMPTY_STRING);
        sb.append(months > 0 ? months + (months > 1 ? " months " : " month "): EMPTY_STRING);
        sb.append(days > 0 ? days + (days > 1 ? " days " : " day "): EMPTY_STRING);
        sb.append(hrs > 0 ? hrs + (hrs > 1 ? " hours " : " hour "): EMPTY_STRING);
        sb.append(mins > 0 ? mins + (mins > 1 ? " mins " : " min "): EMPTY_STRING);
        sb.append(secs > 0 ? secs + (secs > 1 ? " secs " : " secs "): EMPTY_STRING);
        sb.append("ago");
        return sb.toString();
    }

Y como era de esperar se imprime: 7 days ago.

akhil_mittal
fuente
0

Este es un programa que escribí, que obtiene el número de días entre 2 fechas (aquí no hay tiempo).

import java.util.Scanner;
public class HelloWorld {
 public static void main(String args[]) {
  Scanner s = new Scanner(System.in);
  System.out.print("Enter starting date separated by dots: ");
  String inp1 = s.nextLine();
  System.out.print("Enter ending date separated by dots: ");
  String inp2 = s.nextLine();
  int[] nodim = {
   0,
   31,
   28,
   31,
   30,
   31,
   30,
   31,
   31,
   30,
   31,
   30,
   31
  };
  String[] inpArr1 = split(inp1);
  String[] inpArr2 = split(inp2);
  int d1 = Integer.parseInt(inpArr1[0]);
  int m1 = Integer.parseInt(inpArr1[1]);
  int y1 = Integer.parseInt(inpArr1[2]);
  int d2 = Integer.parseInt(inpArr2[0]);
  int m2 = Integer.parseInt(inpArr2[1]);
  int y2 = Integer.parseInt(inpArr2[2]);
  if (y1 % 4 == 0) nodim[2] = 29;
  int diff = m1 == m2 && y1 == y2 ? d2 - (d1 - 1) : (nodim[m1] - (d1 - 1));
  int mm1 = m1 + 1, mm2 = m2 - 1, yy1 = y1, yy2 = y2;
  for (; yy1 <= yy2; yy1++, mm1 = 1) {
   mm2 = yy1 == yy2 ? (m2 - 1) : 12;
   if (yy1 % 4 == 0) nodim[2] = 29;
   else nodim[2] = 28;
   if (mm2 == 0) {
    mm2 = 12;
    yy2 = yy2 - 1;
   }
   for (; mm1 <= mm2 && yy1 <= yy2; mm1++) diff = diff + nodim[mm1];
  }
  System.out.print("No. of days from " + inp1 + " to " + inp2 + " is " + diff);
 }
 public static String[] split(String s) {
  String[] retval = {
   "",
   "",
   ""
  };
  s = s + ".";
  s = s + " ";
  for (int i = 0; i <= 2; i++) {
   retval[i] = s.substring(0, s.indexOf("."));
   s = s.substring((s.indexOf(".") + 1), s.length());
  }
  return retval;
 }
}

http://pastebin.com/HRsjTtUf

Naman Chhaparia
fuente
-2
   // calculating the difference b/w startDate and endDate
        String startDate = "01-01-2016";
        String endDate = simpleDateFormat.format(currentDate);

        date1 = simpleDateFormat.parse(startDate);
        date2 = simpleDateFormat.parse(endDate);

        long getDiff = date2.getTime() - date1.getTime();

        // using TimeUnit class from java.util.concurrent package
        long getDaysDiff = TimeUnit.MILLISECONDS.toDays(getDiff);

Cómo calcular la diferencia entre dos fechas en Java

Sugriv Shekhar
fuente