En caso de que esté trabajando en Android, puede usar esto: android.text.format.DateUtils # getRelativeTimeSpanString ()
Somatik
¿Puede agregar alguna descripción más a su respuesta? La respuesta de solo enlace no es buena por ahora.
Ajay S
@Somatik si necesita obtener esto en una plataforma que no sea Android, puede ver esa clase en AOSP.
greg7gkb
@ataylor ¿cómo se usa esto en Android?
Hardik Parmar
getRelativeTimeSpanString no es ideal para todas las situaciones y es por eso que creé mi propia clase basada en muchos de los ejemplos aquí. Vea mi solución a continuación: stackoverflow.com/a/37042254/468360
Codeversed
67
¿Has considerado la enumeración de TimeUnit ? Puede ser bastante útil para este tipo de cosas.
try{SimpleDateFormat format =newSimpleDateFormat("dd/MM/yyyy");Date past = format.parse("01/10/2010");Date now =newDate();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();}
No creo que esta sea una respuesta completa ya que las unidades de tiempo son independientes. Por ejemplo, el tiempo de milisegundos es solo minutos * 60 * 1000. Debe disminuir de cada unidad de tiempo la siguiente unidad de tiempo más grande (después de convertirla en la unidad de tiempo más baja) para poder usarla en un "tiempo atrás" " cuerda.
Nativ
@Benj - ¿Es correcto? solución anterior? porque una vez está en formato de 12 horas y otra hora está en formato de 24 horas. Déjame saber tus comentarios para mi consulta. Gracias por adelantado.
Swift
sin embargo, esto es incorrecto ... cada unidad es independiente de la otra como ya se mencionó.
Jonathan Laliberte el
1
Android lo hace por usted En caso de que esté trabajando en Android, puede usar esto: android.text.format.DateUtils.getRelativeTimeSpanString (milisegundos)
Wajid Ali el
50
Tomo las respuestas de RealHowTo y Ben J y hago mi propia versión:
publicclassTimeAgo{publicstaticfinalList<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));publicstaticfinalList<String> timesString =Arrays.asList("year","month","day","hour","minute","second");publicstaticString toDuration(long duration){StringBuffer res =newStringBuffer();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";elsereturn res.toString();}publicstaticvoid 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á lo siguiente
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
Realmente genial. Y es realmente fácil agregar otras unidades de tiempo como semana (s)
Piotr
1
Este merece más votos a favor. En primer lugar, no se necesita biblioteca. Todavía está limpio, elegante y fácil de cambiar.
fangzhzh
pequeño error tipográfico: dentro de su código, hace referencia a las propiedades estáticas "Listas" en lugar de "TimeAgo". Lists.times.get (i) debería ser TimeAgo.get (i) ... y así sucesivamente
Diogo Gomes
2
Pequeña sugerencia: usar en .append(temp != 1 ? "s" : "")lugar de .append(temp > 1 ? "s" : "")porque 0 también debería tener ssufijo
berkus
1
@ShajeelAfzal sí, el parámetro de duración está en milisegundos pero es una diferencia entre tiempos, no un valor absoluto. Lo que está obteniendo es el tiempo transcurrido desde el 1 de enero de 1970, la fecha en que comenzó la marca de tiempo de Unix
Terminé usando una versión revisada de esto. He publicado mis revisiones para ti.
David Blevins
55
David Blevins, más ejemplos sobre PrettyTime: stackoverflow.com/questions/3859288/… Big -1 por 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.
Esta versión limpia le permite especificar el rango de tiempo que le puede interesar.
También maneja la parte "y" 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 borrar el último delimitador cuando haya terminado.
import java.util.concurrent.TimeUnit;importstatic java.util.concurrent.TimeUnit.MILLISECONDS;publicclassTimeUtils{/**
* 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
*/publicstaticString formatMillis(long duration,TimeUnit max,TimeUnit min){StringBuilder res =newStringBuilder();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 aboutif(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();}}
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 lo necesite, aquí hay una clase que convertirá cualquier cadena como la anterior nuevamente en milisegundos . Es bastante útil para permitir que las personas especifiquen tiempos de espera de varias cosas en texto legible.
En la mayoría de los casos, desea una pantalla "inteligente", es decir. en lugar de hace 5125 minutos, dices x días atrás.
PhiLho
7
Sobre soluciones integradas :
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 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 alternativas complejas, especialmente para otras configuraciones regionales, necesita una biblioteca externa.
En este último caso, recomiendo usar mi biblioteca Time4J (o Time4A en Android). Ofrece la mayor flexibilidad y la mayor potencia i18n . La clase net.time4j.PrettyTime tiene siete métodos printRelativeTime...(...)para este propósito. 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 inputString durationInDays =PrettyTime.of(Locale.GERMAN).withReferenceClock(clock).printRelative(
moment,Timezone.of(EUROPE.BERLIN),TimeUnit.DAYS);// controlling the precisionSystem.out.println(durationInDays);// heute (german word for today)
Otro ejemplo usando java.time.Instantcomo entrada:
String relativeTime =PrettyTime.of(Locale.ENGLISH).printRelativeInStdTimezone(Moment.from(Instant.EPOCH));System.out.println(relativeTime);// 45 years ago
Esta biblioteca admite a través de su última versión (v4.17) 80 idiomas y también algunas configuraciones regionales específicas del país (especialmente para español, inglés, árabe, francés). Los datos i18n se basan principalmente en la versión más reciente de CLDR v29 . Otras razones importantes por las que usar esta biblioteca son un buen soporte para reglas plurales (que a menudo son diferentes del inglés en otros idiomas), un estilo de formato abreviado (por ejemplo: "Hace 1 segundo") y formas expresivas para tener en cuenta las zonas horarias . Time4J incluso es consciente de detalles tan exóticos como segundos intercalares 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-8existe debido a los métodos de conversión fácilmente disponibles para tipos como java.time.Instanto 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 se conoce bien, por lo que el conocimiento y el soporte de la comunidad aún no están disponibles; de lo contrario, la documentación suministrada es bastante detallada y completa.
Alternativas (compactas):
Si busca una solución más pequeña y no necesita tantas funciones y está dispuesto a tolerar posibles problemas de calidad relacionados con i18n-data, entonces:
Recomendaría ocpsoft / PrettyTime (soporte para actualmente 32 idiomas (¿pronto 34?) Adecuados para trabajar java.util.Datesolo; vea la respuesta de @ataylor). Desafortunadamente, el CLDR estándar de la industria (del consorcio Unicode) con su gran experiencia en la comunidad no es una base de los datos i18n, por lo que otras mejoras o mejoras de datos pueden tomar un tiempo ...
Si está en Android, entonces la clase auxiliar android.text.format.DateUtils es una alternativa incorporada delgada (vea otros comentarios y respuestas aquí, con la desventaja de que no tiene soporte durante años y meses. Y estoy seguro de que solo A muy pocas personas les gusta el estilo API de esta clase auxiliar.
Si eres fanático de Joda-Time, entonces puedes ver su clase PeriodFormat (soporte para 14 idiomas en la versión v2.9.4, por otro lado: Joda-Time seguramente tampoco es compacto, así que lo menciono aquí solo por lo completo). Esta biblioteca no es una respuesta real porque los tiempos relativos no son compatibles en absoluto. Necesitará agregar el literal "ago" al menos (y eliminar 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 sus datos i18n.
privateString getDaysAgo(Date date){long days =(newDate().getTime()- date.getTime())/86400000;if(days ==0)return"Today";elseif(days ==1)return"Yesterday";elsereturn days +" days ago";}
Usando el framework 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");
Esos Durationmétodos informan la duración completa como un número total de horas y como un número total de minutos. En Java 8, la clase extrañamente carecía de métodos para obtener cada parte de hora, minutos y segundos. Java 9 trae esos métodos, to…Part.
En caso de que esté desarrollando una aplicación para Android, proporciona la clase de utilidad DateUtils para todos esos requisitos. Eche un vistazo al método de utilidad DateUtils # getRelativeTimeSpanString () .
De los documentos para
CharSequence getRelativeTimeSpanString (mucho tiempo, mucho tiempo, mucho tiempo minResolution)
Devuelve una cadena que describe 'tiempo' como un tiempo relativo a 'ahora'. Los períodos de tiempo en el pasado están formateados como "hace 42 minutos". Los períodos de tiempo en el futuro están formateados como "En 42 minutos".
Se le pasa en tu timestampcomo el tiempo y System.currentTimeMillis()como ahora . Le minResolutionpermite especificar el intervalo de tiempo mínimo para informar.
Por ejemplo, un tiempo de 3 segundos en el pasado se informará como "hace 0 minutos" si se establece en MINUTE_IN_MILLIS. Pase uno de 0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, WEEK_IN_MILLIS, etc.
Este es un código mejor si consideramos el rendimiento. Reduce la cantidad de cálculos.
Motivo Los
minutos se calculan solo si el número de segundos es mayor que 60 y las Horas se calculan solo si el número de minutos es mayor que 60 y así sucesivamente ...
En caso de que esté trabajando en Android, puede usar esto: android.text.format.DateUtils.getRelativeTimeSpanString (milisegundos)
Wajid Ali
2
java.time
La respuesta de Habsq tiene la idea correcta pero los métodos incorrectos.
Para un período de tiempo no conectado a la línea de tiempo en la escala de años-meses-días, use Period. Para los días que significan fragmentos de tiempo de 24 horas no relacionados con el calendario y las horas-minutos-segundos, use Duration. Mezclar las dos escalas rara vez tiene sentido.
Duration
Comience buscando el momento actual como se ve en UTC , utilizando la Instantclase.
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 texto por horas, minutos y segundos.
// Generate text by calling `to…Part` methods.String output = d.toHoursPart()+" hours ago\n"+ d.toMinutesPart()+" minutes ago\n"+ d.toSecondsPart()+" seconds ago";
Volcado a la consola.
System.out.println("From: "+ then +" to: "+ now );System.out.println( output );
Una zona horaria es crucial para determinar una fecha. Para cualquier momento dado, la fecha varía en todo el mundo por zona. Por ejemplo, unos minutos después de la medianoche en París, Francia es un nuevo día mientras todavía "ayer" en Montreal Québec .
Si no se especifica una zona horaria, la JVM aplica implícitamente su zona horaria predeterminada actual. Ese valor predeterminado puede cambiar en cualquier momento durante el tiempo de ejecución (!), Por lo que sus resultados pueden variar. Es mejor especificar su zona horaria deseada / esperada explícitamente como argumento. Si es crítico, confirme la zona con su usuario.
Especificar un nombre de zona horaria correcta en el formato de Continent/Region, por ejemplo America/Montreal, Africa/Casablancao Pacific/Auckland. Nunca use el 2-4 abreviatura de letras tales como ESTo IST, ya que son no verdaderas zonas de tiempo, no estandarizados, y ni siquiera único (!).
ZoneId z =ZoneId.of("America/Montreal");LocalDate today =LocalDate.now( z );
Recrea una fecha hace ocho días, meses y años.
LocalDate then = today.minusYears(8).minusMonths(8).minusDays(7);// Notice the 7 days, not 8, because of granularity of months.
Calcular el tiempo transcurrido.
Period p =Period.between( then , today );
Construye la cadena de piezas de "tiempo atrás".
String output = p.getDays()+" days ago\n"+ p.getMonths()+" months ago\n"+ p.getYears()+" years ago";
Volcado a la consola.
System.out.println("From: "+ then +" to: "+ today );System.out.println( output );
Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .
Puede intercambiar objetos java.time directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No hay necesidad de cadenas, no hay necesidad de java.sql.*clases.
El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Usted puede encontrar algunas clases útiles aquí, como Interval, YearWeek, YearQuarter, y más .
Después de una larga investigación, encontré esto.
publicclassGetTimeLapse{publicstaticString getlongtoago(long createdAt){DateFormat userDateFormat =newSimpleDateFormat("E MMM dd HH:mm:ss Z yyyy");DateFormat dateFormatNeeded =newSimpleDateFormat("MM/dd/yyyy HH:MM:SS");Date date =null;
date =newDate(createdAt);String crdate1 = dateFormatNeeded.format(date);// Date CalculationDateFormat dateFormat =newSimpleDateFormat("MM/dd/yyyy HH:mm:ss");
crdate1 =newSimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(date);// get current date time with Calendar()Calendar cal =Calendar.getInstance();String currenttime = dateFormat.format(cal.getTime());DateCreatedAt=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;}}
Luego, después de analizarlo, tengo una cita. esa fecha la puse en getRelativeTimeSpanString (sin ningún parámetro adicional, estoy bien, por defecto a minutos)
Obtendrá una excepción si no descubrió la cadena de análisis correcta , algo como: excepción en el carácter 5 . Mira el carácter 5 y corrige tu cadena de análisis inicial. . Es posible que obtenga otra excepción, repita estos pasos hasta que tenga la fórmula correcta.
Este es el guión muy básico. Es fácil de improvisar.
Resultado: (Hace XXX horas) o (Hace XX días / Ayer / Hoy)
<span id='hourpost'></span>,or
<span id='daypost'></span><script>
var postTime =newDate('2017/6/9 00:01');
var now =newDate();
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";}elseif(days <2){
result ="Yesterday";}else{
result = days +" Days ago";}
document.getElementById("hourpost").innerHTML = hours +"Hours Ago";
document.getElementById("daypost").innerHTML = result ;</script>
para esto que he hecho Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years agoen este ejemplo, puede analizar la fecha como 2018-09-05T06:40:46.183Zesta o cualquier otra como a continuación
Esa es una biblioteca de Android, no una biblioteca de Java.
Madbreaks
0
Estoy usando Instant, Date y DateTimeUtils. Los datos (fecha) que se almacenan en la base de datos en tipo de cadena y luego se convierten en instantáneos.
/*
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.
*/publicString convertTimeToAgo(String dataDate){//InitializeString conversionTime =null;String suffix ="Yang Lalu";Date pastTime;//Parse from String (which is stored as Instant.now().toString()//And then convert to become DateInstant instant =Instant.parse(dataDate);
pastTime =DateTimeUtils.toDate(instant);//Today dateDate nowTime =newDate();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;}elseif(minute <60){
conversionTime = minute +" Minit "+ suffix;}elseif(hour <24){
conversionTime = hour +" Jam "+ suffix;}elseif(day >=7){if(day >30){
conversionTime =(day /30)+" Bulan "+ suffix;}elseif(day >360){
conversionTime =(day /360)+" Tahun "+ suffix;}else{
conversionTime =(day /7)+" Minggu "+ suffix;}}elseif(day <7){
conversionTime = day +" Hari "+ suffix;}return conversionTime;}
Las siguientes soluciones están todas en Java puro:
Opción 1: sin redondeo y solo contenedor de tiempo más grande
La siguiente función solo mostrará el contenedor de tiempo más grande, por ejemplo, si el tiempo transcurrido verdadero es "1 month 14 days ago", esta función solo se mostrará "1 month ago". Esta función también siempre se redondeará hacia abajo, por lo que "50 days ago"se mostrará un tiempo equivalente a"1 month"
publicString formatTimeAgo(long millis){String[] ids =newString[]{"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 =newArrayList<>(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";}
Opción 2: con redondeo
Simplemente envuelva el contenedor de tiempo que desea redondear con una instrucción Math.round (...), por lo que si desea redondear 50 daysa 2 months, modifique long months = days / 30along months = Math.round(days / 30.0)
Usarlo Durationcon sus to…Partmétodos sería mucho más fácil, como se muestra en mi Respuesta .
Basil Bourque
0
Aquí está mi caso de prueba, espero que ayude:
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"}
La Calendarclase terrible fue suplantada hace años por las modernas clases java.time con la adopción de JSR 310 . Mal consejo en 2019.
Basil Bourque
Debes haber querido decir var, no val.
Basil Bourque
0
La función getrelativeDateTime le dará la fecha y hora como ve en la notificación de Whatsapp.
Para obtener futuras fechas y horas relativas, agréguele condiciones. Esto se crea específicamente para obtener la fecha y hora como la notificación de Whatsapp.
Gracias por querer contribuir. No es exactamente lo que se pidió, pero tal vez alguien pueda usarlo. Sin embargo, ni a nadie ni a nadie debería querer usar SimpleDateFormaty Calendar, sin embargo. Esas clases están mal diseñadas y anticuadas. En su lugar, lea las respuestas que emplean java.time, la API moderna de fecha y hora de Java.
Ole VV
0
Por falta de simplicidad y respuesta actualizada, sigue la versión más reciente de Java 8 y posterior
Respuestas:
Echa un vistazo a la biblioteca PrettyTime .
Es bastante simple de usar:
También puede pasar una configuración regional para mensajes internacionalizados:
Como se señaló en los comentarios, Android tiene esta funcionalidad integrada en la
android.text.format.DateUtils
clase.fuente
¿Has considerado la enumeración de TimeUnit ? Puede ser bastante útil para este tipo de cosas.
fuente
Tomo las respuestas de RealHowTo y Ben J y hago mi propia versión:
que imprimirá lo siguiente
fuente
.append(temp != 1 ? "s" : "")
lugar de.append(temp > 1 ? "s" : "")
porque 0 también debería teners
sufijomore @ Formatee una duración en milisegundos en un formato legible para humanos
fuente
Esto se basa en la respuesta de RealHowTo, así que si te gusta, dale un poco de amor también.
Esta versión limpia le permite especificar el rango de tiempo que le puede interesar.
También maneja la parte "y" 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 borrar el último delimitador cuando haya terminado.
Pequeño código para darle un giro:
Lo que generará lo siguiente:
Y en caso de que alguien lo necesite, aquí hay una clase que convertirá cualquier cadena como la anterior nuevamente en milisegundos . Es bastante útil para permitir que las personas especifiquen tiempos de espera de varias cosas en texto legible.
fuente
Hay una manera simple de hacer esto:
Digamos que quieres el tiempo hace 20 minutos:
Eso es..
fuente
Sobre soluciones integradas :
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 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 alternativas complejas, especialmente para otras configuraciones regionales, necesita una biblioteca externa.En este último caso, recomiendo usar mi biblioteca Time4J (o Time4A en Android). Ofrece la mayor flexibilidad y la mayor potencia i18n . La clase net.time4j.PrettyTime tiene siete métodos
printRelativeTime...(...)
para este propósito. Ejemplo usando un reloj de prueba como fuente de tiempo:Otro ejemplo usando
java.time.Instant
como entrada:Esta biblioteca admite a través de su última versión (v4.17) 80 idiomas y también algunas configuraciones regionales específicas del país (especialmente para español, inglés, árabe, francés). Los datos i18n se basan principalmente en la versión más reciente de CLDR v29 . Otras razones importantes por las que usar esta biblioteca son un buen soporte para reglas plurales (que a menudo son diferentes del inglés en otros idiomas), un estilo de formato abreviado (por ejemplo: "Hace 1 segundo") y formas expresivas para tener en cuenta las zonas horarias . Time4J incluso es consciente de detalles tan exóticos como segundos intercalares 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-8existe debido a los métodos de conversión fácilmente disponibles para tipos como
java.time.Instant
ojava.time.Period
.¿Hay algún inconveniente? Sólo dos.
Alternativas (compactas):
Si busca una solución más pequeña y no necesita tantas funciones y está dispuesto a tolerar posibles problemas de calidad relacionados con i18n-data, entonces:
Recomendaría ocpsoft / PrettyTime (soporte para actualmente 32 idiomas (¿pronto 34?) Adecuados para trabajar
java.util.Date
solo; vea la respuesta de @ataylor). Desafortunadamente, el CLDR estándar de la industria (del consorcio Unicode) con su gran experiencia en la comunidad no es una base de los datos i18n, por lo que otras mejoras o mejoras de datos pueden tomar un tiempo ...Si está en Android, entonces la clase auxiliar android.text.format.DateUtils es una alternativa incorporada delgada (vea otros comentarios y respuestas aquí, con la desventaja de que no tiene soporte durante años y meses. Y estoy seguro de que solo A muy pocas personas les gusta el estilo API de esta clase auxiliar.
Si eres fanático de Joda-Time, entonces puedes ver su clase PeriodFormat (soporte para 14 idiomas en la versión v2.9.4, por otro lado: Joda-Time seguramente tampoco es compacto, así que lo menciono aquí solo por lo completo). Esta biblioteca no es una respuesta real porque los tiempos relativos no son compatibles en absoluto. Necesitará agregar el literal "ago" al menos (y eliminar 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 sus datos i18n.
fuente
Si busca un simple "Hoy", "Ayer" o "Hace x días".
fuente
java.time
Usando el framework java.time integrado en Java 8 y posterior.
fuente
Duration
métodos informan la duración completa como un número total de horas y como un número total de minutos. En Java 8, la clase extrañamente carecía de métodos para obtener cada parte de hora, minutos y segundos. Java 9 trae esos métodos,to…Part
.Creé un puerto Java timeago simple del complemento jquery-timeago que hace lo que está pidiendo.
fuente
En caso de que esté desarrollando una aplicación para Android, proporciona la clase de utilidad DateUtils para todos esos requisitos. Eche un vistazo al método de utilidad DateUtils # getRelativeTimeSpanString () .
De los documentos para
CharSequence getRelativeTimeSpanString (mucho tiempo, mucho tiempo, mucho tiempo minResolution)
Se le pasa en tu
timestamp
como el tiempo ySystem.currentTimeMillis()
como ahora . LeminResolution
permite especificar el intervalo de tiempo mínimo para informar.fuente
Puede usar esta función para calcular hace tiempo
1) Aquí time_ago está en microsegundo
fuente
Basado en un montón de respuestas aquí, creé lo siguiente para mi caso de uso.
Ejemplo de uso:
fuente
El paquete joda-time , tiene la noción de períodos . Puedes hacer aritmética con Periodos y DateTimes.
De los documentos :
fuente
No es bonito ... pero lo más parecido que puedo pensar es usar Joda-Time (como se describe en esta publicación: ¿Cómo calcular el tiempo transcurrido desde ahora con Joda Time?
fuente
Este es un código mejor si consideramos el rendimiento. Reduce la cantidad de cálculos. Motivo Los minutos se calculan solo si el número de segundos es mayor que 60 y las Horas se calculan solo si el número de minutos es mayor que 60 y así sucesivamente ...
fuente
java.time
La respuesta de Habsq tiene la idea correcta pero los métodos incorrectos.
Para un período de tiempo no conectado a la línea de tiempo en la escala de años-meses-días, use
Period
. Para los días que significan fragmentos de tiempo de 24 horas no relacionados con el calendario y las horas-minutos-segundos, useDuration
. Mezclar las dos escalas rara vez tiene sentido.Duration
Comience buscando el momento actual como se ve en UTC , utilizando la
Instant
clase.Genera texto por horas, minutos y segundos.
Volcado a la consola.
Period
Comience por obtener la fecha actual.
Una zona horaria es crucial para determinar una fecha. Para cualquier momento dado, la fecha varía en todo el mundo por zona. Por ejemplo, unos minutos después de la medianoche en París, Francia es un nuevo día mientras todavía "ayer" en Montreal Québec .
Si no se especifica una zona horaria, la JVM aplica implícitamente su zona horaria predeterminada actual. Ese valor predeterminado puede cambiar en cualquier momento durante el tiempo de ejecución (!), Por lo que sus resultados pueden variar. Es mejor especificar su zona horaria deseada / esperada explícitamente como argumento. Si es crítico, confirme la zona con su usuario.
Especificar un nombre de zona horaria correcta en el formato de
Continent/Region
, por ejemploAmerica/Montreal
,Africa/Casablanca
oPacific/Auckland
. Nunca use el 2-4 abreviatura de letras tales comoEST
oIST
, ya que son no verdaderas zonas de tiempo, no estandarizados, y ni siquiera único (!).Recrea una fecha hace ocho días, meses y años.
Calcular el tiempo transcurrido.
Construye la cadena de piezas de "tiempo atrás".
Volcado a la consola.
Acerca de java.time
El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases suplantar la vieja problemáticos heredados clases de fecha y hora como
java.util.Date
,Calendar
, ySimpleDateFormat
.Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .
El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .
Puede intercambiar objetos java.time directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No hay necesidad de cadenas, no hay necesidad de
java.sql.*
clases.¿Dónde obtener las clases java.time?
El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Usted puede encontrar algunas clases útiles aquí, como
Interval
,YearWeek
,YearQuarter
, y más .fuente
Después de una larga investigación, encontré esto.
fuente
Para Android Exactamente como dijo Ravi, pero dado que muchas personas solo quieren copiar y pegar la cosa aquí está.
Explicación para las personas que tienen más tiempo.
Ex. Recibo los datos de un servidor en el formato Mié, 27 de enero de 2016 09:32:35 GMT [este probablemente NO sea su caso]
esto se traduce en
SimpleDateFormat formatter = new SimpleDateFormat ("EEE, dd MMM aaaa HH: mm: ss Z");
como lo se Lea la documentación aquí.
Luego, después de analizarlo, tengo una cita. esa fecha la puse en getRelativeTimeSpanString (sin ningún parámetro adicional, estoy bien, por defecto a minutos)
Obtendrá una excepción si no descubrió la cadena de análisis correcta , algo como: excepción en el carácter 5 . Mira el carácter 5 y corrige tu cadena de análisis inicial. . Es posible que obtenga otra excepción, repita estos pasos hasta que tenga la fórmula correcta.
fuente
}
Llamada
val String = timeAgo (unixTimeStamp)
aprovechar el tiempo en Kotlin
fuente
Aquí está mi implementación Java de esto
fuente
esto funciona para mi
fuente
Este es el guión muy básico. Es fácil de improvisar.
Resultado: (Hace XXX horas) o (Hace XX días / Ayer / Hoy)
fuente
para esto que he hecho
Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years ago
en este ejemplo, puede analizar la fecha como2018-09-05T06:40:46.183Z
esta o cualquier otra como a continuaciónagregue debajo del valor en string.xml
código java intente a continuación
fuente
Puede usar la Biblioteca RelativeDateTimeFormatter de Java , hace exactamente eso:
fuente
Estoy usando Instant, Date y DateTimeUtils. Los datos (fecha) que se almacenan en la base de datos en tipo de cadena y luego se convierten en instantáneos.
fuente
Las siguientes soluciones están todas en Java puro:
Opción 1: sin redondeo y solo contenedor de tiempo más grande
La siguiente función solo mostrará el contenedor de tiempo más grande, por ejemplo, si el tiempo transcurrido verdadero es
"1 month 14 days ago"
, esta función solo se mostrará"1 month ago"
. Esta función también siempre se redondeará hacia abajo, por lo que"50 days ago"
se mostrará un tiempo equivalente a"1 month"
Opción 2: con redondeo
Simplemente envuelva el contenedor de tiempo que desea redondear con una instrucción Math.round (...), por lo que si desea redondear
50 days
a2 months
, modifiquelong months = days / 30
along months = Math.round(days / 30.0)
fuente
Duration
con susto…Part
métodos sería mucho más fácil, como se muestra en mi Respuesta .Aquí está mi caso de prueba, espero que ayude:
fuente
Calendar
clase terrible fue suplantada hace años por las modernas clases java.time con la adopción de JSR 310 . Mal consejo en 2019.var
, noval
.La función getrelativeDateTime le dará la fecha y hora como ve en la notificación de Whatsapp.
Para obtener futuras fechas y horas relativas, agréguele condiciones. Esto se crea específicamente para obtener la fecha y hora como la notificación de Whatsapp.
fuente
SimpleDateFormat
yCalendar
, sin embargo. Esas clases están mal diseñadas y anticuadas. En su lugar, lea las respuestas que emplean java.time, la API moderna de fecha y hora de Java.Por falta de simplicidad y respuesta actualizada, sigue la versión más reciente de Java 8 y posterior
Esta es la versión que utiliza la API de Java Time que intenta resolver problemas del pasado para tratar con Fecha y Hora.
Javadoc
versión 8 https://docs.oracle.com/javase/8/docs/api/index.html?java/time/package-summary.html
versión 11 https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html
Tutorial de W3Schools - https://www.w3schools.com/java/java_date.asp
Artículo de DZone: https://dzone.com/articles/java-8-date-and-time
fuente