Comment trouver la durée de différence entre deux dates en java?

103

J'ai deux objets de DateTime , qui ont besoin de trouver la durée de leur différence ,

J'ai le code suivant mais je ne sais pas comment le continuer pour obtenir les résultats attendus comme suit:

Exemple

      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

Code

    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
la source
5
Veuillez jeter un œil à Joda time, qui a intégré le support pour cela.
Erik Pragt
1
Quel est le problème avec votre code, vous avez juste besoin de quelques ajustements pour obtenir la sortie requise, laissez-le essayer
Abubakkar
Trouvez d'abord la différence en heures, avec le reste trouvez la différence en minutes puis en secondes!
NINCOMPOOP
1
@PeterLawrey J'ai fourni différents exemples
J888
1
@aquestion duplication signifie deux questions qui attendent les mêmes résultats, le résultat attendu de cette question est différent de celui que vous avez fourni.
Tim Norman

Réponses:

68

essayez ce qui suit

{
        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;
}

la source
20
Cette réponse ignore les fuseaux horaires qui définissent le début et la fin des jours. Cette réponse ignore l'heure d'été et d'autres anomalies qui signifient qu'une journée ne dure pas toujours 24 heures. Voir les bonnes réponses qui utilisent les bibliothèques Joda-Time ou java.time.
Basil Bourque
3
Comme Basil l'a souligné, cette réponse est incorrecte. Il donne le mauvais nombre de jours si la date de fin survient pendant l'heure d'été, mais pas la date de début.
Dawood ibn Kareem
191

La conversion de différence de date pourrait être mieux gérée en utilisant la classe intégrée Java, TimeUnit . Il fournit des méthodes utilitaires pour ce faire:

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
la source
2
Alternativement long diffInSeconds = TimeUnit.SECONDS.convert (durée, TimeUnit.MILLSECONDS);
gerardw
3
C'est la meilleure réponse.
Angel Cuenca
2
J'appuie cette motion; Cette réponse est la meilleure.
Mushy le
3
Aucune dépendance à une bibliothèque tierce.
crmepham
Salut tout d'abord merci beaucoup pour votre réponse courte et gentille, je suis confronté à un problème sur votre solution comme j'ai deux date 06_12_2017_07_18_02_PM et une autre est 06_12_2017_07_13_16_PM, je reçois 286 secondes à la place je ne devrais avoir que 46 secondes
Siddhpura Amit
44

Utiliser la bibliothèque Joda-Time

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

Joda Time a un concept d'intervalle de temps:

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

Un autre exemple de différence de date

Un lien de plus

ou avec Java-8 (qui intégrait les concepts Joda-Time)

Instant start, end;//
Duration dur = Duration.between(start, stop);
long hours = dur.toHours();
long minutes = dur.toMinutes();
MayurB
la source
2
Cela devrait être la réponse acceptée. Joda time is the way to go
Bizmarck
Le seul moyen sûr de gérer correctement les fuseaux horaires, les changements de lumière du jour, etc.
Newtopian
Juste une petite faute de frappe: vous vouliez dire "fin" et non "stop" dans votre 2ème ligne ("Duration dur = Duration.b Between (start, stop);").
Mohamad Fakih le
12

Voici comment le problème peut être résolu dans Java 8, tout comme la réponse de shamimz.

Source: 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)");

Le code produit une sortie similaire à ce qui suit:

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

Nous devons utiliser LocalDateTime http://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html pour obtenir des différences d'heures, de minutes et de secondes.

johnkarka
la source
Cela ressemble tellement à la méthode Joda-Time à laquelle MayurB a répondu. joda-time.sourceforge.net
johnkarka
1
Votre lien vers Joda-Time est ancien. L'URL actuelle est joda.org/joda-time
Basil Bourque
LocalDate ne stocke pas l'heure et le fuseau horaire. Il ne conserve que jour-mois-année. voir docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
Shamim Ahmmed
Cela ne prend pas le temps en considération. La question du PO comportait des secondes, des minutes et des heures.
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
la source
Salut tout d'abord merci beaucoup pour votre réponse courte et gentille, je suis confronté à un problème sur votre solution comme j'ai deux date 06_12_2017_07_18_02_PM et une autre est 06_12_2017_07_13_16_PM, je reçois 286 secondes à la place je ne devrais avoir que 46 secondes
Siddhpura Amit
6

Vous pouvez créer une méthode comme

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

Cette méthode retournera le nombre de jours entre les 2 jours.

Vishal Kumar
la source
5

