Wie berechnet man "Zeit vor" in Java?


127

In Ruby on Rails gibt es eine Funktion, mit der Sie ein beliebiges Datum auswählen und ausdrucken können, wie lange es her ist.

Beispielsweise:

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?


1
Siehe: stackoverflow.com/questions/11/how-do-i-calculate-relative-time Es ist C #, aber ich bin sicher, dass Sie es mit wenig Aufwand konvertieren können.
Brandon

Antworten:


177

Schauen Sie sich die PrettyTime- Bibliothek an.

Es ist ganz einfach zu bedienen:

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.DateUtilsKlasse integriert.


229
Wenn Sie an Android arbeiten, können Sie dies verwenden: android.text.format.DateUtils # getRelativeTimeSpanString ()
Somatik

Können Sie Ihrer Antwort bitte eine weitere Beschreibung hinzufügen? Die Antwort nur über Links ist vorerst nicht gut.
Ajay S

@Somatik Wenn Sie dies auf einer Nicht-Android-Plattform benötigen, können Sie diese Klasse auf AOSP anzeigen.
Greg7gkb

@ataylor wie diese Verwendung in Android?
Hardik Parmar

getRelativeTimeSpanString ist nicht für alle Situationen ideal. Deshalb habe ich anhand vieler Beispiele hier eine eigene Klasse erstellt. Siehe meine Lösung unten: stackoverflow.com/a/37042254/468360
Codeversed

67

Haben Sie die TimeUnit- Aufzählung berücksichtigt ? 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();
    }

4
Ich denke nicht, dass dies eine vollständige Antwort ist, da die Zeiteinheiten unabhängig sind. Beispiel: Die Millisekundenzeit beträgt nur Minuten * 60 * 1000. Sie müssen von jeder Zeiteinheit die nächstgrößere Zeiteinheit (nach der Konvertierung in die niedrigere Zeiteinheit) verringern, um sie in einer "Zeit vor" verwenden zu können "Zeichenfolge.
Nativ

@ Benj - Stimmt es richtig? obige Lösung? weil eine Zeit im 12-Stunden-Format und eine andere Zeit im 24-Stunden-Format ist. Lassen Sie mich Ihr Feedback zu meiner Anfrage wissen. Danke im Voraus.
Swift

Dies ist jedoch falsch ... jede Einheit ist wie bereits erwähnt voneinander unabhängig.
Jonathan Laliberte

1
Android macht es für Sie Wenn Sie an Android arbeiten, können Sie dies verwenden: android.text.format.DateUtils.getRelativeTimeSpanString (Millisekunden)
Wajid Ali

50

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

das 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

Wirklich cool. Und es ist wirklich einfach, andere Zeiteinheiten wie Woche (n) hinzuzufügen
Piotr

1
Dieser verdient mehr positive Stimmen. Zunächst wird keine Bibliothek benötigt. Es ist immer noch sauber, elegant und leicht zu wechseln.
Fangzhzh

kleiner Tippfehler: In Ihrem Code verweisen Sie auf die statischen Eigenschaften "Listen" anstelle von "TimeAgo". Lists.times.get (i) sollte TimeAgo.get (i) sein ... und so weiter
Diogo Gomes

2
Kleiner Vorschlag: Verwenden Sie .append(temp != 1 ? "s" : "")anstelle von, .append(temp > 1 ? "s" : "")weil 0 auch sSuffix haben sollte
Berkus

1
@ShajeelAfzal Ja, der Parameter dauer ist in Millisekunden, aber es ist ein Unterschied zwischen den Zeiten, kein absoluter Wert. Was Sie bekommen, ist die Zeit, die seit dem 1. Januar 1970 vergangen ist, dem Datum, an dem der Unix-Zeitstempel begann
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
         */
    }
}

more @ Formatiert eine Dauer in Millisekunden in ein für Menschen lesbares Format


Am Ende habe ich eine überarbeitete Version davon verwendet. Hat meine Überarbeitungen für Sie gepostet.
David Blevins

5
David Blevins, weitere Beispiele zu PrettyTime: stackoverflow.com/questions/3859288/… Big -1 für die erneute Neuerfindung des Rads und die Nichtempfehlung einer Bibliothek eines Drittanbieters :-p
zakmck

9

