Calculer le temps écoulé en Java / Groovy


J'ai...


Date start = new Date()

...
...
...

Date stop = new Date()

J'aimerais obtenir les années, les mois, les jours, les heures, les minutes et les secondes écoulées entre ces deux dates.

--

Je vais affiner la question.

Je veux juste obtenir le temps écoulé, en tant que mesure absolue, c'est-à-dire sans tenir compte des années bissextiles, des jours de chaque mois, etc.

Donc je pense qu'il est impossible d'obtenir les années et les mois écoulés, tout ce que je peux obtenir, ce sont des jours, des heures, des minutes et des secondes.

Plus précisément I vous voulez dire qu'une certaine tâche a duré par exemple

20 sec
13 min, 4 sec
2 h, 10 min, 2 sec
4 d, 4 h, 2 min, 2 sec

Veuillez donc pardonner mon manque de précision.

Author: S.L. Barth, 2009-02-20

14 answers

Je viens de découvrir cette solution rapide Groovy-sourced:

import groovy.time.TimeCategory 
import groovy.time.TimeDuration

TimeDuration td = TimeCategory.minus( stop, start )
println td
 89
Author: pd., 2015-08-13 05:44:52

Vous pouvez faire tout cela avec division et mod.

long l1 = start.getTime();
long l2 = stop.getTime();
long diff = l2 - l1;

long secondInMillis = 1000;
long minuteInMillis = secondInMillis * 60;
long hourInMillis = minuteInMillis * 60;
long dayInMillis = hourInMillis * 24;

long elapsedDays = diff / dayInMillis;
diff = diff % dayInMillis;
long elapsedHours = diff / hourInMillis;
diff = diff % hourInMillis;
long elapsedMinutes = diff / minuteInMillis;
diff = diff % minuteInMillis;
long elapsedSeconds = diff / secondInMillis;

Qui devrait vous donner toutes les informations que vous avez demandées.

EDIT: Puisque les gens semblent être confus, non, cela ne prend pas en compte des choses comme les années bissextiles ou les changements d'heure d'été. C'est du pur temps écoulé , ce que opensas a demandé.

 25
Author: Sebastian Celis, 2013-03-27 17:57:02

Pas si facile avec l'API de date standard.

, Vous voudrez peut-être regarder à Joda Time, ou JSR 310 à la place.

Je ne suis pas un expert en Joda, mais je pense que le code serait:

Interval interval = new Interval(d1.getTime(), d2.getTime());
Period period = interval.toPeriod();
System.out.printf(
    "%d years, %d months, %d days, %d hours, %d minutes, %d seconds%n", 
    period.getYears(), period.getMonths(), period.getDays(),
    period.getHours(), period.getMinutes(), period.getSeconds());
 19
Author: toolkit, 2009-02-20 09:05:24

En ce qui concerne JodaTime je viens de le faire; merci au répondeur qui l'a suggéré. Voici une version plus condensée du code Joda suggéré:

Period period = new Period(d1.getTime(), d2.getTime());
System.out.printf(
    "%d years, %d months, %d days, %d hours, %d minutes, %d seconds%n", 
    period.getYears(), period.getMonths(), period.getDays(),
    period.getHours(), period.getMinutes(), period.getSeconds());

(je ne sais pas si cela aide la question d'origine mais certainement les chercheurs).

 10
Author: Fletch, 2009-09-21 14:59:29

Eh bien depuis Java 1.5, vous devriez utiliser TimeUnit.

Voici un exemple simple et simple pour cela. Je pense que dans groovy, cela pourrait devenir plus court (comme toujours).

/**
 * Formats a given {@link Date} to display a since-then timespan.
 * @param created
 * @return String with a format like "3 minutes ago"
 */
public static String getElapsedTime(Date created) {
    long duration = System.currentTimeMillis() - created.getTime();
    long seconds = TimeUnit.MILLISECONDS.toSeconds(duration);
    long days = TimeUnit.MILLISECONDS.toDays(duration);
    long hours = TimeUnit.MILLISECONDS.toHours(duration);
    long minutes = TimeUnit.MILLISECONDS.toMinutes(duration);
    if (days > 0) {
        return days + " days";
    }
    if (hours > 0) {
        return hours + " hrs";
    }
    if (minutes > 0) {
        return minutes + " minutes";
    }

    return seconds + " seconds";
}

Oh et évitez les retours multiples veuillez;)

 6
Author: dhesse, 2010-05-18 11:33:27

En fait, en ce qui concerne les réponses ci-dessus sur Joda-Time.

Il existe un moyen plus simple de le faire avec la classe Period de Joda-Time:

Period period = new Period(startDate, endDate);
System.out.println(PeriodFormat.getDefault().print(period));

Pour personnaliser la sortie, regarder dans la PeriodFormat, PeriodFormatter, et PeriodFormatterBuilder classes.

 6
Author: simao, 2014-07-08 22:22:54

Tl; dr

Duration.between( then , Instant.now() )

Utilisation de java.temps

La manière moderne utilise le java.classes de temps qui supplantent les anciennes classes de date-heure gênantes.

Au Lieu de Date, utiliser Instant. L'Instant la classe représente un moment dans le scénario de UTC, avec une résolution de nanosecondes (jusqu'à neuf (9) chiffres d'une fraction décimale).

Instant then = Instant.now();
…
Instant now = Instant.now();

Utiliser le Duration classe pour une période de temps non attachée à la timeline, avec une résolution de les jours-heures-minutes-secondes-nanos.

Duration d = Duration.between( then , now );

Pour un laps de temps avec une résolution des années-mois-jours, utilisez le Period classe.

Générer une chaîne de caractères est standard ISO 8601 format pour des durées: PnYnMnDTnHnMnS. Le P marque le début. Le T sépare les années-mois-jours des heures-minutes-secondes. Donc, deux heures et demie est PT2H30M.

String output = d.toString();

Dans Java 9 et versions ultérieures, vous pouvez accéder aux parties individuelles avec des méthodes toDaysPart, toHoursPart, et ainsi de suite.


À propos de java.temps

Le java.time framework est intégré à Java 8 et versions ultérieures. Ces classes permettent d'éviter la pénible vieux héritage date-heure classes telles que java.util.Date, Calendar, & SimpleDateFormat.

Le projet Joda-Time, maintenant en mode maintenance, conseille la migration vers le java.temps classes.

Pour en savoir plus, consultez le tutoriel Oracle. Et pile de recherche Débordement pour de nombreux exemples et explications. La spécification est JSR 310.

Où obtenir le java.les classes de temps?

Le Le projet ThreeTen-Extra étend java.temps avec des cours supplémentaires. Ce projet est un terrain d'essai pour d'éventuels ajouts futurs à java.temps. Vous pouvez trouver quelques classes utiles ici comme Interval, YearWeek, YearQuarter, et plus.

 5
Author: Basil Bourque, 2017-05-23 10:31:13

Hmm, si je suis ce que vous demandez, vous voulez savoir que si:

Début = 1er janvier 2001, 10:00:00.000 am et

Stop = 6 janvier 2003, 12:01:00.000 pm

Vous voulez une réponse de 2 ans, 0 mois, 5 jours, 2 heures, 1 minute

Malheureusement, c'est une réponse spécieuse. Et si les dates étaient Jan 2, et Jan 31? Ce serait 29 jours? Ok, mais le 2 février au 2 mars est de 28 (29) jours, mais serait répertorié comme 1 mois?

La durée en autre chose que les secondes ou peut-être que les jours sont variables sans connaître le contexte car les mois et les années sont de longueurs différentes. La différence entre 2 dates doit être en unités statiques, qui sont facilement calculables à partir de l'arrêt.getTime () - démarrer.getTime () (qui est la différence en millisecs)

 3
Author: billjamesdev, 2009-02-19 23:15:13

En dehors de la grande JodaTime API susmentionnée que je fais recommande, la meilleure alternative Java standard que vous pouvez avoir est la java.util.Calendar. Il est encombrant de travailler avec lui (c'est un euphémisme .. regardez les exemples de JodaTime à une ligne ici), mais vous pouvez également calculer le temps écoulé avec. La clé importante est que vous devez utiliser le Calendar#add() dans une boucle pour obtenir la valeur écoulée pendant des années, des mois et des jours pour prendre des jours bissextiles, des années et siècles en compte. Vous ne devez pas les calculer à partir des (milli)secondes.

Voici un exemple de base:

import java.util.Calendar;

public class Test {

    public static void main(String[] args) throws Exception {
        Calendar start = Calendar.getInstance();
        start.set(1978, 2, 26, 12, 35, 0); // Just an example.
        Calendar end = Calendar.getInstance();

        Integer[] elapsed = new Integer[6];
        Calendar clone = (Calendar) start.clone(); // Otherwise changes are been reflected.
        elapsed[0] = elapsed(clone, end, Calendar.YEAR);
        clone.add(Calendar.YEAR, elapsed[0]);
        elapsed[1] = elapsed(clone, end, Calendar.MONTH);
        clone.add(Calendar.MONTH, elapsed[1]);
        elapsed[2] = elapsed(clone, end, Calendar.DATE);
        clone.add(Calendar.DATE, elapsed[2]);
        elapsed[3] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 3600000;
        clone.add(Calendar.HOUR, elapsed[3]);
        elapsed[4] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 60000;
        clone.add(Calendar.MINUTE, elapsed[4]);
        elapsed[5] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 1000;

        System.out.format("%d years, %d months, %d days, %d hours, %d minutes, %d seconds", elapsed);
    }

    private static int elapsed(Calendar before, Calendar after, int field) {
        Calendar clone = (Calendar) before.clone(); // Otherwise changes are been reflected.
        int elapsed = -1;
        while (!clone.after(after)) {
            clone.add(field, 1);
            elapsed++;
        }
        return elapsed;
    }

}

Il devrait imprimer mon âge à partir de maintenant=)

