Como calcular o "tempo atrás" em Java?


127

No Ruby on Rails, existe um recurso que permite que você pegue qualquer Data e imprima há quanto tempo ela foi.

Por exemplo:

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

Existe uma maneira fácil de fazer isso em Java?


1
Veja: stackoverflow.com/questions/11/how-do-i-calculate-relative-time É C #, mas tenho certeza que você pode convertê-lo com pequenos problemas.
Brandon

Respostas:


177

Dê uma olhada na biblioteca PrettyTime .

É bastante simples de usar:

import org.ocpsoft.prettytime.PrettyTime;

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

Você também pode passar em um código de idioma para mensagens internacionalizadas:

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

Conforme observado nos comentários, o Android tem essa funcionalidade incorporada à android.text.format.DateUtilsclasse.


229
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 = new SimpleDateFormat("dd/MM/yyyy");
        Date past = format.parse("01/10/2010");
        Date now = new Date();

        System.out.println(TimeUnit.MILLISECONDS.toMillis(now.getTime() - past.getTime()) + " milliseconds ago");
        System.out.println(TimeUnit.MILLISECONDS.toMinutes(now.getTime() - past.getTime()) + " minutes ago");
        System.out.println(TimeUnit.MILLISECONDS.toHours(now.getTime() - past.getTime()) + " hours ago");
        System.out.println(TimeUnit.MILLISECONDS.toDays(now.getTime() - past.getTime()) + " days ago");
    }
    catch (Exception j){
        j.printStackTrace();
    }

4
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:

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á 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
Riccardo Casatta

42
  public class TimeUtils {

      public final static long ONE_SECOND = 1000;
      public final static long SECONDS = 60;

      public final static long ONE_MINUTE = ONE_SECOND * 60;
      public final static long MINUTES = 60;

      public final static long ONE_HOUR = ONE_MINUTE * 60;
      public final static long HOURS = 24;

      public final static long ONE_DAY = ONE_HOUR * 24;

      private TimeUtils() {
      }

      /**
       * converts time (in milliseconds) to human-readable format
       *  "<w> days, <x> hours, <y> minutes and (z) seconds"
       */
      public static String millisToLongDHMS(long duration) {
        StringBuffer res = new StringBuffer();
        long temp = 0;
        if (duration >= ONE_SECOND) {
          temp = duration / ONE_DAY;
          if (temp > 0) {
            duration -= temp * ONE_DAY;
            res.append(temp).append(" day").append(temp > 1 ? "s" : "")
               .append(duration >= ONE_MINUTE ? ", " : "");
          }

          temp = duration / ONE_HOUR;
          if (temp > 0) {
            duration -= temp * ONE_HOUR;
            res.append(temp).append(" hour").append(temp > 1 ? "s" : "")
               .append(duration >= ONE_MINUTE ? ", " : "");
          }

          temp = duration / ONE_MINUTE;
          if (temp > 0) {
            duration -= temp * ONE_MINUTE;
            res.append(temp).append(" minute").append(temp > 1 ? "s" : "");
          }

          if (!res.toString().equals("") && duration >= ONE_SECOND) {
            res.append(" and ");
          }

          temp = duration / ONE_SECOND;
          if (temp > 0) {
            res.append(temp).append(" second").append(temp > 1 ? "s" : "");
          }
          return res.toString();
        } else {
          return "0 second";
        }
      }


      public static void main(String args[]) {
        System.out.println(millisToLongDHMS(123));
        System.out.println(millisToLongDHMS((5 * ONE_SECOND) + 123));
        System.out.println(millisToLongDHMS(ONE_DAY + ONE_HOUR));
        System.out.println(millisToLongDHMS(ONE_DAY + 2 * ONE_SECOND));
        System.out.println(millisToLongDHMS(ONE_DAY + ONE_HOUR + (2 * ONE_MINUTE)));
        System.out.println(millisToLongDHMS((4 * ONE_DAY) + (3 * ONE_HOUR)
            + (2 * ONE_MINUTE) + ONE_SECOND));
        System.out.println(millisToLongDHMS((5 * ONE_DAY) + (4 * ONE_HOUR)
            + ONE_MINUTE + (23 * ONE_SECOND) + 123));
        System.out.println(millisToLongDHMS(42 * ONE_DAY));
        /*
          output :
                0 second
                5 seconds
                1 day, 1 hour
                1 day and 2 seconds
                1 day, 1 hour, 2 minutes
                4 days, 3 hours, 2 minutes and 1 second
                5 days, 4 hours, 1 minute and 23 seconds
                42 days
         */
    }
}

