Come calcolare "tempo fa" in Java?


127

In Ruby on Rails, c'è una funzione che ti consente di prendere qualsiasi data e stampare quanto "molto tempo fa" era.

Per esempio:

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

C'è un modo semplice per farlo in Java?


1
Vedi: stackoverflow.com/questions/11/how-do-i-calculate-relative-time È C #, ma sono sicuro che puoi convertirlo con pochi problemi.
Brandon,

Risposte:


177

Dai un'occhiata alla libreria PrettyTime .

È abbastanza semplice da usare:

import org.ocpsoft.prettytime.PrettyTime;

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

Puoi anche passare un'impostazione internazionale per i messaggi internazionalizzati:

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

Come notato nei commenti, Android ha questa funzionalità integrata nella android.text.format.DateUtilsclasse.


229
Nel caso in cui lavori su Android puoi usare questo: android.text.format.DateUtils # getRelativeTimeSpanString ()
Somatik,

Puoi per favore aggiungere qualche altra descrizione alla tua risposta, solo il link per la risposta non è buono per ora.
Ajay S

@Somatik se devi ottenerlo su una piattaforma non Android, puoi visualizzare quella classe su AOSP.
greg7gkb,

@ataylor come questo uso in Android ??
Hardik Parmar,

getRelativeTimeSpanString non è l'ideale per tutte le situazioni ed è per questo che ho creato la mia classe sulla base di molti esempi qui. Vedere la mia soluzione qui di seguito: stackoverflow.com/a/37042254/468360
Codeversed

67

Hai considerato l' enum TimeUnit ? Può essere abbastanza utile per questo tipo di cose

    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
Non penso che questa sia una risposta completa poiché le unità di tempo sono indipendenti. Ad esempio, il tempo in millisecondi è di pochi minuti * 60 * 1000. È necessario ridurre da ogni unità di tempo l'unità di tempo successiva più grande (dopo averla convertita in unità di tempo inferiore) per poterla utilizzare in un "tempo fa " corda.
Nativ,

@Benj - Esatto? sopra la soluzione? perché una volta è nel formato 12 ore e un'altra è nel formato 24 ore. Fammi sapere il tuo feedback per la mia domanda. Grazie in anticipo.
Rapido

questo non è corretto però ... ogni unità è indipendente l'una dall'altra come già menzionato.
Jonathan Laliberte,

1
android lo fa per te Nel caso in cui lavori su Android puoi usare questo: android.text.format.DateUtils.getRelativeTimeSpanString (millisecondi)
Wajid Ali,

50

Prendo le risposte di RealHowTo e Ben J e creo la mia versione:

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

che stamperà quanto segue

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

Veramente cool. Ed è davvero facile aggiungere altre unità di tempo come settimana (e)
Piotr

1
questo merita più voti. Prima di tutto, nessuna biblioteca necessaria. È ancora pulito, elegante e facile da cambiare.
fangzhzh,

piccolo errore di battitura: all'interno del codice si fa riferimento alle proprietà statiche "Elenchi" anziché "TimeAgo". Lists.times.get (i) dovrebbe essere TimeAgo.get (i) ... e così via
Diogo Gomes

2
Piccolo suggerimento: usare .append(temp != 1 ? "s" : "")invece che .append(temp > 1 ? "s" : "")perché 0 dovrebbe avere anche il ssuffisso
berkus

1
@ShajeelAfzal sì, il parametro duration è in millisecondi ma è una differenza tra i tempi non un valore assoluto. Quello che stai ottenendo è il tempo trascorso dal 1 ° gennaio 1970 la data in cui è iniziato il timestamp di unix
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 @ Formatta una durata in millisecondi in un formato leggibile dall'uomo


Ho finito per usare una versione rivista di questo. Ho pubblicato le mie revisioni per te.
David Blevins,

5
David Blevins, più esempi su PrettyTime: stackoverflow.com/questions/3859288/... Big -1 per reinventare la ruota, una volta di più e non raccomandando un terzo :-p libreria di partito
zakmck