Oh, je dois ajouter, vous pouvez "convertir" Date à Calendar utiliser Calendar#setTime().

 3
Author: BalusC, 2009-12-07 18:45:33

C'est facile, Vous devez définir le bon fuseau horaire

import java.util.TimeZone;
import java.util.logging.Logger;

import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class ImportData {

    private final static Logger log = Logger.getLogger(ImportData.class.getName());
    private final static DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS");
    private final static DateTimeFormatter dtfh = DateTimeFormat.forPattern("HH:mm:ss.SSS");

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
       TimeZone.setDefault(TimeZone.getTimeZone("Europe/Berlin"));
       DateTimeZone.setDefault(DateTimeZone.forID("Europe/Berlin"));
       // Quotes connection=Quotes.getInstance();
       final long start  = System.currentTimeMillis();
       // do something here ...
       // connection.importTickdata();
       Thread.currentThread().sleep(2000);
       final long end  = System.currentTimeMillis();
       log.info("[start]    " + dtf.print(start));
       log.info("[end]      " + dtf.print(end));
       TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
       DateTimeZone.setDefault(DateTimeZone.forID("UTC"));
       log.info("[duration] " + dtfh.print(end - start));
       // connection.logOff();
       // System.exit(0);
    }

Renvoie:

10.11.2010 00:08:12 ImportData main
INFO: [start]    2010-11-10 00:08:10.306
10.11.2010 00:08:12 ImportData main
INFO: [end]      2010-11-10 00:08:12.318
10.11.2010 00:08:12 ImportData main
INFO: [duration] 00:00:02.012
 1
Author: udoline, 2010-11-10 18:03:51

Il ne sert à rien de créer un objet Date car tout cela ne fait qu'envelopper le système.currentTimeMillis (). La fonction getTime () déballe simplement l'objet Date. Je vous suggère simplement d'utiliser cette fonction pour obtenir un long.

Si vous n'avez besoin que d'une deuxième précision, c'est très bien. Cependant, si vous voulez une précision inférieure à la milliseconde, utilisez le système.nanoTime() pour obtenir le temps écoulé.

 0
Author: Peter Lawrey, 2009-11-21 19:49:13

Il s'agit d'une fonction complète que j'ai implémentée sur la base de la réponse Sebastian Celis. Et encore une fois, de son post - cela ne prend pas en compte des choses comme les années bissextiles ou les changements d'heure d'été. C'est du pur temps écoulé.

La sortie est adaptée à mes besoins. Cela ne produit que trois sections significatives. Au lieu de retourner

4 mois, 2 semaines, 3 jours, 7 heures, 28 minutes, 43 secondes