Dies basiert auf der Antwort von RealHowTo. Wenn es Ihnen gefällt, geben Sie ihm / ihr auch etwas Liebe.

Mit dieser bereinigten Version können Sie den Zeitraum angeben, an dem Sie interessiert sein könnten.

Es behandelt auch das "und" Teil etwas anders. Ich finde oft, wenn ich Strings mit einem Trennzeichen verbinde, 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 verwirbeln:

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

}

Welches wird das folgende 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 jemand es jemals braucht, hier ist eine Klasse, die jede Zeichenfolge wie die oben genannte wieder in Millisekunden konvertiert . Es ist ziemlich nützlich, damit Benutzer Zeitüberschreitungen für verschiedene Dinge in lesbarem Text festlegen können.


9

Es gibt einen einfachen Weg, dies zu tun:

Nehmen wir an, Sie möchten 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..


1
In den meisten Fällen möchten Sie ein "intelligentes" Display, dh. statt vor 5125 Minuten sagst du es vor x Tagen.
PhiLho

7

Über integrierte Lösungen:

Java bietet keine integrierte Unterstützung für die Formatierung relativer Zeiten, auch nicht Java-8 und sein neues Paket java.time. Wenn Sie nur Englisch und nichts anderes benötigen, ist eine handgefertigte Lösung möglicherweise akzeptabel - siehe die Antwort von @RealHowTo (obwohl es den großen Nachteil hat, die Zeitzone für die Übersetzung von Sofortdeltas in die Ortszeit nicht zu berücksichtigen Einheiten!). Wenn Sie komplexe Problemumgehungen aus eigenem Anbau vermeiden möchten, insbesondere für andere Ländereinstellungen, benötigen Sie eine externe Bibliothek.

Im letzteren Fall empfehle ich, meine Bibliothek Time4J (oder Time4A unter Android) zu verwenden. Es bietet größte Flexibilität und höchste i18n-Leistung . Die Klasse net.time4j.PrettyTime verfügt printRelativeTime...(...)zu diesem Zweck über sieben Methoden . 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 java.time.Instantals 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 und einige länderspezifische Gebietsschemas (insbesondere für Spanisch, Englisch, Arabisch, Französisch). Die i18n-Daten basieren hauptsächlich auf der neuesten CLDR-Version v29 . Andere wichtige Gründe für die Verwendung dieser Bibliothek sind die gute Unterstützung von Pluralregeln (die sich in anderen Regionen häufig von Englisch unterscheiden), der abgekürzte Formatstil (z. B. "vor 1 Sekunde") und ausdrucksstarke Möglichkeiten zur Berücksichtigung von Zeitzonen . Time4J ist auch bewusst so exotische Details wie Schaltsekunden in den Berechnungen der relativen Zeiten (nicht wirklich wichtig , aber es bildet eine Nachricht an den Erwartungshorizont bezogen). Die Kompatibilität mit Java-8existiert aufgrund leicht verfügbarer Konvertierungsmethoden für Typen wie java.time.Instantoder java.time.Period.

Gibt es irgendwelche Nachteile? Nur zwei.

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

