Comment calculer «il y a du temps» en Java?

127

Dans Ruby on Rails, il existe une fonctionnalité qui vous permet de prendre n'importe quelle date et d'imprimer "il y a longtemps".

Par exemple:

8 minutes ago
8 hours ago
8 days ago
8 months ago
8 years ago

Existe-t-il un moyen simple de le faire en Java?

jts
la source
1
Voir: stackoverflow.com/questions/11/how-do-i-calculate-relative-time C'est C #, mais je suis sûr que vous pouvez le convertir sans problème.
Brandon

Réponses:

177

Jetez un œil à la bibliothèque PrettyTime .

C'est assez simple à utiliser:

import org.ocpsoft.prettytime.PrettyTime;

PrettyTime p = new PrettyTime();
System.out.println(p.format(new Date()));
// prints "moments ago"

Vous pouvez également transmettre une locale pour les messages internationalisés:

PrettyTime p = new PrettyTime(new Locale("fr"));
System.out.println(p.format(new Date()));
// prints "à l'instant"

Comme indiqué dans les commentaires, Android a cette fonctionnalité intégrée à la android.text.format.DateUtilsclasse.

ataylor
la source
229
Si vous travaillez sur Android, vous pouvez utiliser ceci: android.text.format.DateUtils # getRelativeTimeSpanString ()
Somatik
Pouvez-vous s'il vous plaît ajouter une description supplémentaire à votre réponse, la réponse de lien seul n'est pas bonne pour le moment.
Ajay S
@Somatik si vous avez besoin de l'obtenir sur une plate-forme non Android, vous pouvez afficher cette classe sur AOSP.
greg7gkb
@ataylor comment cette utilisation dans Android ??
Hardik Parmar
getRelativeTimeSpanString n'est pas idéal pour toutes les situations et c'est pourquoi j'ai créé ma propre classe basée sur de nombreux exemples ici. Voir ma solution ci-dessous: stackoverflow.com/a/37042254/468360
Codeversé
67

Avez-vous envisagé l' énumération TimeUnit ? Cela peut être très utile pour ce genre de chose

    try {
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
        Date past = format.parse("01/10/2010");
        Date now = new Date();

        System.out.println(TimeUnit.MILLISECONDS.toMillis(now.getTime() - past.getTime()) + " milliseconds ago");
        System.out.println(TimeUnit.MILLISECONDS.toMinutes(now.getTime() - past.getTime()) + " minutes ago");
        System.out.println(TimeUnit.MILLISECONDS.toHours(now.getTime() - past.getTime()) + " hours ago");
        System.out.println(TimeUnit.MILLISECONDS.toDays(now.getTime() - past.getTime()) + " days ago");
    }
    catch (Exception j){
        j.printStackTrace();
    }