mais @ Formate uma duração em milissegundos em um formato legível por humanos


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

Pouco código para dar um 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));
        }
    }

}

Que produzirá o seguinte:

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.


9

existe uma maneira simples de fazer isso:

digamos que você queira o tempo há 20 minutos:

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

é isso aí..


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

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.


5

Se você estiver procurando por um simples "Hoje", "Ontem" ou "x dias 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";
}

5

java.time

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

1
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,.
Basil Bourque 12/04

4

Criei uma porta Java timeago simples do plug-in jquery-timeago que faz o que você está solicitando.

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

4

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.


4

Você pode usar esta função para calcular o tempo atrás

 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) Aqui time_ago está em microssegundo


4

Com base em várias respostas aqui, criei o seguinte para o meu caso de uso.

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

É muito útil, muito obrigado.
Haya Akkad

3

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 :

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


2

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

class timeAgo {

static String getTimeAgo(long time_ago) {
    time_ago=time_ago/1000;
    long cur_time = (Calendar.getInstance().getTimeInMillis())/1000 ;
    long time_elapsed = cur_time - time_ago;
    long seconds = time_elapsed;
   // Seconds
    if (seconds <= 60) {
        return "Just now";
    }
    //Minutes
    else{
        int minutes = Math.round(time_elapsed / 60);

        if (minutes <= 60) {
            if (minutes == 1) {
                return "a minute ago";
            } else {
                return minutes + " minutes ago";
            }
        }
        //Hours
        else {
            int hours = Math.round(time_elapsed / 3600);
            if (hours <= 24) {
                if (hours == 1) {
                    return "An hour ago";
                } else {
                    return hours + " hrs ago";
                }
            }
            //Days
            else {
                int days = Math.round(time_elapsed / 86400);
                if (days <= 7) {
                    if (days == 1) {
                        return "Yesterday";
                    } else {
                        return days + " days ago";
                    }
                }
                //Weeks
                else {
                    int weeks = Math.round(time_elapsed / 604800);
                    if (weeks <= 4.3) {
                        if (weeks == 1) {
                            return "A week ago";
                        } else {
                            return weeks + " weeks ago";
                        }
                    }
                    //Months
                    else {
                        int months = Math.round(time_elapsed / 2600640);
                        if (months <= 12) {
                            if (months == 1) {
                                return "A month ago";
                            } else {
                                return months + " months ago";
                            }
                        }
                        //Years
                        else {
                            int years = Math.round(time_elapsed / 31207680);
                            if (years == 1) {
                                return "One year ago";
                            } else {
                                return years + " years ago";
                            }
                        }
                    }
                }
            }
        }
    }

}

}

1
Você está trabalhando em android você pode usar este: android.text.format.DateUtils.getRelativeTimeSpanString (milissegundos)
Wajid Ali

2

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

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

8 dias atrás

8 meses atrás

8 anos atrás


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, e SimpleDateFormat.

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 dejava.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 .


Muito obrigado!
Ticherhaz 5/06/19

1