(Kompakte) Alternativen:

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

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

  • Wenn Sie mit Android arbeiten, ist die Hilfsklasse android.text.format.DateUtils eine schlanke integrierte Alternative (siehe andere Kommentare und Antworten hier, mit dem Nachteil, dass sie jahrelang und monatelang nicht unterstützt wird. Und das bin ich mir sicher Sehr wenige Leute mögen den API-Stil dieser Hilfsklasse.

  • Wenn Sie ein Fan von Joda-Time sind , können Sie sich die Klasse PeriodFormat ansehen (Unterstützung für 14 Sprachen in Release v2.9.4 auf der anderen Seite: Joda-Time ist sicherlich auch nicht kompakt, deshalb erwähne ich es hier nur für Vollständigkeit). 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 den 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 speziell unterstützt. Wie PrettyTime ist es völlig abhängig von den unbestätigten Beiträgen privater Mitglieder der Java-Community zu ihren i18n-Daten.


5

Wenn Sie nach einem einfachen "Heute", "Gestern" oder "Vor 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

java.time

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

1
Diese DurationMethoden geben die gesamte Dauer als Gesamtzahl der Stunden und als Gesamtzahl der Minuten an. In Java 8 fehlten der Klasse seltsamerweise Methoden, um jeden Teil von Stunden, Minuten und Sekunden abzurufen. Java 9 bringt diese Methoden , to…Part.
Basil Bourque


4

Wenn Sie eine App für Android entwickeln, bietet sie die Dienstprogrammklasse DateUtils für alle diese Anforderungen. Schauen Sie sich die Dienstprogrammmethode DateUtils # getRelativeTimeSpanString () an .

Aus den Dokumenten für

CharSequence getRelativeTimeSpanString (lange Zeit, lange jetzt, lange minResolution)

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

Sie werden Ihre werden vorbei timestampwie Zeit und System.currentTimeMillis()wie jetzt . Mit minResolutionkönnen Sie die Mindestzeitspanne für die Berichterstellung festlegen.

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


4

Mit dieser Funktion können Sie die Zeit vor berechnen

 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


4

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

Anwendungsbeispiel:

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

Es ist sehr nützlich, vielen Dank.
Haya Akkad

3

Das Joda-Time- Paket hat den Begriff Perioden . Sie können mit Perioden und Datums- und Uhrzeitangaben rechnen.

Aus den Dokumenten :

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


2

Dies ist ein besserer Code, wenn wir die Leistung berücksichtigen. Er reduziert die Anzahl der Berechnungen. Grund Minuten werden nur berechnet, wenn die Anzahl der Sekunden größer als 60 ist, und Stunden werden nur berechnet, wenn die Anzahl der Minuten größer als 60 ist 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";
                            }
                        }
                    }
                }
            }
        }
    }

}

}

1
Wenn Sie an Android arbeiten, können Sie dies verwenden: android.text.format.DateUtils.getRelativeTimeSpanString (Millisekunden)
Wajid Ali

2

java.time

Die Antwort von Habsq hat die richtige Idee, aber die falschen Methoden.

Verwenden Sie für einen Zeitraum, der nicht an die Zeitachse in der Größenordnung von Jahren, Monaten und Tagen gebunden ist Period. Verwenden Sie für Tage, die 24-Stunden-Zeitabschnitte ohne Bezug zum Kalender und Stunden-Minuten-Sekunden bedeuten Duration. Das Mischen der beiden Skalen macht selten Sinn.

Duration

Beginnen Sie mit dem Abrufen des aktuellen Moments in UTC mithilfe der InstantKlasse.

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 entscheidend für die Bestimmung eines Datums. 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 es noch „gestern“ in Montréal Québec ist .

Wenn keine Zeitzone angegeben ist, wendet die JVM implizit ihre aktuelle Standardzeitzone an. Diese Standardeinstellung kann sich jederzeit zur Laufzeit (!) Ändern , sodass Ihre Ergebnisse variieren können. Geben Sie Ihre gewünschte / erwartete Zeitzone besser explizit als Argument an. Wenn dies kritisch ist, bestätigen Sie die Zone mit Ihrem Benutzer.

Geben Sie einen richtigen Zeitzonennamen im Format Continent/Region, wie zum Beispiel America/Montreal, Africa/Casablancaoder Pacific/Auckland. Verwenden Sie niemals die Abkürzung für 2-4 Buchstaben, wie z. B. ESToder, ISTda es sich nicht um echte Zeitzonen handelt, die nicht standardisiert und nicht einmal eindeutig (!) Sind.

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

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

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

Verstrichene Zeit berechnen.

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

Bauen Sie die Kette von "vor langer Zeit" Stücken.

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

Von: 27.09.2010 bis: 04.06.2019

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 verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie java.util.Date, Calendar, & SimpleDateFormat.

Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .

Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .

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

Woher bekomme ich die java.time-Klassen?

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


Ich danke dir sehr!
Ticherhaz

1

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

1

Für Android Genau wie Ravi sagte, aber da viele Leute einfach kopieren wollen, fügen Sie das Ding hier ein.

  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 erhalten die Daten von irgendwoher. Zuerst müssen Sie das Format herausfinden.

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

dies wird übersetzt in

SimpleDateFormat-Formatierer = neues SimpleDateFormat ("EEE, TT MMM JJJJ HH: MM: SS Z");

woher weiß ich das Lesen Sie hier die Dokumentation.