Comme l'écrit Michael Borgwardt dans sa réponse ici :

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

Notez que cela fonctionne avec les dates UTC, donc la différence peut être un jour de congé si vous regardez les dates locales. Et le faire fonctionner correctement avec des dates locales nécessite une approche complètement différente en raison de l'heure d'été.

Ghostman
la source
1
Ce n'est pas une bonne idée de multiplier ces valeurs manuellement. Utilisez plutôt la classe java TimeUnit pour ce faire.
Shamim Ahmmed
2
Ce que vous dites concernant les dates locales n'est pas vrai. La méthode getTime (), selon la documentation de l'API Renvoie le nombre de millisecondes depuis le 1er janvier 1970 à 00:00:00 GMT représenté par cet objet Date. Si deux nombres ont la même unité, il est prudent de les additionner et de les soustraire.
Ingo
1
Oui. C'est sûr mais le code n'est pas propre car le java fournit un moyen standard de gérer cela.
Shamim Ahmmed
1
En plus de fournir un lien vers une réponse, vous devez clairement citer le libellé que vous avez copié sur d'autres.
Brad Larson
3

En Java 8, vous pouvez faire de DateTimeFormatter, Durationet LocalDateTime. Voici un exemple:

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
la source
3

Cela a fonctionné pour moi, je peux essayer avec cela, j'espère que cela sera utile. Faites-moi savoir si vous avez des inquiétudes.

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
la source
1
long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds (durée);
Keshav Gera
2

Voici le code:

        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);

et la sortie est:

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

en référence à la mise à jour des réponses de shamim, voici une méthode qui effectue la tâche sans utiliser de bibliothèque tierce. Copiez simplement la méthode et utilisez

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
la source
1

J'ai récemment résolu le problème similaire en utilisant une méthode simple.

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();
    }

Et comme prévu , il imprime: 7 days ago.

akhil_mittal
la source
0

C'est un programme que j'ai écrit, qui obtient le nombre de jours entre 2 dates (pas d'heure ici).

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
la source
0

java.time.Duration

Je n'avais toujours pas le sentiment qu'aucune des réponses n'était tout à fait à jour et pertinente. Voici donc la réponse moderne utilisant Durationde java.time, l'API de date et d'heure Java moderne (les réponses de MayurB et mkobit mentionnent la même classe, mais aucune d'entre elles ne se convertit correctement en jours, heures, minutes et minutes comme demandé).

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yy/MM/dd HH:mm:ss");
    
    String dateStart = "11/03/14 09:29:58";
    String dateStop = "11/03/14 09:33:43";

    ZoneId zone = ZoneId.systemDefault();
    ZonedDateTime startDateTime = LocalDateTime.parse(dateStart, formatter).atZone(zone);
    ZonedDateTime endDateTime = LocalDateTime.parse(dateStop, formatter).atZone(zone);
    
    Duration diff = Duration.between(startDateTime, endDateTime);
    if (diff.isZero()) {
        System.out.println("0 minutes");
    } else {
        long days = diff.toDays();
        if (days != 0) {
            System.out.print("" + days + " days ");
            diff = diff.minusDays(days);
        }
        long hours = diff.toHours();
        if (hours != 0) {
            System.out.print("" + hours + " hours ");
            diff = diff.minusHours(hours);
        }
        long minutes = diff.toMinutes();
        if (minutes != 0) {
            System.out.print("" + minutes + " minutes ");
            diff = diff.minusMinutes(minutes);
        }
        long seconds = diff.getSeconds();
        if (seconds != 0) {
            System.out.print("" + seconds + " seconds ");
        }
        System.out.println();
    }

La sortie de cet exemple d'extrait de code est:

3 minutes 45 secondes

Notez que cela Durationcompte toujours un jour comme 24 heures. Si vous souhaitez traiter différemment les anomalies horaires comme les transistions d'heure d'été, les solutions inlcude (1) utilisent ChronoUnit.DAYS(2) Use Period(3) Use LocalDateTimeinstead of ZonedDateTime` (peut être considéré comme un hack).

Le code ci-dessus fonctionne avec Java 8 et avec ThreeTen Backport, ce backport de java.time vers Java 6 et 7. À partir de Java 9, il peut être possible de l'écrire un peu plus bien en utilisant les méthodes toHoursPart, toMinutesPartettoSecondsPart y être ajouté.

J'élaborerai davantage les explications un des jours où j'aurai le temps, peut-être pas avant la semaine prochaine.

Ole VV
la source
-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);

Comment calculer la différence entre deux dates en Java

Sugriv Shekhar
la source