2010-10-04 12 views
102

En Ruby on Rails, hay una función que le permite tomar cualquier fecha e imprimir cómo fue "hace mucho tiempo".¿Cómo se calcula el "tiempo atrás" en Java?

Por ejemplo:

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

¿Hay una manera fácil de hacer esto en Java?

+1

Ver: http: // stackoverflow.com/questions/11/how-do-i-calculate-relative-time Es C#, pero estoy seguro de que puedes convertirlo sin problemas. – Brandon

Respuesta

148

Eche un vistazo a la biblioteca PrettyTime.

Es muy sencillo de usar:

import org.ocpsoft.prettytime.PrettyTime; 

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

También se puede pasar de un local para los mensajes internacionalizados:

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

Como se señaló en los comentarios, Android tiene esta funcionalidad incorporada en la clase android.text.format.DateUtils .

+196

En caso de que esté trabajando en Android, puede usar esto: android.text.format.DateUtils # getRelativeTimeSpanString() – Somatik

+0

¿Puede agregar alguna más descripción a su respuesta, la respuesta del enlace solo no es buena por ahora? –

+0

@Somatik si necesita obtener esto en una plataforma que no sea de Android, puede [ver esa clase] (https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/ java/android/text/format/DateUtils.java) en AOSP. – greg7gkb

3

El paquete joda-time, tiene la noción de Periods. Puede hacer aritmética con Períodos y Fecha y hora.

Desde el docs:

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

¿Ha considerado la TimeUnit enumeración? puede ser muy útil para este tipo de cosas

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

No creo que esta sea una respuesta completa ya que las unidades de tiempo son independientes. Por ejemplo, el tiempo de los milisegundos es de solo minutos * 60 * 1000. Debe disminuir desde cada unidad de tiempo la siguiente unidad de tiempo más grande (después de convertirla a la unidad de tiempo más baja) para poder usarla en un "tiempo atrás". " cuerda. – Nativ

+0

** @ Benj ** - ¿Correcto? por encima de la solución? porque una vez está en formato de 12 horas y otra vez está en formato de 24 horas. Déjame saber tus comentarios para mi consulta. Gracias por adelantado. – Swift

+0

esto es incorrecto ... cada unidad es independiente entre sí como ya se mencionó. –

41
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 
     */ 
    } 
} 

más @Format a duration in milliseconds into a human-readable format

+0

Terminé usando una versión revisada de esto. Publiqué mis revisiones para ti. –

+4

David Blevins, más ejemplos sobre PrettyTime: http://stackoverflow.com/questions/3859288/how-to-calculate-time-ago-in-java Big -1 para reinventar la rueda una vez más y no recomendar una biblioteca de terceros :-p – zakmck

9

Esto se basa en la respuesta de RealHowTo así que si te gusta, dale un poco de amor también.

Este limpiado versión le permite especificar el intervalo de tiempo que podría estar interesado en.

También se ocupa de la "y" parte un poco diferente. A menudo encuentro que al unir cadenas con un delimitador, es más fácil omitir la lógica complicada y simplemente eliminar el último delimitador cuando haya terminado.

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

pequeño código para darle un giro:

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

} 

¿Cuál es la salida siguiente:

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 

Y en caso de que alguien alguna vez lo necesita, aquí es una clase que va a convertir cualquier cadena como la anterior back into milliseconds. Es bastante útil para permitir que las personas especifiquen tiempos de espera de varias cosas en el texto legible.

4

Creé un puerto simple Java timeago del plug-in jquery-timeago que hace lo que está pidiendo.

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

hay una manera simple de hacer esto:

digamos que desea que el tiempo hace 20 minutos:

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

eso es todo ..

+1

En la mayoría de los casos, desea una pantalla "inteligente", es decir. en vez de hace 5125 minutos, dices x días atrás. – PhiLho

+0

¿Qué sucede si necesita información sobre la configuración regional? –

5

Si busca un sencillo "Hoy", "Ayer" o "x días atrás".

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

Tomo RealHowTo y Ben J respuestas y hacer mi propia versión:

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

que imprimirá el siguiente java.time

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 
+0

Realmente genial. Y es realmente fácil agregar otras unidades de tiempo, como la (s) semana (s) – Piotr

+1

, esta se merece más votos ascendentes. En primer lugar, no se necesita biblioteca. Sigue siendo limpio, elegante y fácil de cambiar. – fangzhzh

+0

small typo: dentro de su código está haciendo referencia a las propiedades estáticas "Listas" en lugar de "TimeAgo". Lists.times.get (i) debe ser TimeAgo.get (i) ... y así sucesivamente –

6

Utilizando el marco java.time integrado en Java 8 y posterior.

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"); 
+0

. Estos métodos de 'Duración 'informan la duración * completa * como el número total de horas y una cantidad total de minutos. En Java 8, la clase extrañamente carecía de métodos para obtener cada * parte * de hora y minutos y segundos. Java 9 trae esos métodos, 'a ... Parte'. –

1

Después de una larga investigación encontré esto.

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

En caso de que esté desarrollando una aplicación para Android, que proporciona la clase de utilidad DateUtils para todos estos requisitos. Eche un vistazo al método de utilidad DateUtils#getRelativeTimeSpanString().

A partir de los documentos de

CharSequence getRelativeTimeSpanString (mucho tiempo, falta mucho, mucho minResolution)

Devuelve una cadena que describe el 'tiempo' como un tiempo en relación con el 'ahora'. Los períodos de tiempo en el pasado tienen el formato "hace 42 minutos". Los períodos de tiempo en el futuro están formateados como "En 42 minutos".

Se le superación de su timestamp como tiempo y System.currentTimeMillis() como ahora. El minResolution le permite especificar el intervalo de tiempo mínimo para informar.

