Caso esteja trabalhando no Android, você pode usar o seguinte: android.text.format.DateUtils # getRelativeTimeSpanString ()
Somatik
Você pode, por favor, adicionar mais uma descrição à sua resposta, apenas a resposta do link não é boa por enquanto.
Ajay S
@ Somatik, se você precisar fazer isso em uma plataforma que não seja Android, poderá ver essa classe no AOSP.
precisa saber é o seguinte
@ataylor como esse uso no Android ??
Hardik Parmar
getRelativeTimeSpanString não é ideal para todas as situações e é por isso que criei minha própria classe com base em muitos exemplos aqui. Veja minha solução abaixo: stackoverflow.com/a/37042254/468360
Codeversed
67
Você já considerou a enumeração TimeUnit ? Pode ser bastante útil para esse tipo de coisa
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();}
Não acho que seja uma resposta completa, pois as unidades de tempo são independentes. Por exemplo: o tempo em milissegundos é de apenas minutos * 60 * 1000. Você precisa diminuir a partir de cada unidade de tempo a próxima unidade de tempo maior (após convertê-la na unidade de tempo inferior) para poder usá-la em um "tempo atrás" " corda.
Nativ
@ Benj - Isso certo? solução acima? porque um horário está no formato de 12 horas e outro horário no formato de 24 horas. Deixe-me saber seus comentários para minha consulta. Agradeço antecipadamente.
Swift
isso está incorreto ... cada unidade é independente uma da outra, como já mencionado.
Jonathan Laliberte 01/01
1
android faz isso por você Você está trabalhando em android você pode usar este: android.text.format.DateUtils.getRelativeTimeSpanString (milissegundos)
Wajid Ali
50
Pego as respostas RealHowTo e Ben J e faço minha própria versão:
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á o seguinte
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 legal. E é muito fácil de adicionar outras unidades de tempo, como a semana (s)
Piotr
1
este merece mais votos positivos. Primeiro de tudo, nenhuma biblioteca é necessária. Ainda é limpo, elegante e fácil de mudar.
Fangzhzh 6/10/2015
pequeno erro de digitação: dentro do seu código, você está fazendo referência às propriedades estáticas "Listas" em vez de "TimeAgo". Lists.times.get (i) deve ser TimeAgo.get (i) ... e assim por diante
Diogo Gomes
2
Pequena sugestão: use .append(temp != 1 ? "s" : "")em vez de .append(temp > 1 ? "s" : "")por causa 0 também deve ter ssufixo
Berkus
1
@ShajeelAfzal sim, o parâmetro duration está em milissegundos, mas é uma diferença entre os tempos e não um valor absoluto. O que você está recebendo é o tempo que passou desde o 01 de janeiro de 1970 a data em que o timestamp unix começou
Acabei usando uma versão revisada disso. Publiquei minhas revisões para você.
David Blevins
5
David Blevins, mais exemplos sobre PrettyTime: stackoverflow.com/questions/3859288/... Big -1 para reinventar a roda mais uma vez e não recomendando uma 3ª :-P biblioteca partido
zakmck
9
Isso se baseia na resposta do RealHowTo, por isso, se você gosta, também dê um pouco de amor a ele.
Esta versão limpa permite especificar o intervalo de tempo em que você pode estar interessado.
Ele também lida com a parte "e" um pouco diferente. Costumo descobrir que, ao unir strings a um delimitador, é mais fácil pular a lógica complicada e excluir o último delimitador quando terminar.
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
E caso alguém precise, aqui está uma classe que converterá qualquer string como a anterior em milissegundos . É bastante útil para permitir que as pessoas especifiquem tempos limite de várias coisas em texto legível.
Na maioria dos casos, você deseja uma exibição "inteligente", ou seja. em vez de 5125 minutos atrás, você diz x dias atrás.
PhiLho
7
Sobre built-in soluções:
O Java não possui nenhum suporte interno para formatação de tempos relativos, também não o Java-8 e seu novo pacote java.time . Se você só precisa de inglês e nada mais, e somente então uma solução feita à mão pode ser aceitável - veja a resposta de @RealHowTo (embora tenha a forte desvantagem de não levar em consideração o fuso horário para a tradução de deltas instantâneos para a hora local unidades!). De qualquer forma, se você deseja evitar soluções alternativas complexas criadas em casa, especialmente para outros locais, precisará de uma biblioteca externa.
Neste último caso, recomendo usar minha biblioteca Time4J (ou Time4A no Android). Oferece maior flexibilidade e mais potência i18n . A classe net.time4j.PrettyTime possui sete métodos printRelativeTime...(...)para esse fim. Exemplo usando um relógio de teste como fonte de tempo:
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)
Outro exemplo usando java.time.Instantcomo entrada:
String relativeTime =PrettyTime.of(Locale.ENGLISH).printRelativeInStdTimezone(Moment.from(Instant.EPOCH));System.out.println(relativeTime);// 45 years ago
Essa biblioteca suporta, por meio de sua versão mais recente (v4.17), 80 idiomas e também alguns códigos de idioma específicos do país (especialmente para espanhol, inglês, árabe, francês). Os dados do i18n são baseados principalmente na versão mais recente do CLDR v29 . Outras razões importantes para usar esta biblioteca são um bom suporte para regras plurais (que geralmente são diferentes do inglês em outros locais), estilo de formato abreviado (por exemplo: "1 segundo atrás") e maneiras expressivas de levar em consideração os fusos horários . O Time4J está ciente de detalhes exóticos, como segundos bissextos nos cálculos de tempos relativos (não é realmente importante, mas forma uma mensagem relacionada ao horizonte de expectativa). A compatibilidade com Java-8existe devido a métodos de conversão facilmente disponíveis para tipos como java.time.Instantou java.time.Period.
Existem desvantagens? Só dois.
A biblioteca não é pequena (também por causa de seu grande repositório de dados i18n).
A API não é bem conhecida; portanto, o conhecimento e o suporte da comunidade ainda não estão disponíveis. Caso contrário, a documentação fornecida é bastante detalhada e abrangente.
Alternativas (compactas):
Se você procura uma solução menor e não precisa de tantos recursos e está disposto a tolerar possíveis problemas de qualidade relacionados aos dados i18n, então:
Eu recomendaria o ocpsoft / PrettyTime (suporte para 32 idiomas (em breve 34?)), Adequado apenas para trabalhos java.util.Date- veja a resposta de @ataylor). O CLDR padrão do setor (do consórcio Unicode), com seu grande histórico na comunidade, não é, infelizmente, uma base dos dados i18n, de modo que outras melhorias ou aprimoramentos de dados podem demorar um pouco ...
Se você está no Android, a classe auxiliar android.text.format.DateUtils é uma alternativa embutida (veja outros comentários e respostas aqui, com a desvantagem de que não há suporte por anos e meses. E tenho certeza de que apenas muito poucas pessoas gostam do estilo API desta classe auxiliar.
Se você é fã do Joda-Time , pode ver a classe PeriodFormat (suporte para 14 idiomas na versão v2.9.4, por outro lado: o Joda-Time certamente também não é compacto, por isso mencionei aqui apenas para completude). Esta biblioteca não é uma resposta real porque os tempos relativos não são suportados. Você precisará anexar o literal "atrás" pelo menos (e remover manualmente todas as unidades inferiores dos formatos de lista gerados - estranho). Ao contrário do Time4J ou do Android-DateUtils, ele não possui suporte especial para abreviações ou alternância automática de tempos relativos para representações de tempo absoluto. Como o PrettyTime, é totalmente dependente das contribuições não confirmadas de membros privados da comunidade Java para seus dados i18n.
Se você estiver procurando por um simples "Hoje", "Ontem" ou "x dias atrás".
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 a estrutura java.time incorporada no Java 8 e 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");
Esses Durationmétodos relatam a duração inteira como um número total de horas e como um número total de minutos. No Java 8, estranhamente, a classe não possuía métodos para obter cada parte de hora, minutos e segundos. O Java 9 traz esses métodos to…Part,.
Caso você esteja desenvolvendo um aplicativo para Android, ele fornece a classe de utilitário DateUtils para todos esses requisitos. Dê uma olhada no DateUtils # getRelativeTimeSpanString () método utilitário .
Dos documentos para
CharSequence getRelativeTimeSpanString (muito tempo, muito tempo, muito tempo minResolution)
Retorna uma string descrevendo 'time' como um horário relativo a 'now'. Os intervalos de tempo no passado são formatados como "42 minutos atrás". Os intervalos de tempo no futuro são formatados como "Em 42 minutos".
Você vai estar passando o seu timestampcomo tempo e System.currentTimeMillis()como agora . O minResolutionpermite especificar o período de tempo mínimo para relatar.
Por exemplo, um tempo de 3 segundos no passado será relatado como "0 minutos atrás" se estiver definido como MINUTE_IN_MILLIS. Passe um dos 0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, WEEK_IN_MILLIS etc.
Este é um código melhor se considerarmos o desempenho. Reduz o número de cálculos.
Motivo
Minutos são calculados apenas se o número de segundos for maior que 60 e Horas são calculados apenas se o número de minutos for maior que 60 e assim por diante ...
Para um período de tempo independente da linha do tempo na escala de anos-meses-dias, use Period. Para os dias que significam intervalos de 24 horas não relacionados ao calendário e horas-minutos-segundos, use Duration. Misturar as duas escalas raramente faz sentido.
Duration
Comece buscando o momento atual, como visto em UTC , usando a 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 );
Gere texto por horas, minutos e segundos.
// Generate text by calling `to…Part` methods.String output = d.toHoursPart()+" hours ago\n"+ d.toMinutesPart()+" minutes ago\n"+ d.toSecondsPart()+" seconds ago";
Despejar no console.
System.out.println("From: "+ then +" to: "+ now );System.out.println( output );
De: 2019-06-04T11: 53: 55.714965Z a: 2019-06-04T20: 02: 03.714965Z
8 horas atrás
8 minutos atrás
8 segundos atrás
Period
Comece obtendo a data atual.
Um fuso horário é crucial para determinar uma data. Por um determinado momento, a data varia em todo o mundo por zona. Por exemplo, alguns minutos depois da meia-noite em Paris, a França é um novo dia, enquanto ainda "ontem" em Montreal, Quebec .
Se nenhum fuso horário for especificado, a JVM aplicará implicitamente seu fuso horário padrão atual. Esse padrão pode mudar a qualquer momento durante o tempo de execução (!), Portanto, seus resultados podem variar. Melhor especificar explicitamente o fuso horário desejado / esperado como argumento. Se crítico, confirme a zona com seu usuário.
Especifique um nome próprio fuso horário no formato Continent/Region, como America/Montreal, Africa/Casablanca, ou Pacific/Auckland. Nunca use o 2-4 letras, como ESTou ISTcomo eles são não zonas verdadeiros tempo, não padronizados, e nem mesmo única (!).
ZoneId z =ZoneId.of("America/Montreal");LocalDate today =LocalDate.now( z );
Recrie uma data há oito dias, meses e anos.
LocalDate then = today.minusYears(8).minusMonths(8).minusDays(7);// Notice the 7 days, not 8, because of granularity of months.
Calcular o tempo decorrido.
Period p =Period.between( then , today );
Construa a sequência de peças "tempo atrás".
String output = p.getDays()+" days ago\n"+ p.getMonths()+" months ago\n"+ p.getYears()+" years ago";
Despejar no console.
System.out.println("From: "+ then +" to: "+ today );System.out.println( output );
Você pode trocar objetos java.time diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade dejava.sql.* classes.
O projeto ThreeTen-Extra estende java.time com classes adicionais. Este projeto é um campo de prova para possíveis adições futuras ao java.time. Você pode encontrar algumas classes úteis aqui, como Interval, YearWeek, YearQuarter, e mais .
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;}}
Depois de analisá-lo, encontro um encontro. nessa data que coloquei no getRelativeTimeSpanString (sem nenhum parâmetro adicional, tudo bem para mim, por padrão, em minutos)
Você receberá uma exceção se não descobrir a String de análise correta , algo como: exceção no caractere 5 . Observe o caractere 5 e corrija sua seqüência de análise inicial. . Você pode receber outra exceção, repita essas etapas até ter a fórmula correta.
Este é o script muito básico. é fácil de improvisar.
Resultado: (XXX horas atrás) ou (XX dias atrás / ontem / hoje)
<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>
por isso eu fiz Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years agoneste exemplo, você pode analisar a data como 2018-09-05T06:40:46.183Zesta ou qualquer outra como abaixo
Essa é uma biblioteca Android, não uma biblioteca Java.
Madbreaks
0
Estou usando o Instant, Date e DateTimeUtils. Os dados (data) armazenados no banco de dados no tipo String e convertidos para se tornar Instantâneo.
/*
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;}
Opção 1: sem arredondamento e apenas o maior contêiner de tempo
A função a seguir exibirá apenas o maior contêiner de tempo, por exemplo, se o tempo decorrido verdadeiro for "1 month 14 days ago", essa função será exibida apenas "1 month ago". Essa função também sempre será arredondada para baixo; portanto, um tempo equivalente a "50 days ago"será exibido como"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";}
Opção 2: Com arredondamento
Basta agrupar o contêiner de tempo que você deseja arredondar com uma instrução Math.round (...); portanto, se você quiser arredondar 50 dayspara 2 months, modifique long months = days / 30paralong months = Math.round(days / 30.0)
Usar Durationcom seus to…Partmétodos seria muito mais fácil, como mostrado na minha resposta .
Basil Bourque
0
Aqui está o meu caso de teste, espero que ajude:
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"}
A Calendarclasse terrível foi substituída anos atrás pelas modernas classes java.time com a adoção do JSR 310 . Má orientação em 2019.
Basil Bourque
Você deve ter pensado var, não val.
Basil Bourque
0
A função getrelativeDateTime fornecerá a data e a hora que você vê na notificação do Whatsapp.
Para obter data e hora relativa futura, adicione condições. Isso é criado especificamente para obter a Data e Hora como a notificação do Whatsapp.
Obrigado por querer contribuir. Não foi exatamente o que foi pedido, mas talvez alguém possa usá-lo. Nem que alguém nem mais ninguém queira usar SimpleDateFormate Calendar, no entanto. Essas classes são mal projetadas e desatualizadas há muito tempo. Em vez disso, leia as respostas que estão empregando java.time, a moderna API de data e hora de Java.
Ole VV
0
Por falta de simplicidade e resposta atualizada, segue a versão mais recente do Java 8 e posterior
Respostas:
Dê uma olhada na biblioteca PrettyTime .
É bastante simples de usar:
Você também pode passar em um código de idioma para mensagens internacionalizadas:
Conforme observado nos comentários, o Android tem essa funcionalidade incorporada à
android.text.format.DateUtils
classe.fonte
Você já considerou a enumeração TimeUnit ? Pode ser bastante útil para esse tipo de coisa
fonte
Pego as respostas RealHowTo e Ben J e faço minha própria versão:
que imprimirá o seguinte
fonte
.append(temp != 1 ? "s" : "")
em vez de.append(temp > 1 ? "s" : "")
por causa 0 também deve ters
sufixomais @ Formate uma duração em milissegundos em um formato legível por humanos
fonte
Isso se baseia na resposta do RealHowTo, por isso, se você gosta, também dê um pouco de amor a ele.
Esta versão limpa permite especificar o intervalo de tempo em que você pode estar interessado.
Ele também lida com a parte "e" um pouco diferente. Costumo descobrir que, ao unir strings a um delimitador, é mais fácil pular a lógica complicada e excluir o último delimitador quando terminar.
Pouco código para dar um giro:
Que produzirá o seguinte:
E caso alguém precise, aqui está uma classe que converterá qualquer string como a anterior em milissegundos . É bastante útil para permitir que as pessoas especifiquem tempos limite de várias coisas em texto legível.
fonte
existe uma maneira simples de fazer isso:
digamos que você queira o tempo há 20 minutos:
é isso aí..
fonte
Sobre built-in soluções:
O Java não possui nenhum suporte interno para formatação de tempos relativos, também não o Java-8 e seu novo pacote
java.time
. Se você só precisa de inglês e nada mais, e somente então uma solução feita à mão pode ser aceitável - veja a resposta de @RealHowTo (embora tenha a forte desvantagem de não levar em consideração o fuso horário para a tradução de deltas instantâneos para a hora local unidades!). De qualquer forma, se você deseja evitar soluções alternativas complexas criadas em casa, especialmente para outros locais, precisará de uma biblioteca externa.Neste último caso, recomendo usar minha biblioteca Time4J (ou Time4A no Android). Oferece maior flexibilidade e mais potência i18n . A classe net.time4j.PrettyTime possui sete métodos
printRelativeTime...(...)
para esse fim. Exemplo usando um relógio de teste como fonte de tempo:Outro exemplo usando
java.time.Instant
como entrada:Essa biblioteca suporta, por meio de sua versão mais recente (v4.17), 80 idiomas e também alguns códigos de idioma específicos do país (especialmente para espanhol, inglês, árabe, francês). Os dados do i18n são baseados principalmente na versão mais recente do CLDR v29 . Outras razões importantes para usar esta biblioteca são um bom suporte para regras plurais (que geralmente são diferentes do inglês em outros locais), estilo de formato abreviado (por exemplo: "1 segundo atrás") e maneiras expressivas de levar em consideração os fusos horários . O Time4J está ciente de detalhes exóticos, como segundos bissextos nos cálculos de tempos relativos (não é realmente importante, mas forma uma mensagem relacionada ao horizonte de expectativa). A compatibilidade com Java-8existe devido a métodos de conversão facilmente disponíveis para tipos como
java.time.Instant
oujava.time.Period
.Existem desvantagens? Só dois.
Alternativas (compactas):
Se você procura uma solução menor e não precisa de tantos recursos e está disposto a tolerar possíveis problemas de qualidade relacionados aos dados i18n, então:
Eu recomendaria o ocpsoft / PrettyTime (suporte para 32 idiomas (em breve 34?)), Adequado apenas para trabalhos
java.util.Date
- veja a resposta de @ataylor). O CLDR padrão do setor (do consórcio Unicode), com seu grande histórico na comunidade, não é, infelizmente, uma base dos dados i18n, de modo que outras melhorias ou aprimoramentos de dados podem demorar um pouco ...Se você está no Android, a classe auxiliar android.text.format.DateUtils é uma alternativa embutida (veja outros comentários e respostas aqui, com a desvantagem de que não há suporte por anos e meses. E tenho certeza de que apenas muito poucas pessoas gostam do estilo API desta classe auxiliar.
Se você é fã do Joda-Time , pode ver a classe PeriodFormat (suporte para 14 idiomas na versão v2.9.4, por outro lado: o Joda-Time certamente também não é compacto, por isso mencionei aqui apenas para completude). Esta biblioteca não é uma resposta real porque os tempos relativos não são suportados. Você precisará anexar o literal "atrás" pelo menos (e remover manualmente todas as unidades inferiores dos formatos de lista gerados - estranho). Ao contrário do Time4J ou do Android-DateUtils, ele não possui suporte especial para abreviações ou alternância automática de tempos relativos para representações de tempo absoluto. Como o PrettyTime, é totalmente dependente das contribuições não confirmadas de membros privados da comunidade Java para seus dados i18n.
fonte
Se você estiver procurando por um simples "Hoje", "Ontem" ou "x dias atrás".
fonte
java.time
Usando a estrutura java.time incorporada no Java 8 e posterior.
fonte
Duration
métodos relatam a duração inteira como um número total de horas e como um número total de minutos. No Java 8, estranhamente, a classe não possuía métodos para obter cada parte de hora, minutos e segundos. O Java 9 traz esses métodosto…Part
,.Criei uma porta Java timeago simples do plug-in jquery-timeago que faz o que você está solicitando.
fonte
Caso você esteja desenvolvendo um aplicativo para Android, ele fornece a classe de utilitário DateUtils para todos esses requisitos. Dê uma olhada no DateUtils # getRelativeTimeSpanString () método utilitário .
Dos documentos para
CharSequence getRelativeTimeSpanString (muito tempo, muito tempo, muito tempo minResolution)
Você vai estar passando o seu
timestamp
como tempo eSystem.currentTimeMillis()
como agora . OminResolution
permite especificar o período de tempo mínimo para relatar.fonte
Você pode usar esta função para calcular o tempo atrás
1) Aqui time_ago está em microssegundo
fonte
Com base em várias respostas aqui, criei o seguinte para o meu caso de uso.
Exemplo de uso:
fonte
O pacote joda-time , tem a noção de Períodos . Você pode fazer aritmética com períodos e data e hora.
Dos documentos :
fonte
Não é bonito ... mas o mais próximo que consigo pensar é usar o Joda-Time (como descrito neste post: Como calcular o tempo decorrido a partir de agora com o Joda Time?
fonte
Este é um código melhor se considerarmos o desempenho. Reduz o número de cálculos. Motivo Minutos são calculados apenas se o número de segundos for maior que 60 e Horas são calculados apenas se o número de minutos for maior que 60 e assim por diante ...
fonte
java.time
A resposta de Habsq tem a idéia certa, mas os métodos errados.
Para um período de tempo independente da linha do tempo na escala de anos-meses-dias, use
Period
. Para os dias que significam intervalos de 24 horas não relacionados ao calendário e horas-minutos-segundos, useDuration
. Misturar as duas escalas raramente faz sentido.Duration
Comece buscando o momento atual, como visto em UTC , usando a
Instant
classeGere texto por horas, minutos e segundos.
Despejar no console.
Period
Comece obtendo a data atual.
Um fuso horário é crucial para determinar uma data. Por um determinado momento, a data varia em todo o mundo por zona. Por exemplo, alguns minutos depois da meia-noite em Paris, a França é um novo dia, enquanto ainda "ontem" em Montreal, Quebec .
Se nenhum fuso horário for especificado, a JVM aplicará implicitamente seu fuso horário padrão atual. Esse padrão pode mudar a qualquer momento durante o tempo de execução (!), Portanto, seus resultados podem variar. Melhor especificar explicitamente o fuso horário desejado / esperado como argumento. Se crítico, confirme a zona com seu usuário.
Especifique um nome próprio fuso horário no formato
Continent/Region
, comoAmerica/Montreal
,Africa/Casablanca
, ouPacific/Auckland
. Nunca use o 2-4 letras, comoEST
ouIST
como eles são não zonas verdadeiros tempo, não padronizados, e nem mesmo única (!).Recrie uma data há oito dias, meses e anos.
Calcular o tempo decorrido.
Construa a sequência de peças "tempo atrás".
Despejar no console.
Sobre java.time
A estrutura java.time é integrada ao Java 8 e posterior. Essas classes suplantar os velhos problemáticos legados aulas de data e hora, como
java.util.Date
,Calendar
, eSimpleDateFormat
.Para saber mais, consulte o Tutorial do Oracle . E procure Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .
O projeto Joda-Time , agora em modo de manutenção , aconselha a migração para as classes java.time .
Você pode trocar objetos java.time diretamente com seu banco de dados. Use um driver JDBC compatível com JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade de
java.sql.*
classes.Onde obter as classes java.time?
O projeto ThreeTen-Extra estende java.time com classes adicionais. Este projeto é um campo de prova para possíveis adições futuras ao java.time. Você pode encontrar algumas classes úteis aqui, como
Interval
,YearWeek
,YearQuarter
, e mais .fonte
Após uma longa pesquisa, encontrei isso.
fonte
Para Android Exatamente como Ravi disse, mas como muitas pessoas querem apenas copiar e colar, a coisa aqui está.
Explicação para pessoas que têm mais tempo
Ex. Eu recebo os dados de um servidor no formato Wed, 27 Jan 2016 09:32:35 GMT [este provavelmente não é o seu caso]
isso é traduzido para
Formatador SimpleDateFormat = novo SimpleDateFormat ("EEE, dd MMM aaaa HH: mm: ss Z");
como eu sei disso? Leia a documentação aqui.
Depois de analisá-lo, encontro um encontro. nessa data que coloquei no getRelativeTimeSpanString (sem nenhum parâmetro adicional, tudo bem para mim, por padrão, em minutos)
Você receberá uma exceção se não descobrir a String de análise correta , algo como: exceção no caractere 5 . Observe o caractere 5 e corrija sua seqüência de análise inicial. . Você pode receber outra exceção, repita essas etapas até ter a fórmula correta.
fonte
}
Ligar
val String = timeAgo (unixTimeStamp)
para obter o tempo atrás em Kotlin
fonte
Aqui está minha implementação Java deste
fonte
funciona para mim
fonte
Este é o script muito básico. é fácil de improvisar.
Resultado: (XXX horas atrás) ou (XX dias atrás / ontem / hoje)
fonte
por isso eu fiz
Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years ago
neste exemplo, você pode analisar a data como2018-09-05T06:40:46.183Z
esta ou qualquer outra como abaixoadicione valor abaixo em string.xml
código java tente abaixo
fonte
Você pode usar a Biblioteca RelativeDateTimeFormatter do Java , faz exatamente isso:
fonte
Estou usando o Instant, Date e DateTimeUtils. Os dados (data) armazenados no banco de dados no tipo String e convertidos para se tornar Instantâneo.
fonte
As seguintes soluções estão todas em Java puro:
Opção 1: sem arredondamento e apenas o maior contêiner de tempo
A função a seguir exibirá apenas o maior contêiner de tempo, por exemplo, se o tempo decorrido verdadeiro for
"1 month 14 days ago"
, essa função será exibida apenas"1 month ago"
. Essa função também sempre será arredondada para baixo; portanto, um tempo equivalente a"50 days ago"
será exibido como"1 month"
Opção 2: Com arredondamento
Basta agrupar o contêiner de tempo que você deseja arredondar com uma instrução Math.round (...); portanto, se você quiser arredondar
50 days
para2 months
, modifiquelong months = days / 30
paralong months = Math.round(days / 30.0)
fonte
Duration
com seusto…Part
métodos seria muito mais fácil, como mostrado na minha resposta .Aqui está o meu caso de teste, espero que ajude:
fonte
Calendar
classe terrível foi substituída anos atrás pelas modernas classes java.time com a adoção do JSR 310 . Má orientação em 2019.var
, nãoval
.A função getrelativeDateTime fornecerá a data e a hora que você vê na notificação do Whatsapp.
Para obter data e hora relativa futura, adicione condições. Isso é criado especificamente para obter a Data e Hora como a notificação do Whatsapp.
fonte
SimpleDateFormat
eCalendar
, no entanto. Essas classes são mal projetadas e desatualizadas há muito tempo. Em vez disso, leia as respostas que estão empregando java.time, a moderna API de data e hora de Java.Por falta de simplicidade e resposta atualizada, segue a versão mais recente do Java 8 e posterior
Esta é a versão que usa a Java Time API que tenta resolver problemas do passado para lidar com Data e Hora.
Javadoc
versão 8 https://docs.oracle.com/javase/8/docs/api/index.html?java/time/package-summary.html
versão 11 https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html
Tutorial do W3Schools - https://www.w3schools.com/java/java_date.asp
Artigo da DZone - https://dzone.com/articles/java-8-date-and-time
fonte