Dann, nachdem ich es analysiert habe, bekomme ich ein Date. Dieses Datum habe ich in den getRelativeTimeSpanString eingegeben (ohne zusätzliche Parameter ist es für mich in Ordnung, standardmäßig Minuten zu verwenden).

Sie erhalten eine Ausnahme, wenn Sie nicht die richtige Analysezeichenfolge gefunden haben. So etwas wie: Ausnahme bei Zeichen 5 . Schauen Sie sich Zeichen 5 an und korrigieren Sie Ihre anfängliche Analysezeichenfolge. . Möglicherweise erhalten Sie eine weitere Ausnahme. Wiederholen Sie diese Schritte, bis Sie die richtige Formel gefunden haben.


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

}}

Anruf

val String = timeAgo (unixTimeStamp)

um die Zeit vor in Kotlin zu bekommen


0

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

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

Dies ist das sehr 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

Dafür habe ich Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years agoin diesem Beispiel das Datum wie 2018-09-05T06:40:46.183Zdieses oder ein anderes wie das folgende analysiert

Fügen Sie den folgenden Wert in string.xml hinzu

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

Wenn Sie an Android arbeiten, können Sie dies verwenden: android.text.format.DateUtils.getRelativeTimeSpanString (Millisekunden)
Wajid Ali

0

Sie können Javas Library RelativeDateTimeFormatter verwenden , genau das tut es:

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"

1
Das ist eine Android-Bibliothek, keine Java-Bibliothek.
Madbreaks

0

Ich verwende Instant, Date und DateTimeUtils. Die Daten (Datum), die in der Datenbank in Form eines Strings 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;
    }

1
Sie verwenden schreckliche alte Datums- / Uhrzeitklassen , die vor Jahren durch die Klassen java.time ersetzt wurden .
Basil Bourque

@BasilBourque Ich kann immer noch nicht den neuesten Weg finden, dies zu tun.
Ticherhaz

@BasilBourque Ich habe Code hinzugefügt, damit ich ihn verstehe. github.com/ticherhaz/tarikhmasa
Ticherhaz

0

Die folgenden Lösungen sind alle in reinem Java:

Option 1: Keine Rundung und nur größter Zeitcontainer

Die folgende Funktion zeigt nur den größten Zeitcontainer an. Wenn beispielsweise die tatsächlich verstrichene Zeit ist "1 month 14 days ago", wird diese Funktion nur angezeigt "1 month ago". Diese Funktion wird auch immer abgerundet, sodass eine Zeit entsprechend "50 days ago"angezeigt wird als"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: Mit Rundung

Wickeln einfach die Zeit Container , den Sie mit einem Math.round (...) Aussage Runde möchten, wenn Sie also zu Runde wollte 50 dayszu 2 months, ändern long months = days / 30zulong months = Math.round(days / 30.0)


1
Die Verwendung Durationmit seinen to…PartMethoden wäre viel einfacher, wie in meiner Antwort gezeigt .
Basil Bourque

0

Hier ist mein Testfall, hoffe es hilft:

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

1
Die schreckliche CalendarKlasse wurde vor Jahren durch die modernen Java.time- Klassen mit der Einführung von JSR 310 ersetzt . Schlechter Rat im Jahr 2019.
Basil Bourque

Sie müssen gemeint haben var, nicht val.
Basil Bourque

0

Die Funktion getrelativeDateTime gibt Ihnen die Datums- und Uhrzeitangabe an , wie Sie in der WhatsApp-Benachrichtigung sehen.
Um zukünftige relative Datums- und Uhrzeitangaben zu erhalten, fügen Sie Bedingungen dafür hinzu. Dies wurde speziell für das Abrufen von Datum und Uhrzeit wie WhatsApp-Benachrichtigungen erstellt.

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

Vielen Dank für Ihren Beitrag. Es ist nicht genau das, was gefragt wurde, aber vielleicht kann es jemand benutzen. Weder jemand noch sonst jemand sollte es benutzen wollen SimpleDateFormatund Calendartrotzdem. Diese Klassen sind schlecht gestaltet und längst veraltet. Lesen Sie stattdessen die Antworten, die java.time verwenden, die moderne Java-API für Datum und Uhrzeit.
Ole VV
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.