Por ejemplo, un tiempo de 3 segundos en el pasado se informará como "0 minutos atrás" si se establece en MINUTE_IN_MILLIS. Pasar uno de 0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, etc. WEEK_IN_MILLIS

5

Sobre incorporada soluciones:

Java no tiene soporte incorporado para formatear tiempos relativos, tampoco Java-8 y su nuevo paquete java.time. Si solo necesita inglés y nada más entonces y solo entonces, una solución hecha a mano podría ser aceptable: vea la respuesta de @RealHowTo (aunque tiene la gran desventaja de no tener en cuenta la zona horaria para la traducción de deltas instantáneos a la hora local ¡unidades!).De todos modos, si desea evitar soluciones complejas de fabricación casera, especialmente para otras configuraciones regionales, entonces necesita una biblioteca externa.

En este último caso, recomiendo usar mi biblioteca Time4J (o Time4A en Android). Ofrece mayor flexibilidad y la mayoría de i18n-power. La clase net.time4j.PrettyTime tiene siete métodos printRelativeTime...(...) para este fin. Ejemplo usando un reloj de prueba como fuente de tiempo:

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) 

Otro ejemplo usando java.time.Instant como entrada:

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

Esta biblioteca apoya a través de su última versión (v4.17) 80 idiomas y también algún país locales específicos (especialmente para español, inglés, árabe, francés). Los datos i18n se basan principalmente en la más nueva versión CLDR v29. Otras razones importantes para usar esta biblioteca son buenas compatibilidad con las reglas (que a menudo son diferentes del inglés en otras configuraciones regionales), formato abreviado estilo (por ejemplo: "1 segundo atrás") y formas expresivas para teniendo en cuenta Zonas horarias de cuenta. Time4J es consciente incluso de detalles tan exóticos como segundos bisuntos en los cálculos de tiempos relativos (no es realmente importante pero forma un mensaje relacionado con el horizonte de expectativas). La compatibilidad con Java-8 existe debido a los métodos de conversión fácilmente disponibles para tipos como java.time.Instant o java.time.Period.

¿Hay algún inconveniente? Sólo dos.

  • La biblioteca no es pequeña (también debido a su gran repositorio de datos i18n).
  • La API no es muy conocida, por lo tanto, el conocimiento y el soporte de la comunidad no están disponibles; de lo contrario, la documentación suministrada es bastante detallada y completa.

(resumen) alternativas:

Si usted busca una solución más pequeña y no necesita tantas características y están dispuestos a tolerar posibles problemas de calidad relacionados con la i18n-datos entonces:

  • recomendaría ocpsoft/PrettyTime (apoyo a los actualmente 32 idiomas (pronto 34) adecuados para el trabajo con java.util.Date única - ver la respuesta de @ataylor). El estándar industrial CLDR (del consorcio Unicode) con su gran fondo comunitario desafortunadamente no es una base de datos i18n, por lo que las mejoras o mejoras de los datos pueden tardar un tiempo ...

  • Si está en Android, entonces helper class android.text.format.DateUtils es una delgada alternativa incorporada (vea otros comentarios y respuestas aquí, con la desventaja de que no tiene soporte durante años y meses. Y estoy seguro de que a muy pocas personas les gusta API-estilo de esta clase de ayuda.

  • Si usted es un fan de Joda-Time entonces usted puede mirar a su clase PeriodFormat (apoyo a la 14 idiomas en el lanzamiento v2.9.4, en el otro lado: Joda-Time seguramente no es compacto, así que lo menciono aquí solo para completarlo). Esta biblioteca no es una respuesta real porque los tiempos relativos no son compatibles en absoluto. Tendrá que añadir al menos el literal "ago" (y quitar manualmente todas las unidades inferiores de los formatos de lista generados, incómodo). A diferencia de Time4J o Android-DateUtils, no tiene soporte especial para abreviaturas o cambio automático de tiempos relativos a representaciones de tiempo absoluto. Al igual que PrettyTime, depende totalmente de las contribuciones no confirmadas de los miembros privados de la comunidad Java a su i18n-data.

1

Se puede utilizar esta función para calcular el tiempo hace

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) Aquí TIME_AGO está en microsegundos

0

Aquí está mi Java La aplicación de esta

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

Para Android Exactamente como dijo Ravi, pero como mucha gente quiere , simplemente copie y pegue aquí está.

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

Explicación para las personas que tienen más tiempo

  1. Usted obtiene los datos de alguna parte. Primero tienes que descubrir su formato.

Ej. Consigo los datos de un servidor en el formato Miér 27 Ene el año 2016 09:32:35 GMT [esto probablemente no es su caso]

esto se traduce en

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

¿cómo lo sé? Lea el documentation here.

Luego, después de analizarlo, obtengo una fecha. esa fecha pongo en el getRelativeTimeSpanString (sin ningún parámetro adicional está bien para mí, para ser predeterminado a minutos)

Usted recibirá una excepción si no averiguar la correcta cadena análisis, algo así como : excepción en el carácter 5. Mire el carácter 5 y corrija su cadena de análisis inicial.. Puede obtener otra excepción, repita estos pasos hasta que tenga la fórmula correcta.

1

Basado en un montón de respuestas aquí, creé lo siguiente para mi caso de uso.

Ejemplo de uso:

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

funciona para mí

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

Este es el guión muy básico. es fácil de improvisar
Resultado: (Hace XXX Horas) o (XX Dias/Ayer/Hoy)

<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> 
1

Este es un código mejor si tenemos en cuenta performance.It reduce el número de cálculos. Razón Minutos se calculan sólo si el número de segundos es superior a 60 y Horas se calculan sólo si el número de minutos es superior a 60 y así sucesivamente ...

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

} 

} 
Cuestiones relacionadas