Após uma longa pesquisa, encontrei isso.

    public class GetTimeLapse {
    public static String getlongtoago(long createdAt) {
        DateFormat userDateFormat = new SimpleDateFormat("E MMM dd HH:mm:ss Z yyyy");
        DateFormat dateFormatNeeded = new SimpleDateFormat("MM/dd/yyyy HH:MM:SS");
        Date date = null;
        date = new Date(createdAt);
        String crdate1 = dateFormatNeeded.format(date);

        // Date Calculation
        DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        crdate1 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(date);

        // get current date time with Calendar()
        Calendar cal = Calendar.getInstance();
        String currenttime = dateFormat.format(cal.getTime());

        Date CreatedAt = null;
        Date current = null;
        try {
            CreatedAt = dateFormat.parse(crdate1);
            current = dateFormat.parse(currenttime);
        } catch (java.text.ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // Get msec from each, and subtract.
        long diff = current.getTime() - CreatedAt.getTime();
        long diffSeconds = diff / 1000;
        long diffMinutes = diff / (60 * 1000) % 60;
        long diffHours = diff / (60 * 60 * 1000) % 24;
        long diffDays = diff / (24 * 60 * 60 * 1000);

        String time = null;
        if (diffDays > 0) {
            if (diffDays == 1) {
                time = diffDays + "day ago ";
            } else {
                time = diffDays + "days ago ";
            }
        } else {
            if (diffHours > 0) {
                if (diffHours == 1) {
                    time = diffHours + "hr ago";
                } else {
                    time = diffHours + "hrs ago";
                }
            } else {
                if (diffMinutes > 0) {
                    if (diffMinutes == 1) {
                        time = diffMinutes + "min ago";
                    } else {
                        time = diffMinutes + "mins ago";
                    }
                } else {
                    if (diffSeconds > 0) {
                        time = diffSeconds + "secs ago";
                    }
                }

            }

        }
        return time;
    }
}

1

Para Android Exatamente como Ravi disse, mas como muitas pessoas querem apenas copiar e colar, a coisa aqui 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("");
    }

Explicação para pessoas que têm mais tempo

  1. Você obtém os dados de algum lugar. Primeiro você precisa descobrir o formato.

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.


1
private const val SECOND_MILLIS = 1
private const val MINUTE_MILLIS = 60 * SECOND_MILLIS
private const val HOUR_MILLIS = 60 * MINUTE_MILLIS
private const val DAY_MILLIS = 24 * HOUR_MILLIS

object TimeAgo {

fun timeAgo(time: Int): String {

    val now = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())
    if (time > now || time <= 0) {
        return "in the future"
    }

    val diff = now - time
    return when {
        diff < MINUTE_MILLIS -> "Just now"
        diff < 2 * MINUTE_MILLIS -> "a minute ago"
        diff < 60 * MINUTE_MILLIS -> "${diff / MINUTE_MILLIS} minutes ago"
        diff < 2 * HOUR_MILLIS -> "an hour ago"
        diff < 24 * HOUR_MILLIS -> "${diff / HOUR_MILLIS} hours ago"
        diff < 48 * HOUR_MILLIS -> "yesterday"
        else -> "${diff / DAY_MILLIS} days ago"
    }
}

}

Ligar

val String = timeAgo (unixTimeStamp)

para obter o tempo atrás em Kotlin


0

Aqui está minha implementação Java deste

    public static String relativeDate(Date date){
    Date now=new Date();
    if(date.before(now)){
    int days_passed=(int) TimeUnit.MILLISECONDS.toDays(now.getTime() - date.getTime());
    if(days_passed>1)return days_passed+" days ago";
    else{
        int hours_passed=(int) TimeUnit.MILLISECONDS.toHours(now.getTime() - date.getTime());
        if(hours_passed>1)return days_passed+" hours ago";
        else{
            int minutes_passed=(int) TimeUnit.MILLISECONDS.toMinutes(now.getTime() - date.getTime());
            if(minutes_passed>1)return minutes_passed+" minutes ago";
            else{
                int seconds_passed=(int) TimeUnit.MILLISECONDS.toSeconds(now.getTime() - date.getTime());
                return seconds_passed +" seconds ago";
            }
        }
    }

    }
    else
    {
        return new SimpleDateFormat("HH:mm:ss MM/dd/yyyy").format(date).toString();
    }
  }