9

Questo si basa sulla risposta di RealHowTo, quindi se ti piace, dagli anche un po 'di amore.

Questa versione ripulita consente di specificare l'intervallo di tempo che potrebbe interessare.

Gestisce anche la parte "e" in modo leggermente diverso. Trovo spesso quando unire le stringhe con un delimitatore è spesso più semplice saltare la logica complicata ed eliminare l'ultimo delimitatore quando hai finito.

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

Piccolo codice per dargli un vortice:

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

}

Che produrrà quanto segue:

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 

E nel caso qualcuno ne abbia mai bisogno, ecco una classe che convertirà qualsiasi stringa come quella sopra in millisecondi . È abbastanza utile per consentire alle persone di specificare i timeout di varie cose nel testo leggibile.


9

c'è un modo semplice per farlo:

diciamo che vuoi il tempo 20 minuti fa:

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

questo è tutto..


1
Nella maggior parte dei casi, si desidera un display "intelligente", ad es. invece di 5125 minuti fa, lo dici x giorni fa.
PhiLho,

7

Informazioni sulle soluzioni integrate:

Java non ha alcun supporto integrato per la formattazione dei tempi relativi, anche Java-8 e il suo nuovo pacchetto java.time . Se hai solo bisogno dell'inglese e nient'altro allora e solo allora una soluzione fatta a mano potrebbe essere accettabile - vedi la risposta di @RealHowTo (anche se ha il forte svantaggio di non tener conto del fuso orario per la traduzione di delta istantanei nell'ora locale unità!). Ad ogni modo, se si desidera evitare soluzioni alternative complesse coltivate in casa, specialmente per altre versioni locali, è necessaria una libreria esterna.

In quest'ultimo caso, consiglio di utilizzare la mia libreria Time4J (o Time4A su Android). Offre la massima flessibilità e la massima potenza i18n . La classe net.time4j.PrettyTime ha sette metodi printRelativeTime...(...)per questo scopo. Esempio di utilizzo di un orologio di prova come sorgente temporale:

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

Un altro esempio che utilizza java.time.Instantcome input:

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

Questa libreria supporta tramite l'ultima versione (v4.17) 80 lingue e anche alcune localizzazioni specifiche per paese (specialmente per spagnolo, inglese, arabo, francese). I dati i18n si basano principalmente sull'ultima versione CLDR v29 . Altri motivi importanti per cui utilizzare questa libreria sono un buon supporto per le regole plurali (che spesso sono diverse dall'inglese in altre lingue), stile di formato abbreviato (ad esempio: "1 sec fa") e modi espressivi per tenere conto dei fusi orari . Time4J è persino a conoscenza di dettagli esotici come i secondi saltati nei calcoli dei tempi relativi (non molto importante ma forma un messaggio relativo all'orizzonte delle aspettative). La compatibilità con Java-8esiste a causa di metodi di conversione facilmente disponibili per tipi come java.time.Instanto java.time.Period.

Ci sono degli svantaggi? Solo due.

  • La libreria non è piccola (anche a causa del suo grande repository i18n-data).
  • L'API non è ben nota, quindi la conoscenza e il supporto della community non sono ancora disponibili, altrimenti la documentazione fornita è piuttosto dettagliata e completa.

Alternative (compatte):

Se cerchi una soluzione più piccola e non hai bisogno di tante funzionalità e sei disposto a tollerare possibili problemi di qualità relativi ai dati i18n, allora:

  • Consiglierei ocpsoft / PrettyTime (supporto per 32 lingue (presto 34?) Adatto a lavorare conjava.util.Date - vedi la risposta di @ataylor). Il CLDR standard del settore (dal consorzio Unicode) con il suo ampio background di comunità non è purtroppo una base dei dati i18n, quindi ulteriori miglioramenti o miglioramenti dei dati possono richiedere del tempo ...

  • Se sei su Android, allora la classe helper android.text.format.DateUtils è un'alternativa integrata sottile (vedi altri commenti e risposte qui, con lo svantaggio di non avere supporto per anni e mesi. E sono sicuro che solo pochissime persone apprezzano lo stile API di questa classe di supporto.

  • Se sei un fan di Joda-Time , puoi guardare la sua classe PeriodFormat (supporto per 14 lingue nella versione v2.9.4, dall'altro lato: Joda-Time non è sicuramente compatto, quindi lo menziono qui solo per completezza). Questa libreria non è una vera risposta perché i tempi relativi non sono affatto supportati. Dovrai aggiungere almeno il letterale "ago" (e rimuovere manualmente tutte le unità inferiori dai formati di elenco generati - scomodo). A differenza di Time4J o Android-DateUtils, non ha un supporto speciale per le abbreviazioni o il passaggio automatico da tempi relativi a rappresentazioni di tempo assolute. Come PrettyTime, dipende totalmente dai contributi non confermati dei membri privati ​​della comunità Java ai suoi dati i18n.


5

Se stai cercando un semplice "Oggi", "Ieri" o "x giorni fa".

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

Utilizzo del framework java.time incorporato in Java 8 e versioni successive.

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
Tali Durationmetodi riportano l' intera durata come numero totale di ore e come numero totale di minuti. In Java 8 la classe mancava stranamente di metodi per ottenere ogni parte di ora, minuti e secondi. Java 9 porta quei metodi, to…Part.
Basil Bourque,

4

Ho creato una semplice porta timeago Java del plug-in jquery-timeago che fa quello che stai chiedendo.

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

4

Nel caso in cui stai sviluppando un'app per Android, fornisce la classe di utilità DateUtils per tutti questi requisiti. Dai un'occhiata al metodo di utilità DateUtils # getRelativeTimeSpanString () .

Dai documenti per

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

Restituisce una stringa che descrive "time" come tempo relativo a "now". Gli intervalli di tempo passati sono formattati come "42 minuti fa". Gli intervalli di tempo in futuro sono formattati come "In 42 minuti".

Ti verrà passare il vostro timestampcome tempo e System.currentTimeMillis()come ora . Il minResolutionpermette di specificare il periodo minimo da segnalare.

Ad esempio, un tempo di 3 secondi nel passato verrà segnalato come "0 minuti fa" se impostato su MINUTE_IN_MILLIS. Passa uno di 0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, WEEK_IN_MILLIS ecc.


4

È possibile utilizzare questa funzione per calcolare il tempo fa

 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) Qui time_ago è in microsecondi


4

Sulla base di una serie di risposte qui, ho creato quanto segue per il mio caso d'uso.

Esempio di utilizzo:

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

È molto utile, grazie mille.
Haya Akkad,

3

Il pacchetto joda-time ha il concetto di Periodi . Puoi fare l'aritmetica con Periodi e DateTimes.

Dai documenti :

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


2

Questo è un codice migliore se consideriamo le prestazioni e riduce il numero di calcoli. Motivo I minuti vengono calcolati solo se il numero di secondi è maggiore di 60 e le Ore vengono calcolate solo se il numero di minuti è maggiore di 60 e così via ...

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
Nel caso in cui tu stia lavorando su Android puoi usare questo: android.text.format.DateUtils.getRelativeTimeSpanString (millisecondi)
Wajid Ali,

2

java.time

La risposta di Habsq ha l'idea giusta ma i metodi sbagliati.

Per un arco di tempo non attaccato alla linea temporale nella scala di anni-mesi-giorni, utilizzare Period. Per i giorni che significano blocchi di 24 ore non correlati al calendario e ore-minuti-secondi, utilizzare Duration. Mescolare le due scale raramente ha senso.

Duration

Inizia recuperando il momento attuale come visto in UTC , usando la Instantclasse.

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

Genera testo per ore, minuti e secondi.

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

Scarica alla console.

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

Da: 2019-06-04T11: 53: 55.714965Z a: 2019-06-04T20: 02: 03.714965Z

8 ore fa

8 minuti fa

8 secondi fa

Period

Inizia ottenendo la data corrente.

Un fuso orario è fondamentale per determinare una data. Per ogni dato momento, la data varia in tutto il mondo per zona. Ad esempio, pochi minuti dopo la mezzanotte a Parigi, la Francia è un nuovo giorno mentre è ancora "ieri" a Montréal Québec .

Se non viene specificato alcun fuso orario, la JVM applica implicitamente il fuso orario predefinito corrente. Tale inadempienza può cambiare in qualsiasi momento durante il runtime (!), Quindi i risultati possono variare. Meglio specificare esplicitamente il fuso orario desiderato / previsto come argomento. Se critico, confermare la zona con l'utente.

Specificare un nome proprio fuso orario nel formato Continent/Region, come ad esempio America/Montreal, Africa/Casablancao Pacific/Auckland. Non usare mai il 2-4 lettera sigla come ad esempio ESTo ISTcome sono non fusi orari veri e propri, non standardizzati, e nemmeno unico (!).

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

Ricreare un appuntamento otto giorni, mesi e anni fa.

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

Calcola il tempo trascorso.

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

Costruisci la stringa di pezzi "tempo fa".

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

Scarica alla console.

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

Da: 2010-09-27 a: 2019-06-04

8 giorni fa

8 mesi fa

8 anni fa


Informazioni su java.time

Il framework java.time è integrato in Java 8 e versioni successive. Queste classi soppiantare la vecchia fastidiosi legacy classi data-time come java.util.Date, Calendar, e SimpleDateFormat.

Per saperne di più, consulta il tutorial Oracle . E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310 .

Il progetto Joda-Time , ora in modalità manutenzione , consiglia la migrazione alle classi java.time .

Puoi scambiare oggetti java.time direttamente con il tuo database. Utilizzare un driver JDBC conforme a JDBC 4.2 o successivo. Non c'è bisogno di stringhe, non è necessariojava.sql.* classi.

Dove ottenere le classi java.time?

Il progetto ThreeTen-Extra estende java.time con classi aggiuntive. Questo progetto è un banco di prova per possibili aggiunte future a java.time. Si possono trovare alcune classi utili, come per esempio Interval, YearWeek, YearQuartere altro .


Grazie mille!
Ticherhaz,

1

Dopo lunghe ricerche ho scoperto questo.

    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

Per Android Esattamente come ha detto Ravi, ma poiché molte persone vogliono semplicemente copiare e incollare la cosa qui è.

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

Spiegazione per le persone che hanno più tempo

  1. Ottieni i dati da qualche parte. Per prima cosa devi capire il suo formato.

Ex. Ricevo i dati da un server nel formato mer, 27 gen 2016 09:32:35 GMT [questo probabilmente NON è il tuo caso]

questo è tradotto in

Formattatore SimpleDateFormat = new SimpleDateFormat ("EEE, gg MMM aaaa HH: mm: ss Z");

come lo so? Leggi la documentazione qui.

Quindi dopo averlo analizzato ho un appuntamento. quella data che ho inserito in getRelativeTimeSpanString (senza parametri aggiuntivi va bene per me, per impostazione predefinita è minuti)

Otterrai un'eccezione se non riuscissi a capire la stringa di analisi corretta , qualcosa del tipo: eccezione al carattere 5 . Guarda il carattere 5 e correggi la stringa di analisi iniziale. . È possibile ottenere un'altra eccezione, ripetere questi passaggi fino a quando non si dispone della formula corretta.


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

}

