web-dev-qa-db-ger.com

Wie berechnet man "time ago" in Java?

In Ruby on Rails gibt es eine Funktion, mit der Sie jedes Datum übernehmen und ausdrucken können, wie es vor langer Zeit war.

Zum Beispiel:

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

Gibt es eine einfache Möglichkeit, dies in Java zu tun?

109
jts

Schauen Sie sich die Bibliothek PrettyTime an.

Es ist ganz einfach zu benutzen:

import org.ocpsoft.prettytime.PrettyTime;

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

Sie können auch ein Gebietsschema für internationalisierte Nachrichten übergeben:

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

Wie in den Kommentaren erwähnt, hat Android diese Funktionalität in die Android.text.format.DateUtils Klasse eingebaut.

156
ataylor

Haben Sie sich die TimeUnit Enum angesehen? Es kann für solche Dinge ziemlich nützlich sein

    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();
    }
68
Ben J
  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
         */
    }
}

more @ Eine Dauer in Millisekunden in ein für Menschen lesbares Format formatieren

42
RealHowTo

Ich nehme die Antworten von RealHowTo und Ben J und erstelle meine eigene 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));
}}

was wird das Folgende drucken

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
39

es gibt einen einfachen Weg, dies zu tun:

angenommen, Sie wollen die Zeit vor 20 Minuten:

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

das ist es..

9
Moria

Dies basiert auf der Antwort von RealHowTo. Wenn Sie es also mögen, geben Sie ihm/ihr auch etwas Liebe.

In dieser bereinigten Version können Sie den Zeitraum angeben, an dem Sie möglicherweise interessiert sind. 

Es behandelt auch das "und" Teil etwas anders. Wenn Sie Zeichenfolgen mit einem Trennzeichen verbinden, ist es oft einfacher, die komplizierte Logik zu überspringen und einfach das letzte Trennzeichen zu löschen, wenn Sie fertig sind.

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

Kleiner Code, um es zu drehen:

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

}

Welche wird folgendes ausgeben:

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 

Und falls es jemand braucht, wird hier eine Klasse verwendet, die jeden String wie den obigen zurück in Millisekunden konvertiert. Dies ist sehr nützlich, wenn Benutzer Zeitlimits für verschiedene Dinge in lesbarem Text angeben können.

9
David Blevins

Java.time

Verwendung des in Java 8 und höher integrierten Java.time - Frameworks.

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");
6
habsq

Wenn Sie nach einem einfachen "Heute", "Gestern" oder "x Tagen" suchen.

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";
}
5

Über integrierte Lösungen:

Java bietet keine integrierte Unterstützung für die Formatierung relativer Zeiten, auch nicht für Java-8 und das neue Paket Java.time. Wenn Sie nur Englisch und nichts anderes als dann brauchen, kann eine von Hand gefertigte Lösung akzeptabel sein - siehe die Antwort von @RealHowTo (obwohl es den großen Nachteil hat, die Zeitzone für die Übersetzung von Instant-Deltas in Ortszeit nicht zu berücksichtigen.) Einheiten!). Auf jeden Fall benötigen Sie eine externe Bibliothek, wenn Sie die komplexen Problemumgehungen im eigenen Land speziell für andere Gebietsschemas vermeiden möchten.

Im letzteren Fall empfehle ich, meine Bibliothek Time4J (oder Time4A unter Android) zu verwenden. Es bietet größte Flexibilität und die meiste I18n-Leistung. Die Klasse net.time4j.PrettyTime hat zu diesem Zweck sieben Methoden printRelativeTime...(...). Beispiel mit einer Testuhr als Zeitquelle:

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)

Ein weiteres Beispiel mit Java.time.Instant als Eingabe:

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