0

funciona para mim

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 é 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 = new Date('2017/6/9 00:01'); 
var now = new Date();
var difference = now.getTime() - postTime.getTime();
var minutes = Math.round(difference/60000);
var hours = Math.round(minutes/60);
var days = Math.round(hours/24);

var result;
if (days < 1) {
result = "Today";
} else if (days < 2) {
result = "Yesterday";
} else {
result = days + " Days ago";
}

document.getElementById("hourpost").innerHTML = hours + "Hours Ago" ;
document.getElementById("daypost").innerHTML = result ;
</script>

0

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

adicione valor abaixo em string.xml

  <string name="lbl_justnow">Just Now</string>
    <string name="lbl_seconds_ago">seconds ago</string>
    <string name="lbl_min_ago">min ago</string>
    <string name="lbl_mins_ago">mins ago</string>
    <string name="lbl_hr_ago">hr ago</string>
    <string name="lbl_hrs_ago">hrs ago</string>
    <string name="lbl_day_ago">day ago</string>
    <string name="lbl_days_ago">days ago</string>
    <string name="lbl_lstweek_ago">last week</string>
    <string name="lbl_week_ago">weeks ago</string>
    <string name="lbl_onemonth_ago">1 month ago</string>
    <string name="lbl_month_ago">months ago</string>
    <string name="lbl_oneyear_ago" >last year</string>
    <string name="lbl_year_ago" >years ago</string>

código java tente abaixo

  public String getFormatDate(String postTime1) {
        Calendar cal=Calendar.getInstance();
        Date now=cal.getTime();
        String disTime="";
        try {
            Date postTime;
            //2018-09-05T06:40:46.183Z
            postTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(postTime1);

            long diff=(now.getTime()-postTime.getTime()+18000)/1000;

            //for months
            Calendar calObj = Calendar.getInstance();
            calObj.setTime(postTime);
            int m=calObj.get(Calendar.MONTH);
            calObj.setTime(now);

            SimpleDateFormat monthFormatter = new SimpleDateFormat("MM"); // output month

            int mNow = Integer.parseInt(monthFormatter.format(postTime));

            diff = diff-19800;

            if(diff<15) { //below 15 sec

                disTime = getResources().getString(R.string.lbl_justnow);
            } else if(diff<60) {

                //below 1 min
                disTime= diff+" "+getResources().getString(R.string.lbl_seconds_ago);
            } else if(diff<3600) {//below 1 hr

                // convert min
                long temp=diff/60;

                if(temp==1) {
                    disTime= temp + " " +getResources().getString(R.string.lbl_min_ago);
                } else {
                    disTime = temp  + " " +getResources().getString(R.string.lbl_mins_ago);
                }
            } else if(diff<(24*3600)) {// below 1 day

                // convert hr
                long temp= diff/3600;
                System.out.println("hey temp3:"+temp);
                if(temp==1) {
                    disTime = temp  + " " +getResources().getString(R.string.lbl_hr_ago);
                } else {
                    disTime = temp + " " +getResources().getString(R.string.lbl_hrs_ago);
                }
            } else if(diff<(24*3600*7)) {// below week

                // convert days
                long temp=diff/(3600*24);
                if (temp==1) {
                    //  disTime = "\nyesterday";
                    disTime = temp + " " +getResources().getString(R.string.lbl_day_ago);
                } else {
                    disTime = temp + " " +getResources().getString(R.string.lbl_days_ago);
                }
            } else if(diff<((24*3600*28))) {// below month

                // convert week
                long temp=diff/(3600*24*7);
                if (temp <= 4) {

                    if (temp < 1) {
                        disTime = getResources().getString(R.string.lbl_lstweek_ago);
                    }else{
                        disTime = temp + " " + getResources().getString(R.string.lbl_week_ago);
                    }

                } else {
                    int diffMonth = mNow - m;
                    Log.e("count : ", String.valueOf(diffMonth));
                    disTime = diffMonth + " " + getResources().getString(R.string.lbl_month_ago);
                }
            }else if(diff<((24*3600*365))) {// below year

                // convert month
                long temp=diff/(3600*24*30);

                System.out.println("hey temp2:"+temp);
                if (temp <= 12) {

                    if (temp == 1) {
                        disTime = getResources().getString(R.string.lbl_onemonth_ago);
                    }else{
                        disTime = temp + " " + getResources().getString(R.string.lbl_month_ago);
                    }
                }

            }else if(diff>((24*3600*365))) { // above year

                // convert year
                long temp=diff/(3600*24*30*12);

                System.out.println("hey temp8:"+temp);

                if (temp == 1) {
                    disTime = getResources().getString(R.string.lbl_oneyear_ago);
                }else{
                    disTime = temp + " " + getResources().getString(R.string.lbl_year_ago);
                }
            }

        } catch(Exception e) {
            e.printStackTrace();
        }

        return disTime;
    }