Il renvoie simplement le premier bloc 3 (voir plus d'échantillon exécuté à la fin du post):

4 mois, 2 semaines, 3 jours

Voici le code source complet de la méthode:

/**
 * Format milliseconds to elapsed time format
 * 
 * @param time difference in milliseconds
 * @return Human readable string representation - eg. 2 days, 14 hours, 5 minutes
 */
public static String formatTimeElapsedSinceMillisecond(long milisDiff) {
    if(milisDiff<1000){ return "0 second";}

    String formattedTime = "";
    long secondInMillis = 1000;
    long minuteInMillis = secondInMillis * 60;
    long hourInMillis = minuteInMillis * 60;
    long dayInMillis = hourInMillis * 24;
    long weekInMillis = dayInMillis * 7;
    long monthInMillis = dayInMillis * 30;

    int timeElapsed[] = new int[6];
    // Define time units - plural cases are handled inside loop
    String timeElapsedText[] = {"second", "minute", "hour", "day", "week", "month"};
    timeElapsed[5] = (int) (milisDiff / monthInMillis); // months
    milisDiff = milisDiff % monthInMillis;
    timeElapsed[4] = (int) (milisDiff / weekInMillis); // weeks
    milisDiff = milisDiff % weekInMillis;
    timeElapsed[3] = (int) (milisDiff / dayInMillis); // days
    milisDiff = milisDiff % dayInMillis;
    timeElapsed[2] = (int) (milisDiff / hourInMillis); // hours
    milisDiff = milisDiff % hourInMillis;
    timeElapsed[1] = (int) (milisDiff / minuteInMillis); // minutes
    milisDiff = milisDiff % minuteInMillis;
    timeElapsed[0] = (int) (milisDiff / secondInMillis); // seconds

    // Only adds 3 significant high valued units
    for(int i=(timeElapsed.length-1), j=0; i>=0 && j<3; i--){
        // loop from high to low time unit
        if(timeElapsed[i] > 0){
            formattedTime += ((j>0)? ", " :"") 
                + timeElapsed[i] 
                + " " + timeElapsedText[i] 
                + ( (timeElapsed[i]>1)? "s" : "" );
            ++j;
        }
    } // end for - build string

    return formattedTime;
} // end of formatTimeElapsedSinceMillisecond utility method

Voici quelques exemples de déclaration de test:

System.out.println(formatTimeElapsedSinceMillisecond(21432424234L));
// Output: 8 months, 1 week, 1 day

System.out.println(formatTimeElapsedSinceMillisecond(87724294L));
// Output: 1 day, 22 minutes, 4 seconds

System.out.println(formatTimeElapsedSinceMillisecond(123434L));
// Output: 2 minutes, 3 seconds
 0
Author: Hossain Khan, 2011-08-19 17:30:38

Il s'agit d'une autre fonction similaire, elle n'apparaîtra pas de jours, d'heures, de minutes, etc. si ce n'est pas nécessaire, changez ses littéraux si nécessaire.

public class ElapsedTime {

    public static void main(String args[]) {

        long start = System.currentTimeMillis();
        start -= (24 * 60 * 60 * 1000 * 2);
        start -= (60 * 60 * 1000 * 2);
        start -= (60 * 1000 * 3);
        start -= (1000 * 55);
        start -= 666;
        long end = System.currentTimeMillis();
        System.out.println(elapsedTime(start, end));

    }

    public static String elapsedTime(long start, long end) {

        String auxRet = "";

        long aux = end - start;
        long days = 0, hours = 0, minutes = 0, seconds = 0, milliseconds = 0;
        // days
        if (aux > 24 * 60 * 60 * 1000) {
            days = aux / (24 * 60 * 60 * 1000);
        }
        aux = aux % (24 * 60 * 60 * 1000);
        // hours
        if (aux > 60 * 60 * 1000) {
            hours = aux / (60 * 60 * 1000);
        }
        aux = aux % (60 * 60 * 1000);
        // minutes
        if (aux > 60 * 1000) {
            minutes = aux / (60 * 1000);
        }
        aux = aux % (60 * 1000);
        // seconds
        if (aux > 1000) {
            seconds = aux / (1000);
        }
        milliseconds = aux % 1000;

        if (days > 0) {
            auxRet = days + " days ";
        }
        if (days != 0 || hours > 0) {
            auxRet += hours + " hours ";
        }
        if (days != 0 || hours != 0 || minutes > 0) {
            auxRet += minutes + " minutes ";
        }
        if (days != 0 || hours != 0 || minutes != 0 || seconds > 0) {
            auxRet += seconds + " seconds ";
        }
        auxRet += milliseconds + " milliseconds ";

        return auxRet;
    }

}
 0
Author: jcgonzalez, 2012-11-09 07:12:02

C'est un problème et un algorithme doit être fait pour tenir compte des années bissextiles et du nombre exact de mois et de jours à côté des années. Intéressant comment il est simple si une seule unité de mesure doit être utilisée. Par exemple, le nombre total de jours entre deux jours est correct car apposé au nombre de jours de rappel après le nombre de mois et d'années est calculé dans les deux décennies.

Je travaille actuellement sur cela pour le fournir à partir de mon implémentation PML, par exemple, sous la forme de:

unemployed <- date.difference[
    From = 2009-07-01, 
    Till = now, 
    YEARS, MONTHS, DAYS
]: yyyy-MM-dd

$$-> *unemployed -> date.translate[ YEARS, MONTHS, DAYS ] -> print["Unemployed for:", .]

Bien sûr, cela serait également utile et nécessaire pour les calculs exacts des taux d'intérêt.

 -1
Author: buda, 2012-12-01 00:02:16