Diese Bibliothek unterstützt über ihre neueste Version (v4.17) 80 Sprachen sowie einige länderspezifische Sprachumgebungen (insbesondere für Spanisch, Englisch, Arabisch, Französisch). Die i18n-Daten basieren hauptsächlich auf der neueste CLDR-Version v29. Andere wichtige Gründe für die Verwendung dieser Bibliothek sind gute Unterstützung für Pluralregeln (die sich in anderen Sprachumgebungen oft von Englisch unterscheiden), abgekürzter Formatstil (zum Beispiel: "Vor 1 Sekunde" ) und ausdrucksstarke Möglichkeiten für unter Berücksichtigung von Zeitzonen. Time4J kennt sogar exotische Details wie Schaltsekunden bei der Berechnung der relativen Zeiten (nicht wirklich wichtig, bildet jedoch eine Nachricht, die sich auf den Erwartungshorizont bezieht). Das Kompatibilität mit Java-8 existiert aufgrund leicht verfügbarer Konvertierungsmethoden für Typen wie Java.time.Instant oder Java.time.Period.

Gibt es Nachteile? Nur zwei. 

  • Die Bibliothek ist nicht klein (auch wegen ihres großen i18n-Daten-Repositorys).
  • Die API ist nicht allgemein bekannt, daher sind noch keine Community-Kenntnisse und -Support verfügbar. Andernfalls ist die mitgelieferte Dokumentation ziemlich detailliert und umfassend.

(Kompakte) Alternativen:

Wenn Sie nach einer kleineren Lösung suchen, nicht so viele Funktionen benötigen und bereit sind, mögliche Qualitätsprobleme bei i18n-Daten zu tolerieren, dann gilt Folgendes:

  • Ich würde ocpsoft/PrettyTime empfehlen (Unterstützung für eigentlich 32 Sprachen (bald 34?), Die nur für die Arbeit mit Java.util.Date geeignet sind - siehe die Antwort von @ataylor). Der Industriestandard CLDR (von Unicode-Konsortium) mit seinem großen Community-Hintergrund ist leider keine Basis für die i18n-Daten, daher können weitere Verbesserungen oder Verbesserungen der Daten eine Weile dauern ...

  • Wenn Sie sich auf Android befinden, ist die Hilfsklasse Android.text.format.DateUtils eine schlanke, integrierte Alternative (siehe andere Kommentare und Antworten hier), mit dem Nachteil, dass sie jahrelang keine Unterstützung bietet. Und ich bin sicher, dass nur sehr wenige Leute den API-Stil dieser Hilfsklasse mögen.

  • Wenn Sie ein Fan von Joda-Time sind, können Sie sich die Klasse PeriodFormat anschauen (Unterstützung für 14 Sprachen in Version v2.9.4). Joda-Time ist sicherlich nicht kompakt auch, ich erwähne es hier nur der Vollständigkeit halber). Diese Bibliothek ist keine echte Antwort, da relative Zeiten überhaupt nicht unterstützt werden. Sie müssen mindestens das Literal "vor" anhängen (und alle unteren Einheiten manuell aus generierten Listenformaten entfernen - umständlich). Im Gegensatz zu Time4J oder Android-DateUtils werden Abkürzungen oder das automatische Umschalten von relativen Zeiten auf absolute Zeitdarstellungen nicht unterstützt. Wie PrettyTime ist es völlig abhängig von den unbestätigten Beiträgen privater Mitglieder der Java-Community zu seinen i18n-Daten.

5
Meno Hochschild

Ich habe ein einfaches Java timeago port des jquery-timeago plug-in erstellt, das das tut, was Sie wollen.

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

Das Paket joda-time hat den Begriff Perioden . Sie können mit Perioden und DateTimes arithmetisch arbeiten.

Aus den docs :

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

Sie können diese Funktion zum Berechnen der Zeit verwenden

 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) Hier ist time_ago in Mikrosekunden

3
Rajesh Tiwari

Falls Sie eine App für Android entwickeln, wird für diese Anforderungen die Dienstklasse DateUtils bereitgestellt. Sehen Sie sich die Utility-Methode DateUtils # getRelativeTimeSpanString () an.