Você está trabalhando em android você pode usar este: android.text.format.DateUtils.getRelativeTimeSpanString (milissegundos)
Wajid Ali

0

Você pode usar a Biblioteca RelativeDateTimeFormatter do Java , faz exatamente isso:

RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance();
 fmt.format(1, Direction.NEXT, RelativeUnit.DAYS); // "in 1 day"
 fmt.format(3, Direction.NEXT, RelativeUnit.DAYS); // "in 3 days"
 fmt.format(3.2, Direction.LAST, RelativeUnit.YEARS); // "3.2 years ago"

 fmt.format(Direction.LAST, AbsoluteUnit.SUNDAY); // "last Sunday"
 fmt.format(Direction.THIS, AbsoluteUnit.SUNDAY); // "this Sunday"
 fmt.format(Direction.NEXT, AbsoluteUnit.SUNDAY); // "next Sunday"
 fmt.format(Direction.PLAIN, AbsoluteUnit.SUNDAY); // "Sunday"

 fmt.format(Direction.LAST, AbsoluteUnit.DAY); // "yesterday"
 fmt.format(Direction.THIS, AbsoluteUnit.DAY); // "today"
 fmt.format(Direction.NEXT, AbsoluteUnit.DAY); // "tomorrow"

 fmt.format(Direction.PLAIN, AbsoluteUnit.NOW); // "now"

1
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.
     */
    public String convertTimeToAgo(String dataDate) {
    //Initialize
    String conversionTime = null;
    String suffix = "Yang Lalu";
    Date pastTime;
    //Parse from String (which is stored as Instant.now().toString()
    //And then convert to become Date
    Instant instant = Instant.parse(dataDate);
    pastTime = DateTimeUtils.toDate(instant);

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

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

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

1
Você está usando classes terríveis de data e hora antigas que foram suplantadas anos atrás pelas classes java.time .
Basil Bourque

@BasilBourque Ainda não consigo encontrar a maneira mais recente de fazer isso.
Ticherhaz 4/06/19

@BasilBourque Adicionei algum código para eu entender. github.com/ticherhaz/tarikhmasa
Ticherhaz 6/06/19

0

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"

public String formatTimeAgo(long millis) {
        String[] ids = new String[]{"second","minute","hour","day","month","year"};

        long seconds = millis / 1000;
        long minutes = seconds / 60;
        long hours = minutes / 60;
        long days = hours / 24;
        long months = days / 30;
        long years = months / 12;

        ArrayList<Long> times = new ArrayList<>(Arrays.asList(years, months, days, hours, minutes, seconds));

        for(int i = 0; i < times.size(); i++) {
            if(times.get(i) != 0) {
                long value = times.get(i).intValue();

                return value + " " + ids[ids.length - 1 - i] + (value == 1 ? "" : "s") + " ago";
            }
        }

        return "0 seconds ago";
    }

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)


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

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

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

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

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

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

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

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

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

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.