Chiamata

val String = timeAgo (unixTimeStamp)

per ottenere il tempo fa a Kotlin


0

Ecco la mia implementazione Java di questo

    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

per me funziona

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

Questa è la sceneggiatura di base. è facile da improvvisare.
Risultato: (XXX ore fa) o (XX giorni fa / ieri / oggi)

<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

per questo ho fatto Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years agoin questo esempio è possibile analizzare la data come 2018-09-05T06:40:46.183Zquesta o qualsiasi altra come di seguito

aggiungi sotto il valore 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>

codice Java provare di seguito

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

Nel caso in cui lavori su Android puoi usare questo: android.text.format.DateUtils.getRelativeTimeSpanString (millisecondi)
Wajid Ali,

0

È possibile utilizzare la libreria RelativeDateTimeFormatter di Java , che fa esattamente questo:

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
Questa è una libreria Android, non una libreria Java.
Madbreaks

0

Sto usando Instant, Date e DateTimeUtils. I dati (data) che sono memorizzati nel database nel tipo di stringa e quindi convertiti in Instant.

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

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

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

    if (second < 60) {
        conversionTime = second + " Saat " + suffix;
    } else if (minute < 60) {
        conversionTime = minute + " Minit " + suffix;
    } else if (hour < 24) {
        conversionTime = hour + " Jam " + suffix;
    } else if (day >= 7) {
        if (day > 30) {
            conversionTime = (day / 30) + " Bulan " + suffix;
        } else if (day > 360) {
            conversionTime = (day / 360) + " Tahun " + suffix;
        } else {
            conversionTime = (day / 7) + " Minggu " + suffix;
        }
    } else if (day < 7) {
        conversionTime = day + " Hari " + suffix;
    }
    return conversionTime;
    }