Aus den Dokumenten für

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

Gibt eine Zeichenfolge zurück, die 'time' als Zeit relativ zu 'now' beschreibt. Zeitspannen in der Vergangenheit sind wie "vor 42 Minuten" formatiert. Zeitspannen in der Zukunft werden wie "In 42 Minuten" formatiert.

Sie übergeben Ihre timestamp als Zeit und System.currentTimeMillis() als jetzt. Mit minResolution können Sie die Mindestzeitspanne für den Bericht angeben.

Beispielsweise wird eine Zeit von 3 Sekunden in der Vergangenheit als "vor 0 Minuten" gemeldet, wenn MINUTE_IN_MILLIS eingestellt ist. Übergeben Sie eine von 0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, WEEK_IN_MILLIS usw.

3
Ravi Thapliyal

Dies ist ein besserer Code, wenn wir die Leistung berücksichtigen. Er reduziert die Anzahl der Berechnungen . Reason Minuten werden nur berechnet, wenn die Anzahl der Sekunden größer als 60 ist, und Stunden werden nur berechnet, wenn die Anzahl von Minuten sind größer als 60 und so weiter ...

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

}

}
2
Asad Mirza

Es ist nicht hübsch ... aber am nächsten fällt mir die Verwendung von Joda-Time (wie in diesem Beitrag beschrieben: Wie berechne ich jetzt die verstrichene Zeit mit Joda Time?

2
Justin Niessner

Für Android Genau wie Ravi gesagt hat, aber da viele Leute kopieren wollen, kopieren Sie einfach das Ding hier ist es.

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

Erklärung für Leute, die mehr Zeit haben

  1. Sie bekommen die Daten von irgendwoher. Zuerst müssen Sie herausfinden, welches Format vorliegt.

Ex. Ich bekomme die Daten von einem Server im Format Wed, 27 Jan 2016 09:32:35 GMT [das ist wahrscheinlich NICHT Ihr Fall]

das ist übersetzt in

SimpleDateFormat formatter = new SimpleDateFormat ("EEE, TTMM JJJJ HH: mm: ss Z");

woher weiß ich das? Lesen Sie hier die Dokumentation.

Nachdem ich es analysiert habe, bekomme ich ein Date. dieses Datum habe ich in den getRelativeTimeSpanString eingetragen (ohne weitere Parameter ist von mir in Ordnung, standardmäßig auf Minuten zu setzen)

Sie erhalten eine Ausnahme, wenn Sie den korrekten Parsing-String nicht gefunden haben. Etwas wie: Ausnahme bei Zeichen 5. Schauen Sie sich das Zeichen 5 an und korrigieren Sie Ihre ursprüngliche Zeichenfolge für die Analyse.. Möglicherweise erhalten Sie eine weitere Ausnahme. Wiederholen Sie diese Schritte, bis Sie die richtige Formel haben.

1
OWADVL

Basierend auf einer Reihe von Antworten habe ich für meinen Anwendungsfall Folgendes erstellt.

Verwendungsbeispiel:

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

Java.time

Das Answer by Habsq hat die richtige Idee, aber die falschen Methoden.

Verwenden Sie Period für eine Zeitspanne, die auf der Skala von Jahren-Monaten-Tagen nicht mit der Zeitachse verknüpft ist. Verwenden Sie Duration für Tage, die 24-Stunden-Zeitblöcke bedeuten, die nicht mit Kalender und Stunden-Minuten-Sekunden zusammenhängen. Das Mischen der beiden Skalen macht selten Sinn.

Duration

Beginnen Sie mit dem Abrufen des aktuellen Moments, wie in UTC gezeigt, mit der Klasse Instant .

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

Generieren Sie Text für Stunden, Minuten und Sekunden.

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

Dump zur Konsole.

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

Von: 2019-06-04T11: 53: 55.714965Z bis: 2019-06-04T20: 02: 03.714965Z

vor 8 Stunden

Vor 8 Minuten

Vor 8 Sekunden

Period

Beginnen Sie mit dem Abrufen des aktuellen Datums.

Eine Zeitzone ist für die Bestimmung eines Datums von entscheidender Bedeutung. Für jeden Moment variiert das Datum weltweit je nach Zone. Zum Beispiel ist ein paar Minuten nach Mitternacht in Paris Frankreich ein neuer Tag, während noch „gestern“ in Montréal Québec .

Wenn keine Zeitzone angegeben ist, wendet die JVM implizit ihre aktuelle Standardzeitzone an. Diese Standardeinstellung kann zu jedem Zeitpunkt ändern während der Laufzeit (!), So dass Ihre Ergebnisse variieren können. Geben Sie Ihre gewünschte/erwartete Zeitzone lieber explizit als Argument an. Wenn dies kritisch ist, bestätigen Sie die Zone mit Ihrem Benutzer.

Geben Sie Name der richtigen Zeitzone im Format _Continent/Region_ an, z. B. _America/Montreal_, _Africa/Casablanca_ oder _Pacific/Auckland_. Verwenden Sie niemals die Abkürzung mit 2 bis 4 Buchstaben wie EST oder IST, da es sich um nicht echte Zeitzonen handelt, die nicht standardisiert und nicht einmalig (!) Sind.

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

Erstellen Sie ein Datum vor acht Tagen, Monaten und Jahren.

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

Berechnen Sie die verstrichene Zeit.

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

Bauen Sie die Zeichenfolge der "Zeit vor" Stücke.

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

Dump zur Konsole.

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

Vom: 2010-09-27 bis: 2019-06-04

vor 8 Tagen

vor 8 Monaten

Vor 8 Jahren


Über Java.time

Das Java.time Framework ist in Java 8 und höher integriert. Diese Klassen ersetzen die lästigen alten Legacy Datum-Zeit-Klassen wie Java.util.Date , Calendar , & SimpleDateFormat =.

Weitere Informationen finden Sie im Oracle Tutorial . Suchen Sie in Stack Overflow nach vielen Beispielen und Erklärungen. Spezifikation ist JSR 31 .

Das Joda-Time -Projekt, das sich jetzt im Wartungsmodus befindet, rät zur Migration in die Java.time -Klassen.

Sie können Java.time - Objekte direkt mit Ihrer Datenbank austauschen. Verwenden Sie einen JDBC-Treiber , der JDBC 4.2 oder höher entspricht. Keine Notwendigkeit für Zeichenfolgen, keine Notwendigkeit für _Java.sql.*_ Klassen.

Woher bekomme ich die Java.time-Klassen?

Das Projekt ThreeTen-Extra erweitert Java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von Java.time. Hier finden Sie möglicherweise einige nützliche Klassen wie Interval , YearWeek , YearQuarter und more .

1
Basil Bourque

Nach langer Recherche habe ich das gefunden.

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

Hier ist meine Java-Implementierung davon

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

für mich geht das

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;
    } }
0
Rahul

Ich benutze die Instant, Date und DateTimeUtils. Die Daten (Datum), die in der Datenbank als Zeichenfolgentyp gespeichert und dann in Instant konvertiert werden.

    /*
    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;
    }
0
Ticherhaz

Dies ist das grundlegende Skript. es ist leicht zu improvisieren.
Ergebnis: (vor XXX Stunden) oder (vor XX Tagen/Gestern/Heute)

<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>
0
Dwipa Arantha

dafür habe ich Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years ago gemacht. In diesem Beispiel können Sie das Datum wie 2018-09-05T06:40:46.183Z dieses oder ein anderes wie unten beschrieben analysieren

addiere den Wert in 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>

Java-Code versuchen Sie unten

  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;
    }
0
Omi

Sie können Java-Bibliothek RelativeDateTimeFormatter verwenden. 

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"
0
mavesonzini