Ben J
la source
4
Je ne pense pas que ce soit une réponse complète puisque les unités de temps sont indépendantes. Par exemple, le temps en millisecondes est juste en minutes * 60 * 1000. Vous devez diminuer à partir de chaque unité de temps la prochaine unité de temps plus grande (après l'avoir convertie en unité de temps inférieure) afin de pouvoir l'utiliser il y a "un certain temps" " chaîne.
Nativ
@Benj - Est-ce bien? au-dessus de la solution? car une heure est au format 12 heures et une autre heure est au format 24 heures. Faites-moi part de vos commentaires sur ma requête. Merci d'avance.
Swift
c'est incorrect cependant ... chaque unité est indépendante l'une de l'autre comme déjà mentionné.
Jonathan Laliberte
1
Android le fait pour vous Si vous travaillez sur Android, vous pouvez utiliser ceci: android.text.format.DateUtils.getRelativeTimeSpanString (millisecondes)
Wajid Ali
50

Je prends les réponses de RealHowTo et Ben J et je crée ma propre version:

public class TimeAgo {
public static final List<Long> times = Arrays.asList(
        TimeUnit.DAYS.toMillis(365),
        TimeUnit.DAYS.toMillis(30),
        TimeUnit.DAYS.toMillis(1),
        TimeUnit.HOURS.toMillis(1),
        TimeUnit.MINUTES.toMillis(1),
        TimeUnit.SECONDS.toMillis(1) );
public static final List<String> timesString = Arrays.asList("year","month","day","hour","minute","second");

public static String toDuration(long duration) {

    StringBuffer res = new StringBuffer();
    for(int i=0;i< TimeAgo.times.size(); i++) {
        Long current = TimeAgo.times.get(i);
        long temp = duration/current;
        if(temp>0) {
            res.append(temp).append(" ").append( TimeAgo.timesString.get(i) ).append(temp != 1 ? "s" : "").append(" ago");
            break;
        }
    }
    if("".equals(res.toString()))
        return "0 seconds ago";
    else
        return res.toString();
}
public static void main(String args[]) {
    System.out.println(toDuration(123));
    System.out.println(toDuration(1230));
    System.out.println(toDuration(12300));
    System.out.println(toDuration(123000));
    System.out.println(toDuration(1230000));
    System.out.println(toDuration(12300000));
    System.out.println(toDuration(123000000));
    System.out.println(toDuration(1230000000));
    System.out.println(toDuration(12300000000L));
    System.out.println(toDuration(123000000000L));
}}

qui imprimera ce qui suit

0 second ago
1 second ago
12 seconds ago
2 minutes ago
20 minutes ago
3 hours ago
1 day ago
14 days ago
4 months ago
3 years ago
Riccardo Casatta
la source
Vraiment cool. Et il est vraiment facile d'ajouter d'autres unités de temps telles que semaine (s)
Piotr
1
celui-ci mérite plus de votes positifs. Tout d'abord, aucune bibliothèque n'est nécessaire. Il est toujours propre, élégant et facile à changer.
fangzhzh
petite faute de frappe: dans votre code, vous faites référence aux propriétés statiques "Lists" au lieu de "TimeAgo". Lists.times.get (i) devrait être TimeAgo.get (i) ... et ainsi de suite
Diogo Gomes
2
Petite suggestion: utiliser à la .append(temp != 1 ? "s" : "")place de .append(temp > 1 ? "s" : "")car 0 devrait également avoir le ssuffixe
berkus
1
@ShajeelAfzal oui, le paramètre de durée est en milliseconde mais c'est une différence entre les temps et non une valeur absolue. Ce que vous obtenez est l'heure qui s'est écoulée depuis le 1er janvier 1970, la date à laquelle l'horodatage unix a commencé
Riccardo Casatta
42
  public class TimeUtils {

      public final static long ONE_SECOND = 1000;
      public final static long SECONDS = 60;

      public final static long ONE_MINUTE = ONE_SECOND * 60;
      public final static long MINUTES = 60;

      public final static long ONE_HOUR = ONE_MINUTE * 60;
      public final static long HOURS = 24;

      public final static long ONE_DAY = ONE_HOUR * 24;

      private TimeUtils() {
      }

      /**
       * converts time (in milliseconds) to human-readable format
       *  "<w> days, <x> hours, <y> minutes and (z) seconds"
       */
      public static String millisToLongDHMS(long duration) {
        StringBuffer res = new StringBuffer();
        long temp = 0;
        if (duration >= ONE_SECOND) {
          temp = duration / ONE_DAY;
          if (temp > 0) {
            duration -= temp * ONE_DAY;
            res.append(temp).append(" day").append(temp > 1 ? "s" : "")
               .append(duration >= ONE_MINUTE ? ", " : "");
          }

          temp = duration / ONE_HOUR;
          if (temp > 0) {
            duration -= temp * ONE_HOUR;
            res.append(temp).append(" hour").append(temp > 1 ? "s" : "")
               .append(duration >= ONE_MINUTE ? ", " : "");
          }

          temp = duration / ONE_MINUTE;
          if (temp > 0) {
            duration -= temp * ONE_MINUTE;
            res.append(temp).append(" minute").append(temp > 1 ? "s" : "");
          }

          if (!res.toString().equals("") && duration >= ONE_SECOND) {
            res.append(" and ");
          }

          temp = duration / ONE_SECOND;
          if (temp > 0) {
            res.append(temp).append(" second").append(temp > 1 ? "s" : "");
          }
          return res.toString();
        } else {
          return "0 second";
        }
      }


      public static void main(String args[]) {
        System.out.println(millisToLongDHMS(123));
        System.out.println(millisToLongDHMS((5 * ONE_SECOND) + 123));
        System.out.println(millisToLongDHMS(ONE_DAY + ONE_HOUR));
        System.out.println(millisToLongDHMS(ONE_DAY + 2 * ONE_SECOND));
        System.out.println(millisToLongDHMS(ONE_DAY + ONE_HOUR + (2 * ONE_MINUTE)));
        System.out.println(millisToLongDHMS((4 * ONE_DAY) + (3 * ONE_HOUR)
            + (2 * ONE_MINUTE) + ONE_SECOND));
        System.out.println(millisToLongDHMS((5 * ONE_DAY) + (4 * ONE_HOUR)
            + ONE_MINUTE + (23 * ONE_SECOND) + 123));
        System.out.println(millisToLongDHMS(42 * ONE_DAY));
        /*
          output :
                0 second
                5 seconds
                1 day, 1 hour
                1 day and 2 seconds
                1 day, 1 hour, 2 minutes
                4 days, 3 hours, 2 minutes and 1 second
                5 days, 4 hours, 1 minute and 23 seconds
                42 days
         */
    }
}

plus @ Formatez une durée en millisecondes dans un format lisible par l'homme

RealHowTo
la source
J'ai fini par utiliser une version révisée de ceci. J'ai publié mes révisions pour vous.
David Blevins
5
David Blevins, plus d'exemples sur PrettyTime: stackoverflow.com/questions/3859288/... Big -1 pour réinventer la roue une fois de plus et ne pas recommander une bibliothèque tierce
:-p
9

Ceci est basé sur la réponse de RealHowTo, donc si vous l'aimez, donnez-lui aussi un peu d'amour.

Cette version nettoyée vous permet de spécifier la plage de temps qui pourrait vous intéresser.

Il gère également la partie "et" un peu différemment. Je trouve souvent que lors de la jonction de chaînes avec un délimiteur, il est souvent plus facile de sauter la logique compliquée et de simplement supprimer le dernier délimiteur lorsque vous avez terminé.

import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

public class TimeUtils {

    /**
     * Converts time to a human readable format within the specified range
     *
     * @param duration the time in milliseconds to be converted
     * @param max      the highest time unit of interest
     * @param min      the lowest time unit of interest
     */
    public static String formatMillis(long duration, TimeUnit max, TimeUnit min) {
        StringBuilder res = new StringBuilder();

        TimeUnit current = max;

        while (duration > 0) {
            long temp = current.convert(duration, MILLISECONDS);

            if (temp > 0) {
                duration -= current.toMillis(temp);
                res.append(temp).append(" ").append(current.name().toLowerCase());
                if (temp < 2) res.deleteCharAt(res.length() - 1);
                res.append(", ");
            }

            if (current == min) break;

            current = TimeUnit.values()[current.ordinal() - 1];
        }

        // clean up our formatting....

        // we never got a hit, the time is lower than we care about
        if (res.lastIndexOf(", ") < 0) return "0 " + min.name().toLowerCase();

        // yank trailing  ", "
        res.deleteCharAt(res.length() - 2);

        //  convert last ", " to " and"
        int i = res.lastIndexOf(", ");
        if (i > 0) {
            res.deleteCharAt(i);
            res.insert(i, " and");
        }

        return res.toString();
    }
}

Petit code pour lui donner un tourbillon:

import static java.util.concurrent.TimeUnit.*;

public class Main {

    public static void main(String args[]) {
        long[] durations = new long[]{
            123,
            SECONDS.toMillis(5) + 123,
            DAYS.toMillis(1) + HOURS.toMillis(1),
            DAYS.toMillis(1) + SECONDS.toMillis(2),
            DAYS.toMillis(1) + HOURS.toMillis(1) + MINUTES.toMillis(2),
            DAYS.toMillis(4) + HOURS.toMillis(3) + MINUTES.toMillis(2) + SECONDS.toMillis(1),
            DAYS.toMillis(5) + HOURS.toMillis(4) + MINUTES.toMillis(1) + SECONDS.toMillis(23) + 123,
            DAYS.toMillis(42)
        };

        for (long duration : durations) {
            System.out.println(TimeUtils.formatMillis(duration, DAYS, SECONDS));
        }

        System.out.println("\nAgain in only hours and minutes\n");

        for (long duration : durations) {
            System.out.println(TimeUtils.formatMillis(duration, HOURS, MINUTES));
        }
    }

}

Ce qui produira ce qui suit:

0 seconds
5 seconds 
1 day and 1 hour 
1 day and 2 seconds 
1 day, 1 hour and 2 minutes 
4 days, 3 hours, 2 minutes and 1 second 
5 days, 4 hours, 1 minute and 23 seconds 
42 days 

Again in only hours and minutes

0 minutes
0 minutes
25 hours 
24 hours 
25 hours and 2 minutes 
99 hours and 2 minutes 
124 hours and 1 minute 
1008 hours 

Et au cas où quelqu'un en aurait besoin, voici une classe qui convertira toute chaîne comme celle-ci en millisecondes . C'est assez utile pour permettre aux gens de spécifier des délais d'expiration de diverses choses dans un texte lisible.

David Blevins
la source
9

il y a un moyen simple de le faire:

disons que vous voulez l'heure d'il y a 20 minutes:

Long minutesAgo = new Long(20);
Date date = new Date();
Date dateIn_X_MinAgo = new Date (date.getTime() - minutesAgo*60*1000);

c'est tout..

Moria
la source
1
Dans la plupart des cas, vous voulez un affichage "intelligent", c'est à dire. au lieu d'il y a 5125 minutes, vous dites il y a x jours.
PhiLho
7

À propos des solutions intégrées:

Java n'a pas de support intégré pour le formatage des temps relatifs, pas plus que Java-8 et son nouveau package java.time . Si vous n'avez besoin que de l'anglais et de rien d'autre, alors et seulement, une solution faite à la main pourrait être acceptable - voir la réponse de @RealHowTo (bien qu'elle ait le fort inconvénient de ne pas prendre en compte le fuseau horaire pour la traduction des deltas instantanés en heure locale unités!). Quoi qu'il en soit, si vous souhaitez éviter des solutions de contournement complexes, en particulier pour d'autres paramètres régionaux, vous avez besoin d'une bibliothèque externe.

Dans ce dernier cas, je recommande d'utiliser ma bibliothèque Time4J (ou Time4A sur Android). Il offre une plus grande flexibilité et la plus grande puissance i18n . La classe net.time4j.PrettyTime a sept méthodes printRelativeTime...(...)à cet effet. Exemple utilisant une horloge de test comme source de temps:

TimeSource<?> clock = () -> PlainTimestamp.of(2015, 8, 1, 10, 24, 5).atUTC();
Moment moment = PlainTimestamp.of(2015, 8, 1, 17, 0).atUTC(); // our input
String durationInDays =
  PrettyTime.of(Locale.GERMAN).withReferenceClock(clock).printRelative(
    moment,
    Timezone.of(EUROPE.BERLIN),
    TimeUnit.DAYS); // controlling the precision
System.out.println(durationInDays); // heute (german word for today)

Un autre exemple utilisant java.time.Instantcomme entrée:

String relativeTime = 
  PrettyTime.of(Locale.ENGLISH)
    .printRelativeInStdTimezone(Moment.from(Instant.EPOCH));
System.out.println(relativeTime); // 45 years ago

Cette bibliothèque prend en charge via sa dernière version (v4.17) 80 langues et également certains paramètres régionaux spécifiques à un pays (en particulier pour l'espagnol, l'anglais, l'arabe, le français). Les données i18n sont principalement basées sur la dernière version CLDR v29 . D'autres raisons importantes pour l'utilisation de cette bibliothèque sont un bon support pour les règles du pluriel (qui sont souvent différentes de l'anglais dans d'autres paramètres régionaux), le style de format abrégé (par exemple: "1 sec ago") et les moyens expressifs de prendre en compte les fuseaux horaires . Time4J est même conscient de ces détails exotiques comme les secondes intercalaires dans les calculs de temps relatifs (pas vraiment important mais il forme un message lié à l'horizon d'attente). La compatibilité avec Java-8existe en raison de méthodes de conversion facilement disponibles pour des types tels que java.time.Instantou java.time.Period.

Y a-t-il des inconvénients? Seulement deux.

  • La bibliothèque n'est pas petite (également à cause de son grand référentiel de données i18n).
  • L'API n'est pas bien connue, donc les connaissances et l'assistance de la communauté ne sont pas encore disponibles, sinon la documentation fournie est assez détaillée et complète.

Alternatives (compactes):

Si vous recherchez une solution plus petite et n'avez pas besoin de autant de fonctionnalités et êtes prêt à tolérer d'éventuels problèmes de qualité liés aux données i18n, alors:

  • Je recommanderais ocpsoft / PrettyTime (support pour en fait 32 langues (bientôt 34?) Convient pour travailler avec java.util.Dateseulement - voir la réponse de @ataylor). Le CLDR standard de l'industrie (du consortium Unicode) avec son grand fond de communauté n'est malheureusement pas une base de données i18n, de sorte que d'autres améliorations ou améliorations des données peuvent prendre un certain temps ...

  • Si vous êtes sur Android, la classe d'assistance android.text.format.DateUtils est une alternative intégrée mince (voir les autres commentaires et réponses ici, avec l'inconvénient qu'elle n'a pas de support pendant des années et des mois. Et je suis sûr que seulement très peu de gens aiment le style API de cette classe d'assistance.

  • Si vous êtes fan de Joda-Time, vous pouvez regarder sa classe PeriodFormat (prise en charge de 14 langues dans la version v2.9.4, de l'autre côté: Joda-Time n'est sûrement pas compact aussi, donc je le mentionne ici juste pour exhaustivité). Cette bibliothèque n'est pas une vraie réponse car les temps relatifs ne sont pas du tout pris en charge. Vous devrez au moins ajouter le littéral "ago" (et en supprimant manuellement toutes les unités inférieures des formats de liste générés - gênant). Contrairement à Time4J ou Android-DateUtils, il n'a pas de support spécial pour les abréviations ou le passage automatique des temps relatifs aux représentations de temps absolu. Comme PrettyTime, il est totalement dépendant des contributions non confirmées de membres privés de la communauté Java à ses données i18n.

Meno Hochschild
la source
5

Si vous recherchez un simple "Aujourd'hui", "Hier" ou "il y a x jours".

private String getDaysAgo(Date date){
    long days = (new Date().getTime() - date.getTime()) / 86400000;

    if(days == 0) return "Today";
    else if(days == 1) return "Yesterday";
    else return days + " days ago";
}
Dumi Jay
la source
5

java.time

Utilisation du framework java.time intégré à Java 8 et versions ultérieures.

LocalDateTime t1 = LocalDateTime.of(2015, 1, 1, 0, 0, 0);
LocalDateTime t2 = LocalDateTime.now();
Period period = Period.between(t1.toLocalDate(), t2.toLocalDate());
Duration duration = Duration.between(t1, t2);

System.out.println("First January 2015 is " + period.getYears() + " years ago");
System.out.println("First January 2015 is " + period.getMonths() + " months ago");
System.out.println("First January 2015 is " + period.getDays() + " days ago");
System.out.println("First January 2015 is " + duration.toHours() + " hours ago");
System.out.println("First January 2015 is " + duration.toMinutes() + " minutes ago");
habsq
la source
1
Ces Durationméthodes rapportent l' ensemble durée en nombre total d'heures et un nombre total de minutes. Dans Java 8, la classe manquait étrangement de méthodes pour obtenir chaque partie des heures, des minutes et des secondes. Java 9 apporte ces méthodes, to…Part.
Basil Bourque
4

J'ai créé un simple port Java timeago du plug-in jquery-timeago qui fait ce que vous demandez.

TimeAgo time = new TimeAgo();
String minutes = time.timeAgo(System.currentTimeMillis() - (15*60*1000)); // returns "15 minutes ago"
Kevin Sawicki
la source
4

Si vous développez une application pour Android, elle fournit la classe utilitaire DateUtils pour toutes ces exigences. Jetez un œil à la méthode utilitaire DateUtils # getRelativeTimeSpanString () .

À partir de la documentation pour

CharSequence getRelativeTimeSpanString (long time, long now, long minResolution)

Renvoie une chaîne décrivant «l'heure» comme une heure relative à «maintenant». Les intervalles de temps dans le passé sont au format "Il y a 42 minutes". Les intervalles de temps dans le futur sont au format "En 42 minutes".

Vous passerez votre timestampcomme temps et System.currentTimeMillis()comme maintenant . Le minResolutionvous permet de spécifier la période minimale de rapport.

Par exemple, une heure dans le passé de 3 secondes sera signalée comme "il y a 0 minutes" si elle est définie sur MINUTE_IN_MILLIS. Passez l'un des 0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, WEEK_IN_MILLIS etc.

Ravi Thapliyal
la source
4

Vous pouvez utiliser cette fonction pour calculer le temps passé

 private String timeAgo(long time_ago) {
        long cur_time = (Calendar.getInstance().getTimeInMillis()) / 1000;
        long time_elapsed = cur_time - time_ago;
        long seconds = time_elapsed;
        int minutes = Math.round(time_elapsed / 60);
        int hours = Math.round(time_elapsed / 3600);
        int days = Math.round(time_elapsed / 86400);
        int weeks = Math.round(time_elapsed / 604800);
        int months = Math.round(time_elapsed / 2600640);
        int years = Math.round(time_elapsed / 31207680);

        // Seconds
        if (seconds <= 60) {
            return "just now";
        }
        //Minutes
        else if (minutes <= 60) {
            if (minutes == 1) {
                return "one minute ago";
            } else {
                return minutes + " minutes ago";
            }
        }
        //Hours
        else if (hours <= 24) {
            if (hours == 1) {
                return "an hour ago";
            } else {
                return hours + " hrs ago";
            }
        }
        //Days
        else if (days <= 7) {
            if (days == 1) {
                return "yesterday";
            } else {
                return days + " days ago";
            }
        }
        //Weeks
        else if (weeks <= 4.3) {
            if (weeks == 1) {
                return "a week ago";
            } else {
                return weeks + " weeks ago";
            }
        }
        //Months
        else if (months <= 12) {
            if (months == 1) {
                return "a month ago";
            } else {
                return months + " months ago";
            }
        }
        //Years
        else {
            if (years == 1) {
                return "one year ago";
            } else {
                return years + " years ago";
            }
        }
    }

1) Ici time_ago est en microseconde

Rajesh Tiwari
la source
4

Sur la base d'un tas de réponses ici, j'ai créé ce qui suit pour mon cas d'utilisation.

Exemple d'utilisation:

String relativeDate = String.valueOf(
                TimeUtils.getRelativeTime( 1000L * myTimeInMillis() ));

import java.util.Arrays;
import java.util.List;

import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * Utilities for dealing with dates and times
 */
public class TimeUtils {

    public static final List<Long> times = Arrays.asList(
        DAYS.toMillis(365),
        DAYS.toMillis(30),
        DAYS.toMillis(7),
        DAYS.toMillis(1),
        HOURS.toMillis(1),
        MINUTES.toMillis(1),
        SECONDS.toMillis(1)
    );

    public static final List<String> timesString = Arrays.asList(
        "yr", "mo", "wk", "day", "hr", "min", "sec"
    );

    /**
     * Get relative time ago for date
     *
     * NOTE:
     *  if (duration > WEEK_IN_MILLIS) getRelativeTimeSpanString prints the date.
     *
     * ALT:
     *  return getRelativeTimeSpanString(date, now, SECOND_IN_MILLIS, FORMAT_ABBREV_RELATIVE);
     *
     * @param date String.valueOf(TimeUtils.getRelativeTime(1000L * Date/Time in Millis)
     * @return relative time
     */
    public static CharSequence getRelativeTime(final long date) {
        return toDuration( Math.abs(System.currentTimeMillis() - date) );
    }

    private static String toDuration(long duration) {
        StringBuilder sb = new StringBuilder();
        for(int i=0;i< times.size(); i++) {
            Long current = times.get(i);
            long temp = duration / current;
            if (temp > 0) {
                sb.append(temp)
                  .append(" ")
                  .append(timesString.get(i))
                  .append(temp > 1 ? "s" : "")
                  .append(" ago");
                break;
            }
        }
        return sb.toString().isEmpty() ? "now" : sb.toString();
    }
}
Code inversé
la source
C'est très utile, merci beaucoup.
Haya Akkad
3

Le package joda-time , a la notion de périodes . Vous pouvez faire de l'arithmétique avec des périodes et des dates / heures.

À partir de la documentation :

public boolean isRentalOverdue(DateTime datetimeRented) {
  Period rentalPeriod = new  Period().withDays(2).withHours(12);
  return datetimeRented.plus(rentalPeriod).isBeforeNow();
}
Paul Rubel
la source
2

C'est un meilleur code si l'on considère les performances, il réduit le nombre de calculs. Raison Les minutes sont calculées uniquement si le nombre de secondes est supérieur à 60 et les heures ne sont calculées que si le nombre de minutes est supérieur à 60 et ainsi de suite ...

class timeAgo {

static String getTimeAgo(long time_ago) {
    time_ago=time_ago/1000;
    long cur_time = (Calendar.getInstance().getTimeInMillis())/1000 ;
    long time_elapsed = cur_time - time_ago;
    long seconds = time_elapsed;
   // Seconds
    if (seconds <= 60) {
        return "Just now";
    }
    //Minutes
    else{
        int minutes = Math.round(time_elapsed / 60);

        if (minutes <= 60) {
            if (minutes == 1) {
                return "a minute ago";
            } else {
                return minutes + " minutes ago";
            }
        }
        //Hours
        else {
            int hours = Math.round(time_elapsed / 3600);
            if (hours <= 24) {
                if (hours == 1) {
                    return "An hour ago";
                } else {
                    return hours + " hrs ago";
                }
            }
            //Days
            else {
                int days = Math.round(time_elapsed / 86400);
                if (days <= 7) {
                    if (days == 1) {
                        return "Yesterday";
                    } else {
                        return days + " days ago";
                    }
                }
                //Weeks
                else {
                    int weeks = Math.round(time_elapsed / 604800);
                    if (weeks <= 4.3) {
                        if (weeks == 1) {
                            return "A week ago";
                        } else {
                            return weeks + " weeks ago";
                        }
                    }
                    //Months
                    else {
                        int months = Math.round(time_elapsed / 2600640);
                        if (months <= 12) {
                            if (months == 1) {
                                return "A month ago";
                            } else {
                                return months + " months ago";
                            }
                        }
                        //Years
                        else {
                            int years = Math.round(time_elapsed / 31207680);
                            if (years == 1) {
                                return "One year ago";
                            } else {
                                return years + " years ago";
                            }
                        }
                    }
                }
            }
        }
    }

}

}
Asad Mirza
la source
1
Si vous travaillez sur Android, vous pouvez utiliser ceci: android.text.format.DateUtils.getRelativeTimeSpanString (millisecondes)
Wajid Ali
2

java.time

The Answer by Habsq a la bonne idée mais les mauvaises méthodes.

Pour un intervalle de temps indépendant de la chronologie à l'échelle des années-mois-jours, utilisez Period. Pour les jours signifiant des tranches de 24 heures sans rapport avec le calendrier et les heures-minutes-secondes, utilisez Duration. Mélanger les deux échelles n'a guère de sens.

Duration

Commencez par récupérer le moment actuel comme vu en UTC , en utilisant la Instantclasse.

Instant now = Instant.now();  // Capture the current moment as seen in UTC.
Instant then = now.minus( 8L , ChronoUnit.HOURS ).minus( 8L , ChronoUnit.MINUTES ).minus( 8L , ChronoUnit.SECONDS );
Duration d = Duration.between( then , now );

Générez du texte pendant des heures, des minutes et des secondes.

// Generate text by calling `to…Part` methods.
String output = d.toHoursPart() + " hours ago\n" + d.toMinutesPart() + " minutes ago\n" + d.toSecondsPart() + " seconds ago";

Dump dans la console.

System.out.println( "From: " + then + " to: " + now );
System.out.println( output );

Du: 2019-06-04T11: 53: 55.714965Z au: 2019-06-04T20: 02: 03.714965Z

il y a 8 heures

Il y a 8 minutes

Il y a 8 secondes

Period

Commencez par obtenir la date actuelle.

Un fuseau horaire est crucial pour déterminer une date. Pour un moment donné, la date varie dans le monde entier par zone. Par exemple, quelques minutes après minuit à Paris France est un nouveau jour alors qu'il est encore «hier» à Montréal Québec .

Si aucun fuseau horaire n'est spécifié, la machine virtuelle Java applique implicitement son fuseau horaire par défaut actuel. Cette valeur par défaut peut changer à tout moment pendant l'exécution (!), Donc vos résultats peuvent varier. Mieux vaut spécifier explicitement votre fuseau horaire souhaité / attendu comme argument. Si critique, confirmez la zone avec votre utilisateur.

Indiquez un nom de fuseau horaire approprié dans le format Continent/Region, tels que America/Montreal, Africa/Casablancaou Pacific/Auckland. N'utilisez jamais l'abréviation de 2 à 4 lettres telle que ESTou ISTcar ce ne sont pas de vrais fuseaux horaires, ni standardisés, ni même uniques (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

Recréez une date il y a huit jours, des mois et des années.

LocalDate then = today.minusYears( 8 ).minusMonths( 8 ).minusDays( 7 ); // Notice the 7 days, not 8, because of granularity of months. 

Calculez le temps écoulé.

Period p = Period.between( then , today );

Construisez la chaîne de pièces "il y a du temps".

String output = p.getDays() + " days ago\n" + p.getMonths() + " months ago\n" + p.getYears() + " years ago";

Dump dans la console.

System.out.println( "From: " + then + " to: " + today );
System.out.println( output );

Du: 2010-09-27 au: 2019-06-04

Il y a 8 jours

il y a 8 mois

il y a 8 ans


À propos de java.time

Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciens gênants hérités des classes date-heure tels que java.util.Date, Calendar, et SimpleDateFormat.

Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .

Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers les classes java.time .

Vous pouvez échanger des objets java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de java.sql.*classes.

Où obtenir les classes java.time?

Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour d'éventuels futurs ajouts à java.time. Vous trouverez peut - être des classes utiles ici, comme Interval, YearWeek, YearQuarteret plus .

Basil Bourque
la source
Merci beaucoup!
Ticherhaz
1

Après de longues recherches, j'ai trouvé ceci.

    public class GetTimeLapse {
    public static String getlongtoago(long createdAt) {
        DateFormat userDateFormat = new SimpleDateFormat("E MMM dd HH:mm:ss Z yyyy");
        DateFormat dateFormatNeeded = new SimpleDateFormat("MM/dd/yyyy HH:MM:SS");
        Date date = null;
        date = new Date(createdAt);
        String crdate1 = dateFormatNeeded.format(date);

        // Date Calculation
        DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        crdate1 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(date);

        // get current date time with Calendar()
        Calendar cal = Calendar.getInstance();
        String currenttime = dateFormat.format(cal.getTime());

        Date CreatedAt = null;
        Date current = null;
        try {
            CreatedAt = dateFormat.parse(crdate1);
            current = dateFormat.parse(currenttime);
        } catch (java.text.ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // Get msec from each, and subtract.
        long diff = current.getTime() - CreatedAt.getTime();
        long diffSeconds = diff / 1000;
        long diffMinutes = diff / (60 * 1000) % 60;
        long diffHours = diff / (60 * 60 * 1000) % 24;
        long diffDays = diff / (24 * 60 * 60 * 1000);

        String time = null;
        if (diffDays > 0) {
            if (diffDays == 1) {
                time = diffDays + "day ago ";
            } else {
                time = diffDays + "days ago ";
            }
        } else {
            if (diffHours > 0) {
                if (diffHours == 1) {
                    time = diffHours + "hr ago";
                } else {
                    time = diffHours + "hrs ago";
                }
            } else {
                if (diffMinutes > 0) {
                    if (diffMinutes == 1) {
                        time = diffMinutes + "min ago";
                    } else {
                        time = diffMinutes + "mins ago";
                    }
                } else {
                    if (diffSeconds > 0) {
                        time = diffSeconds + "secs ago";
                    }
                }

            }

        }
        return time;
    }
}
Hari krishna Andhra Pradesh
la source
1

Pour Android Exactement comme Ravi l'a dit, mais comme beaucoup de gens veulent simplement copier-coller la chose ici, c'est.

  try {
      SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
      Date dt = formatter.parse(date_from_server);
      CharSequence output = DateUtils.getRelativeTimeSpanString (dt.getTime());
      your_textview.setText(output.toString());
    } catch (Exception ex) {
      ex.printStackTrace();
      your_textview.setText("");
    }

Explication pour les personnes qui ont plus de temps

  1. Vous obtenez les données de quelque part. Vous devez d'abord déterminer son format.

Ex. Je reçois les données d'un serveur au format Wed, 27 Jan 2016 09:32:35 GMT [ce n'est probablement PAS votre cas]

cela se traduit par

Formateur SimpleDateFormat = nouveau SimpleDateFormat ("EEE, jj MMM aaaa HH: mm: ss Z");

comment je le sais? Lisez la documentation ici.

Ensuite, après l'avoir analysé, j'obtiens une date. cette date que j'ai mise dans le getRelativeTimeSpanString (sans aucun paramètre supplémentaire, c'est bien pour moi, être par défaut en minutes)

Vous obtiendrez une exception si vous n'avez pas trouvé la bonne chaîne d'analyse , quelque chose comme: exception au caractère 5 . Regardez le caractère 5 et corrigez votre chaîne d'analyse initiale. . Vous pourriez obtenir une autre exception, répétez ces étapes jusqu'à ce que vous ayez la formule correcte.

OWADVL
la source
1
private const val SECOND_MILLIS = 1
private const val MINUTE_MILLIS = 60 * SECOND_MILLIS
private const val HOUR_MILLIS = 60 * MINUTE_MILLIS
private const val DAY_MILLIS = 24 * HOUR_MILLIS

object TimeAgo {

fun timeAgo(time: Int): String {

    val now = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())
    if (time > now || time <= 0) {
        return "in the future"
    }

    val diff = now - time
    return when {
        diff < MINUTE_MILLIS -> "Just now"
        diff < 2 * MINUTE_MILLIS -> "a minute ago"
        diff < 60 * MINUTE_MILLIS -> "${diff / MINUTE_MILLIS} minutes ago"
        diff < 2 * HOUR_MILLIS -> "an hour ago"
        diff < 24 * HOUR_MILLIS -> "${diff / HOUR_MILLIS} hours ago"
        diff < 48 * HOUR_MILLIS -> "yesterday"
        else -> "${diff / DAY_MILLIS} days ago"
    }
}

}

Appel

val Chaîne = timeAgo (unixTimeStamp)

pour obtenir l'heure il y a à Kotlin

Dino Sunny
la source
0

Voici ma mise en œuvre Java de ce

    public static String relativeDate(Date date){
    Date now=new Date();
    if(date.before(now)){
    int days_passed=(int) TimeUnit.MILLISECONDS.toDays(now.getTime() - date.getTime());
    if(days_passed>1)return days_passed+" days ago";
    else{
        int hours_passed=(int) TimeUnit.MILLISECONDS.toHours(now.getTime() - date.getTime());
        if(hours_passed>1)return days_passed+" hours ago";
        else{
            int minutes_passed=(int) TimeUnit.MILLISECONDS.toMinutes(now.getTime() - date.getTime());
            if(minutes_passed>1)return minutes_passed+" minutes ago";
            else{
                int seconds_passed=(int) TimeUnit.MILLISECONDS.toSeconds(now.getTime() - date.getTime());
                return seconds_passed +" seconds ago";
            }
        }
    }

    }
    else
    {
        return new SimpleDateFormat("HH:mm:ss MM/dd/yyyy").format(date).toString();
    }
  }
Joey Pinto
la source
0

ça marche pour moi

public class TimeDifference {
    int years;
    int months;
    int days;
    int hours;
    int minutes;
    int seconds;
    String differenceString;

    public TimeDifference(@NonNull Date curdate, @NonNull Date olddate) {

        float diff = curdate.getTime() - olddate.getTime();
        if (diff >= 0) {
            int yearDiff = Math.round((diff / (AppConstant.aLong * AppConstant.aFloat)) >= 1 ? (diff / (AppConstant.aLong * AppConstant.aFloat)) : 0);
            if (yearDiff > 0) {
                years = yearDiff;
                setDifferenceString(years + (years == 1 ? " year" : " years") + " ago");
            } else {
                int monthDiff = Math.round((diff / AppConstant.aFloat) >= 1 ? (diff / AppConstant.aFloat) : 0);
                if (monthDiff > 0) {
                    if (monthDiff > AppConstant.ELEVEN) {
                        monthDiff = AppConstant.ELEVEN;
                    }
                    months = monthDiff;
                    setDifferenceString(months + (months == 1 ? " month" : " months") + " ago");
                } else {
                    int dayDiff = Math.round((diff / (AppConstant.bFloat)) >= 1 ? (diff / (AppConstant.bFloat)) : 0);
                    if (dayDiff > 0) {
                        days = dayDiff;
                        if (days == AppConstant.THIRTY) {
                            days = AppConstant.TWENTYNINE;
                        }
                        setDifferenceString(days + (days == 1 ? " day" : " days") + " ago");
                    } else {
                        int hourDiff = Math.round((diff / (AppConstant.cFloat)) >= 1 ? (diff / (AppConstant.cFloat)) : 0);
                        if (hourDiff > 0) {
                            hours = hourDiff;
                            setDifferenceString(hours + (hours == 1 ? " hour" : " hours") + " ago");
                        } else {
                            int minuteDiff = Math.round((diff / (AppConstant.dFloat)) >= 1 ? (diff / (AppConstant.dFloat)) : 0);
                            if (minuteDiff > 0) {
                                minutes = minuteDiff;
                                setDifferenceString(minutes + (minutes == 1 ? " minute" : " minutes") + " ago");
                            } else {
                                int secondDiff = Math.round((diff / (AppConstant.eFloat)) >= 1 ? (diff / (AppConstant.eFloat)) : 0);
                                if (secondDiff > 0) {
                                    seconds = secondDiff;
                                } else {
                                    seconds = 1;
                                }
                                setDifferenceString(seconds + (seconds == 1 ? " second" : " seconds") + " ago");
                            }
                        }
                    }

                }
            }

        } else {
            setDifferenceString("Just now");
        }

    }

    public String getDifferenceString() {
        return differenceString;
    }

    public void setDifferenceString(String differenceString) {
        this.differenceString = differenceString;
    }

    public int getYears() {
        return years;
    }

    public void setYears(int years) {
        this.years = years;
    }

    public int getMonths() {
        return months;
    }

    public void setMonths(int months) {
        this.months = months;
    }

    public int getDays() {
        return days;
    }

    public void setDays(int days) {
        this.days = days;
    }

    public int getHours() {
        return hours;
    }

    public void setHours(int hours) {
        this.hours = hours;
    }

    public int getMinutes() {
        return minutes;
    }

    public void setMinutes(int minutes) {
        this.minutes = minutes;
    }

    public int getSeconds() {
        return seconds;
    }

    public void setSeconds(int seconds) {
        this.seconds = seconds;
    } }
Rahul
la source
0

C'est le script très basique. c'est facile à improviser.
Résultat: (il y a XXX heures) ou (il y a XX jours / hier / aujourd'hui)

<span id='hourpost'></span>
,or
<span id='daypost'></span>

<script>
var postTime = new Date('2017/6/9 00:01'); 
var now = new Date();
var difference = now.getTime() - postTime.getTime();
var minutes = Math.round(difference/60000);
var hours = Math.round(minutes/60);
var days = Math.round(hours/24);

var result;
if (days < 1) {
result = "Today";
} else if (days < 2) {
result = "Yesterday";
} else {
result = days + " Days ago";
}

document.getElementById("hourpost").innerHTML = hours + "Hours Ago" ;
document.getElementById("daypost").innerHTML = result ;
</script>
Dwipa Arantha
la source
0

pour cela, j'ai fait Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years agodans cet exemple, vous pouvez analyser la date comme 2018-09-05T06:40:46.183Zcelle-ci ou tout autre comme ci-dessous

ajouter la valeur ci-dessous dans string.xml

  <string name="lbl_justnow">Just Now</string>
    <string name="lbl_seconds_ago">seconds ago</string>
    <string name="lbl_min_ago">min ago</string>
    <string name="lbl_mins_ago">mins ago</string>
    <string name="lbl_hr_ago">hr ago</string>
    <string name="lbl_hrs_ago">hrs ago</string>
    <string name="lbl_day_ago">day ago</string>
    <string name="lbl_days_ago">days ago</string>
    <string name="lbl_lstweek_ago">last week</string>
    <string name="lbl_week_ago">weeks ago</string>
    <string name="lbl_onemonth_ago">1 month ago</string>
    <string name="lbl_month_ago">months ago</string>
    <string name="lbl_oneyear_ago" >last year</string>
    <string name="lbl_year_ago" >years ago</string>

code java essayez ci-dessous

  public String getFormatDate(String postTime1) {
        Calendar cal=Calendar.getInstance();
        Date now=cal.getTime();
        String disTime="";
        try {
            Date postTime;
            //2018-09-05T06:40:46.183Z
            postTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(postTime1);

            long diff=(now.getTime()-postTime.getTime()+18000)/1000;

            //for months
            Calendar calObj = Calendar.getInstance();
            calObj.setTime(postTime);
            int m=calObj.get(Calendar.MONTH);
            calObj.setTime(now);

            SimpleDateFormat monthFormatter = new SimpleDateFormat("MM"); // output month

            int mNow = Integer.parseInt(monthFormatter.format(postTime));

            diff = diff-19800;

            if(diff<15) { //below 15 sec

                disTime = getResources().getString(R.string.lbl_justnow);
            } else if(diff<60) {

                //below 1 min
                disTime= diff+" "+getResources().getString(R.string.lbl_seconds_ago);
            } else if(diff<3600) {//below 1 hr

                // convert min
                long temp=diff/60;

                if(temp==1) {
                    disTime= temp + " " +getResources().getString(R.string.lbl_min_ago);
                } else {
                    disTime = temp  + " " +getResources().getString(R.string.lbl_mins_ago);
                }
            } else if(diff<(24*3600)) {// below 1 day

                // convert hr
                long temp= diff/3600;
                System.out.println("hey temp3:"+temp);
                if(temp==1) {
                    disTime = temp  + " " +getResources().getString(R.string.lbl_hr_ago);
                } else {
                    disTime = temp + " " +getResources().getString(R.string.lbl_hrs_ago);
                }
            } else if(diff<(24*3600*7)) {// below week

                // convert days
                long temp=diff/(3600*24);
                if (temp==1) {
                    //  disTime = "\nyesterday";
                    disTime = temp + " " +getResources().getString(R.string.lbl_day_ago);
                } else {
                    disTime = temp + " " +getResources().getString(R.string.lbl_days_ago);
                }
            } else if(diff<((24*3600*28))) {// below month

                // convert week
                long temp=diff/(3600*24*7);
                if (temp <= 4) {

                    if (temp < 1) {
                        disTime = getResources().getString(R.string.lbl_lstweek_ago);
                    }else{
                        disTime = temp + " " + getResources().getString(R.string.lbl_week_ago);
                    }

                } else {
                    int diffMonth = mNow - m;
                    Log.e("count : ", String.valueOf(diffMonth));
                    disTime = diffMonth + " " + getResources().getString(R.string.lbl_month_ago);
                }
            }else if(diff<((24*3600*365))) {// below year

                // convert month
                long temp=diff/(3600*24*30);

                System.out.println("hey temp2:"+temp);
                if (temp <= 12) {

                    if (temp == 1) {
                        disTime = getResources().getString(R.string.lbl_onemonth_ago);
                    }else{
                        disTime = temp + " " + getResources().getString(R.string.lbl_month_ago);
                    }
                }

            }else if(diff>((24*3600*365))) { // above year

                // convert year
                long temp=diff/(3600*24*30*12);

                System.out.println("hey temp8:"+temp);

                if (temp == 1) {
                    disTime = getResources().getString(R.string.lbl_oneyear_ago);
                }else{
                    disTime = temp + " " + getResources().getString(R.string.lbl_year_ago);
                }
            }

        } catch(Exception e) {
            e.printStackTrace();
        }

        return disTime;
    }
OmiK
la source
Si vous travaillez sur Android, vous pouvez utiliser ceci: android.text.format.DateUtils.getRelativeTimeSpanString (millisecondes)
Wajid Ali
0

Vous pouvez utiliser la bibliothèque Java RelativeDateTimeFormatter , elle fait exactement cela:

RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance();
 fmt.format(1, Direction.NEXT, RelativeUnit.DAYS); // "in 1 day"
 fmt.format(3, Direction.NEXT, RelativeUnit.DAYS); // "in 3 days"
 fmt.format(3.2, Direction.LAST, RelativeUnit.YEARS); // "3.2 years ago"

 fmt.format(Direction.LAST, AbsoluteUnit.SUNDAY); // "last Sunday"
 fmt.format(Direction.THIS, AbsoluteUnit.SUNDAY); // "this Sunday"
 fmt.format(Direction.NEXT, AbsoluteUnit.SUNDAY); // "next Sunday"
 fmt.format(Direction.PLAIN, AbsoluteUnit.SUNDAY); // "Sunday"

 fmt.format(Direction.LAST, AbsoluteUnit.DAY); // "yesterday"
 fmt.format(Direction.THIS, AbsoluteUnit.DAY); // "today"
 fmt.format(Direction.NEXT, AbsoluteUnit.DAY); // "tomorrow"

 fmt.format(Direction.PLAIN, AbsoluteUnit.NOW); // "now"
mavesonzini
la source
1
C'est une bibliothèque Android, pas une bibliothèque Java.
Madbreaks
0

J'utilise Instant, Date et DateTimeUtils. Les données (date) qui sont stockées dans la base de données dans le type de chaîne, puis converties en Instant.

    /*
    This method is to display ago.
    Example: 3 minutes ago.
    I already implement the latest which is including the Instant.
    Convert from String to Instant and then parse to Date.
     */
    public String convertTimeToAgo(String dataDate) {
    //Initialize
    String conversionTime = null;
    String suffix = "Yang Lalu";
    Date pastTime;
    //Parse from String (which is stored as Instant.now().toString()
    //And then convert to become Date
    Instant instant = Instant.parse(dataDate);
    pastTime = DateTimeUtils.toDate(instant);

    //Today date
    Date nowTime = new Date();

    long dateDiff = nowTime.getTime() - pastTime.getTime();
    long second = TimeUnit.MILLISECONDS.toSeconds(dateDiff);
    long minute = TimeUnit.MILLISECONDS.toMinutes(dateDiff);
    long hour = TimeUnit.MILLISECONDS.toHours(dateDiff);
    long day = TimeUnit.MILLISECONDS.toDays(dateDiff);

    if (second < 60) {
        conversionTime = second + " Saat " + suffix;
    } else if (minute < 60) {
        conversionTime = minute + " Minit " + suffix;
    } else if (hour < 24) {
        conversionTime = hour + " Jam " + suffix;
    } else if (day >= 7) {
        if (day > 30) {
            conversionTime = (day / 30) + " Bulan " + suffix;
        } else if (day > 360) {
            conversionTime = (day / 360) + " Tahun " + suffix;
        } else {
            conversionTime = (day / 7) + " Minggu " + suffix;
        }
    } else if (day < 7) {
        conversionTime = day + " Hari " + suffix;
    }
    return conversionTime;
    }
Ticherhaz
la source
1
Vous utilisez de terribles anciennes classes date-heure qui ont été supplantées il y a des années par les classes java.time .
Basil Bourque
@BasilBourque Je ne trouve toujours pas la dernière façon de le faire.
Ticherhaz le
@BasilBourque J'ai ajouté du code pour que je le comprenne. github.com/ticherhaz/tarikhmasa
Ticherhaz
0

Les solutions suivantes sont toutes en Java pur:

Option 1: pas d'arrondi et seulement le plus grand conteneur de temps

La fonction suivante n'affichera que le plus grand conteneur de temps, par exemple, si le vrai temps écoulé est "1 month 14 days ago", cette fonction s'affichera uniquement "1 month ago". Cette fonction sera également toujours arrondie vers le bas, donc un temps équivalent à "50 days ago"s'affichera comme"1 month"

public String formatTimeAgo(long millis) {
        String[] ids = new String[]{"second","minute","hour","day","month","year"};

        long seconds = millis / 1000;
        long minutes = seconds / 60;
        long hours = minutes / 60;
        long days = hours / 24;
        long months = days / 30;
        long years = months / 12;

        ArrayList<Long> times = new ArrayList<>(Arrays.asList(years, months, days, hours, minutes, seconds));

        for(int i = 0; i < times.size(); i++) {
            if(times.get(i) != 0) {
                long value = times.get(i).intValue();

                return value + " " + ids[ids.length - 1 - i] + (value == 1 ? "" : "s") + " ago";
            }
        }

        return "0 seconds ago";
    }

Option 2: avec arrondi

Enveloppez simplement le conteneur de temps que vous souhaitez arrondir avec une instruction Math.round (...), donc si vous voulez arrondir 50 daysà 2 months, modifiez-le long months = days / 30enlong months = Math.round(days / 30.0)

wdavies973
la source
1
L'utilisation Durationavec ses to…Partméthodes serait beaucoup plus facile, comme indiqué dans ma réponse .
Basil Bourque
0

Voici mon cas de test, j'espère que cela vous aidera:

    val currentCalendar = Calendar.getInstance()
    currentCalendar.set(2019, 6, 2, 5, 31, 0)

    val targetCalendar = Calendar.getInstance()
    targetCalendar.set(2019, 6, 2, 5, 30, 0)

    val diffTs = currentCalendar.timeInMillis - targetCalendar.timeInMillis
    val diffMins = TimeUnit.MILLISECONDS.toMinutes(diffTs)
    val diffHours = TimeUnit.MILLISECONDS.toHours(diffTs)
    val diffDays = TimeUnit.MILLISECONDS.toDays(diffTs)
    val diffWeeks = TimeUnit.MILLISECONDS.toDays(diffTs) / 7
    val diffMonths = TimeUnit.MILLISECONDS.toDays(diffTs) / 30
    val diffYears = TimeUnit.MILLISECONDS.toDays(diffTs) / 365

    val newTs = when {
        diffYears >= 1 -> "Years $diffYears"
        diffMonths >= 1 -> "Months $diffMonths"
        diffWeeks >= 1 -> "Weeks $diffWeeks"
        diffDays >= 1 -> "Days $diffDays"
        diffHours >= 1 -> "Hours $diffHours"
        diffMins >= 1 -> "Mins $diffMins"
        else -> "now"
    }
David_Wang
la source
1
La Calendarclasse terrible a été supplantée il y a des années par les classes java.time modernes avec l'adoption de JSR 310 . Mauvais conseils en 2019.
Basil Bourque
Vous devez avoir voulu dire var, non val.
Basil Bourque
0

La fonction getrelativeDateTime vous donnera la date et l'heure comme vous le voyez dans la notification Whatsapp.
Pour obtenir la date et l'heure relatives futures, ajoutez des conditions. Ceci est créé spécifiquement pour obtenir la date et l'heure comme la notification Whatsapp.

private static String getRelativeDateTime(long date) {
    SimpleDateFormat DateFormat = new SimpleDateFormat("MMM dd, yyyy", Locale.getDefault());
    SimpleDateFormat TimeFormat = new SimpleDateFormat(" hh:mm a", Locale.getDefault());
    long now = Calendar.getInstance().getTimeInMillis();
    long startOfDay = StartOfDay(Calendar.getInstance().getTime());
    String Day = "";
    String Time = "";
    long millSecInADay = 86400000;
    long oneHour = millSecInADay / 24;
    long differenceFromNow = now - date;

    if (date > startOfDay) {
        if (differenceFromNow < (oneHour)) {
            int minute = (int) (differenceFromNow / (60000));
            if (minute == 0) {
                int sec = (int) differenceFromNow / 1000;
                if (sec == 0) {
                    Time = "Just Now";
                } else if (sec == 1) {
                    Time = sec + " second ago";
                } else {
                    Time = sec + " seconds ago";
                }
            } else if (minute == 1) {
                Time = minute + " minute ago";
            } else if (minute < 60) {
                Time = minute + " minutes ago";
            }
        } else {
            Day = "Today, ";
        }
    } else if (date > (startOfDay - millSecInADay)) {
        Day = "Yesterday, ";
    } else if (date > (startOfDay - millSecInADay * 7)) {
        int days = (int) (differenceFromNow / millSecInADay);
        Day = days + " Days ago, ";
    } else {
        Day = DateFormat.format(date);
    }
    if (Time.isEmpty()) {
        Time = TimeFormat.format(date);
    }
    return Day + Time;
}

public static long StartOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTimeInMillis();
}
Sumit Singh
la source
Merci de vouloir contribuer. Ce n'est pas exactement ce qui a été demandé, mais peut-être que quelqu'un peut l'utiliser. Ni que quelqu'un ni personne d'autre ne devrait vouloir utiliser SimpleDateFormatet Calendar, cependant. Ces classes sont mal conçues et dépassées depuis longtemps. Lisez plutôt les réponses qui utilisent java.time, l'API de date et d'heure Java moderne.
Ole VV
0

Pour le manque de simplicité et de réponse mise à jour, suit la version plus récente de Java 8 et au-delà

import java.time.*;
import java.time.temporal.*;

public class Time {
    public static void main(String[] args) {

        System.out.println(LocalTime.now().minus(8, ChronoUnit.MINUTES));
        System.out.println(LocalTime.now().minus(8, ChronoUnit.HOURS));
        System.out.println(LocalDateTime.now().minus(8, ChronoUnit.DAYS));
        System.out.println(LocalDateTime.now().minus(8, ChronoUnit.MONTHS));
    }
}

Il s'agit de la version qui utilise l'API Java Time qui tente de résoudre les problèmes du passé pour gérer la date et l'heure.

Javadoc

version 8 https://docs.oracle.com/javase/8/docs/api/index.html?java/time/package-summary.html

version 11 https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html

Tutoriel W3Schools - https://www.w3schools.com/java/java_date.asp

Article DZone - https://dzone.com/articles/java-8-date-and-time

Brunocrt
la source