1
Stai usando terribili vecchie classi di data e ora che sono state soppiantate anni fa dalle classi java.time .
Basil Bourque,

@BasilBourque Non riesco ancora a trovare l'ultimo modo per farlo.
Ticherhaz,

@BasilBourque Ho aggiunto del codice per comprenderlo. github.com/ticherhaz/tarikhmasa
Ticherhaz il

0

Le seguenti soluzioni sono tutte in puro Java:

Opzione 1: nessun arrotondamento e solo contenitore del tempo più grande

La seguente funzione visualizzerà solo il contenitore del tempo più grande, ad esempio, se è il tempo reale trascorso "1 month 14 days ago", questa funzione visualizzerà solo "1 month ago". Questa funzione verrà sempre arrotondata per difetto, quindi un tempo equivalente a "50 days ago"verrà visualizzato come"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";
    }

Opzione 2: con arrotondamento

Basta avvolgere il contenitore di tempo che desideri rotonda con un (...) dichiarazione Math.round, quindi se si voleva rotonda 50 daysa 2 months, modificare long months = days / 30along months = Math.round(days / 30.0)


1
L'uso Durationcon i suoi to…Partmetodi sarebbe molto più semplice, come mostrato nella mia risposta .
Basil Bourque,

0

Ecco il mio caso di test, spero che aiuti:

    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
La Calendarclasse terribile è stata soppiantata anni fa dalle moderne classi java.time con l'adozione di JSR 310 . Scarsi consigli nel 2019.
Basil Bourque,

Devi aver significato var, no val.
Basil Bourque,

0

La funzione getrelativeDateTime ti darà la data e l'ora come vedi nella notifica di Whatsapp.
Per ottenere la data e l'ora relativa futura, aggiungere le condizioni per esso. Questo è stato creato appositamente per ottenere la data e l'ora come la notifica di Whatsapp.

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

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

public static long StartOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTimeInMillis();
}

Grazie per aver voluto contribuire. Non è esattamente quello che è stato chiesto, ma forse qualcuno può usarlo. Né quel qualcuno né chiunque altro dovrebbe voler usare SimpleDateFormate Calendar, comunque. Queste classi sono mal progettate e obsolete da tempo. Leggi invece le risposte che utilizzano java.time, la moderna API di data e ora di Java.
Ole VV,

0

Per la mancanza di semplicità e la risposta aggiornata, segue la versione più recente di Java 8 e successive

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

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

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

Questa è la versione che utilizza l'API Java Time che tenta di risolvere i problemi del passato per gestire la data e l'ora.

Javadoc

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

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

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

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.