Calculer le temps écoulé En Java / Groovy

j'ai...


Date start = new Date()

...
...
...

Date stop = new Date()

j'aimerais avoir les années, mois, jours, heures, minutes et secondes ellapsed entre ces deux dates.

--

je vais affiner la question.

je veux juste obtenir le temps écoulé, comme 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 des mois se sont écoulés, tout ce que je peux avoir c'est des jours, des heures, des minutes et des secondes.

plus précisément, je veux dire qu'une certaine tâche a duré pour par exemple

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

alors pardonnez mon manque de précision.

38
demandé sur S.L. Barth 2009-02-20 02:03:39

14 réponses

je viens de découvrir cette solution rapide et originale:

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

TimeDuration td = TimeCategory.minus( stop, start )
println td
89
répondu 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 des choses comme les années bissextiles ou les commutateurs d'heure d'été en compte. Il est pur écoulé temps , qui est ce que opensas demandé.

25
répondu Sebastian Celis 2013-03-27 17:57:02

pas si facile avec L'API Date standard.

Vous voudrez peut-être chercher à 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
répondu toolkit 2009-02-20 09:05:24

en ce qui concerne JodaTime je viens de le faire démarrer; merci à l'intervenant 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());

(pas sûr que cela aide la question originale, mais certainement les chercheurs).

10
répondu Fletch 2009-09-21 14:59:29

bien depuis Java 1.5 vous devez utiliser TimeUnit.

voici un exemple simple et simple pour cela. Je pense qu'en groovy il 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 éviter de multiples retours s'il vous plaît ;)

6
répondu dhesse 2010-05-18 11:33:27

en Fait, concernant les réponses ci-dessus à propos de Joda-Time .

il y a une façon plus facile de le faire avec la classe

de Joda-Time période classe:

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

pour personnaliser la sortie, regardez dans les PeriodFormat , PeriodFormatter , et PeriodFormatterBuilder classes.

6
répondu simao 2014-07-08 22:22:54

tl; dr

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

utilisant java.time

d'une façon moderne utilise le java.les classes de temps qui remplacent les vieilles classes de date ennuyeuses.

au lieu de Date , utilisez Instant . La classe Instant représente un moment sur la ligne de temps dans UTC avec une résolution de nanosecondes (jusqu'à neuf (9) chiffres d'une décimale fraction.)

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

utilisez la classe Duration pour une période de temps libre de la ligne de temps, avec résolution de jour-Heures-minutes-secondes-nanos.

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

pour une période de temps avec la résolution des années-mois-jours, utilisez la classe Period ".

Générer une chaîne de caractères est la norme ISO 8601 format pour les 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();

en Java 9 et plus tard, vous pouvez accéder aux différentes parties avec les méthodes toDaysPart , toHoursPart , et ainsi de suite.


à Propos de java.time

Le de java.temps framework est construit dans Java 8 et plus tard. Ces classes remplacent les anciennes héritées classes de date-heure 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, voir le Oracle Tutorial . Et rechercher le débordement de la pile pour de nombreux exemples et explications. La spécification est JSR 310 .

où obtenir le java.les classes de temps?

le projet ThreeTen-Extra étend java.temps avec des cours supplémentaires. Ce projet est un terrain d'expérimentation pour d'éventuelles futures additions à java.temps. Vous pouvez trouver ici quelques cours utiles tels que: Interval , YearWeek , YearQuarter , et plus .

5
répondu Basil Bourque 2017-05-23 10:31:13

Hmm, si j'obtiens ce que vous demandez, vous voulez savoir que si:

start = 1 Jan, 2001, 10:00:00.000 suis et

stop= Jan 6, 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 le 2 et le 31 janvier? Serait-ce la 29 jours? Ok, mais du 2 février au 2 Mars est de 28 (29) jours, mais serait listé comme 1 mois?

la durée en secondes ou éventuellement en jours est variable sans connaître le contexte puisque les mois et les années sont de longueurs différentes. La différence entre 2 dates devrait être en unités statiques, qui sont facilement calculables à partir de stop.gettime () - start.getTime () (qui est la différence en millisec)

3
répondu billjamesdev 2009-02-19 23:15:13

mis à part le grand JodaTime API que je do recommande, la meilleure alternative Java standard que vous pouvez avoir est le java.util.Calendar . Il est lourd de travailler avec elle (c'est un euphémisme .. regardez la seule ligne JodaTime exemples ici), mais vous pouvez calculer le temps écoulé. Clé importante est que vous devez utiliser le Calendar#add() dans une boucle pour obtenez la valeur écoulée pour des années, des mois et des jours pour prendre des jours bissextiles, des années et des siècles en compte. Vous ne devriez 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 écrire mon âge à partir de Maintenant =)

Oh, je devrais ajouter, vous pouvez" convertir " Date en Calendar en utilisant Calendar#setTime() .

3
répondu 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);
    }

retourne:

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
répondu udoline 2010-11-10 18:03:51

il ne sert à rien de créer un objet Date car tout ce que cela fait est wrap System.currentTimeMillis (). La fonction getTime () déballe simplement l'objet Date. Je vous suggère de simplement utiliser cette fonction pour obtenir une longue.

si vous n'avez besoin que d'une seconde précision, c'est parfait. Cependant, si vous voulez le système de précision sub-milliseconde.nanoTime() pour obtenir l'écoulement du temps.

0
répondu Peter Lawrey 2009-11-21 19:49:13

c'est une fonction complète que j'ai implémentée basée sur Sebastian Celis réponse. Et encore une fois, de son post - cela ne prend pas des choses comme années bissextiles ou commutateurs de l'heure d'été en compte. C'est le temps pur écoulé .

le résultat est adapté à mon besoin. Cela ne produit que trois sections importantes. Au lieu de retourner

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

il retourne juste le premier 3 bloc (voir plus d'essai à la fin de la 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 un exemple d'énoncé d'essai:

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
répondu Hossain Khan 2011-08-19 17:30:38

il s'agit d'une autre fonction similaire, elle n'apparaîtra PAS jours, Heures, minutes, etc. si elle n'est pas nécessaire changer ses littérales 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
répondu jcgonzalez 2012-11-09 07:12:02

il s'agit d'un problème et un algorithme doit être élaboré pour tenir compte des années bissextiles et du nombre exact de mois et de jours en plus des années. Il est intéressant de constater à quel point il est simple d'utiliser une seule unité de mesure. Par exemple, le nombre total de jours entre deux jours est correct comme revêtue de rappel nombre de jours après le nombre de mois et d'années est calculer dans disons deux décennies.

je travaille actuellement sur ceci pour le fournir à partir de mon implémentation PML, pour 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 le calcul exact des taux d'intérêt.

-1
répondu buda 2012-12-01 00:02:16