Como encontrar o tempo é hoje ou ontem no android

87

Estou desenvolvendo um aplicativo para envio de sms. Iam armazenando a hora atual e mostrando na página de histórico de envio, recuperando a hora do banco de dados. Na página de histórico de envio, quero exibir a hora em que a mensagem foi enviada. Quero aqui verificar se a mensagem foi enviada hoje ou ontem ou ontem antes. Se a mensagem foi enviada ontem significa que preciso exibir "Ontem 20:00" assim e até mesmo a mensagem enviada ontem antes significa "Segunda-feira 20:00". Não sei como isso deve ser feito. Por favor me ajude se alguém souber.

Manikanda
fonte
por favor, mostre o código que você fez ...
Pateta
@Keyser Você pode me dizer como fazer isso?
Manikandan,
2
Como você ainda não experimentou nenhum código, não sabe de que ajuda precisa. Fazer uma pergunta é prematuro. Espere até ver o que está causando problemas.
David Schwartz,
sempre que você buscar dados do banco de dados, busque o último tempo de conversão na caixa enviada
Nirav Ranpara 10/10/12
@ user1498488 Simplesmente encontre alguns tutoriais sobre manipulação de data / hora Java.
keyser

Respostas:

51

Você pode fazer isso facilmente usando a classe android.text.format.DateFormat. Experimente algo assim.

public String getFormattedDate(Context context, long smsTimeInMilis) {
    Calendar smsTime = Calendar.getInstance();
    smsTime.setTimeInMillis(smsTimeInMilis);

    Calendar now = Calendar.getInstance();

    final String timeFormatString = "h:mm aa";
    final String dateTimeFormatString = "EEEE, MMMM d, h:mm aa";
    final long HOURS = 60 * 60 * 60;
    if (now.get(Calendar.DATE) == smsTime.get(Calendar.DATE) ) {
        return "Today " + DateFormat.format(timeFormatString, smsTime);
    } else if (now.get(Calendar.DATE) - smsTime.get(Calendar.DATE) == 1  ){
        return "Yesterday " + DateFormat.format(timeFormatString, smsTime);
    } else if (now.get(Calendar.YEAR) == smsTime.get(Calendar.YEAR)) {
        return DateFormat.format(dateTimeFormatString, smsTime).toString();
    } else {
        return DateFormat.format("MMMM dd yyyy, h:mm aa", smsTime).toString();
    }
}

Verifique http://developer.android.com/reference/java/text/DateFormat.html para obter mais informações.

Sudhanshu Gupta
fonte
21
Tem certeza que está correto? Você compara apenas datas, que tal ano e mês? Hoje é 20.11.2014, mas seu código mostra "Today" para 20.10.2010
Daryn
3
Esta resposta não está correta. De acordo com a documentação, Calendar.DATE é sinônimo de DAY_OF_MONTH. Portanto, você não está comparando nem o ano nem o mês.
João Sousa
Sim, não está correto. (Calendar.DATE) == smsTime.get (Calendar.DATE) corresponde apenas à data, não ao mês e ao ano. retorna verdadeiro para 01.01.2012 e 01.01.2017
Anjum
1
Para o texto "hoje", esta solução está sempre correta, mas para o texto "ontem", ela não está correta no primeiro dia do mês. O método get (Calendar.DATE) retorna o dia do mês e, por exemplo, 1 - 31 = -30 em vez de 1, o que deveria exibir "ontem" - porque 31 de dezembro é o dia anterior de 1º de janeiro.
lukjar 01 de
O "hoje" e o "ontem" precisam incluir o mês e o ano na verificação, não apenas o calendário
DATA
242

Para verificar se a data é hoje, use a biblioteca de utilitários do Android

DateUtils.isToday(long timeInMilliseconds)

Esta classe utils também oferece strings legíveis por humanos para tempos relativos. Por exemplo,

DateUtils.getRelativeTimeSpanString(long timeInMilliseconds) -> "42 minutes ago"

Existem vários parâmetros que você pode usar para definir o quão preciso o intervalo de tempo deve ser

Veja DateUtils

Maragues
fonte
5
DateUtils.isToday (myDate.getTime ()) está funcionando bem, obrigado!
Loenix
4
Isso está consumindo a hora local (não UTC) ou os carimbos de data / hora UTC apenas?
Matthias
5
DateUtils.isToday(long millis)funciona conforme descrito por @Maragues, mas esteja ciente de que se você usar esse método em um trecho de código que deseja testar de unidade (como um ViewModel ou um Presenter), você obterá uma RuntimeException ao executar seus testes. Isso se deve ao fato de que o android.jar usado para testes de unidade não contém nenhum código. Para mais informações, link
Kaskasi 01 de
78

Conforme mencionado, DateUtils.isToday(d.getTime())funcionará para determinar se Date dé hoje. Mas algumas respostas aqui não respondem realmente como determinar se uma data foi ontem. Você também pode fazer isso facilmente com DateUtils:

public static boolean isYesterday(Date d) {
    return DateUtils.isToday(d.getTime() + DateUtils.DAY_IN_MILLIS);
}

Depois disso, você também pode determinar se a data é amanhã:

public static boolean isTomorrow(Date d) {
    return DateUtils.isToday(d.getTime() - DateUtils.DAY_IN_MILLIS);
}
thebaer
fonte
Esta deve ser a resposta aceita. Simples de ler e eficaz. A única maneira de torná-lo ainda mais eficaz seria escrever os métodos para um carimbo de data / hora em millis, para que seja possível usá-lo com Calendar, Date ou qualquer classe de sua preferência.
joe1806772
Isso é ótimo. Mas, por alguma razão estranha, não consigo usar isso como uma função de extensão em Kotlin, como:fun DateUtils.isYesterday(d: Long): Boolean { return DateUtils.isToday(d + DateUtils.DAY_IN_MILLIS) }
Saifur Rahman Mohsin
Acho que essa é a melhor solução em literalmente duas linhas de código - ela faz o trabalho
Amir Dora.
22

Por hoje você pode usar a DateUtils.isTodaypartir da API do Android .

Para ontem, você pode usar esse código:

public static boolean isYesterday(long date) {
    Calendar now = Calendar.getInstance();
    Calendar cdate = Calendar.getInstance();
    cdate.setTimeInMillis(date);

    now.add(Calendar.DATE,-1);

    return now.get(Calendar.YEAR) == cdate.get(Calendar.YEAR)
        && now.get(Calendar.MONTH) == cdate.get(Calendar.MONTH)
        && now.get(Calendar.DATE) == cdate.get(Calendar.DATE);
}
lujop
fonte
@lujpo perfeection!
swooby
O código acima com now.get (Calendar.MONTH) parece retornar ao mês anterior !?
Tina
@tina só deve acontecer no primeiro dia do mês
lujop
9

Você pode tentar isto:

Calendar mDate = Calendar.getInstance(); // just for example
if (DateUtils.isToday(mDate.getTimeInMillis())) {
  //format one way
} else {
  //format in other way
}
Roman Golyshev
fonte
7

Se o seu nível de API for 26 ou superior, é melhor usar a classe LocalDate:

fun isToday(whenInMillis: Long): Boolean {
    return LocalDate.now().compareTo(LocalDate(whenInMillis)) == 0
}

fun isTomorrow(whenInMillis: Long): Boolean {
    return LocalDate.now().plusDays(1).compareTo(LocalDate(whenInMillis)) == 0
}

fun isYesterday(whenInMillis: Long): Boolean {
    return LocalDate.now().minusDays(1).compareTo(LocalDate(whenInMillis)) == 0
}

Se seu aplicativo tiver um nível de API inferior, use

fun isToday(whenInMillis: Long): Boolean {
    return DateUtils.isToday(whenInMillis)
}

fun isTomorrow(whenInMillis: Long): Boolean {
    return DateUtils.isToday(whenInMillis - DateUtils.DAY_IN_MILLIS)
}

fun isYesterday(whenInMillis: Long): Boolean {
    return DateUtils.isToday(whenInMillis + DateUtils.DAY_IN_MILLIS)
} 
Константин Семочкин
fonte
5

SEM libs usados


Ontem

Hoje

Amanhã

Este ano

Qualquer ano

 public static String getMyPrettyDate(long neededTimeMilis) {
    Calendar nowTime = Calendar.getInstance();
    Calendar neededTime = Calendar.getInstance();
    neededTime.setTimeInMillis(neededTimeMilis);

    if ((neededTime.get(Calendar.YEAR) == nowTime.get(Calendar.YEAR))) {

        if ((neededTime.get(Calendar.MONTH) == nowTime.get(Calendar.MONTH))) {

            if (neededTime.get(Calendar.DATE) - nowTime.get(Calendar.DATE) == 1) {
                //here return like "Tomorrow at 12:00"
                return "Tomorrow at " + DateFormat.format("HH:mm", neededTime);

            } else if (nowTime.get(Calendar.DATE) == neededTime.get(Calendar.DATE)) {
                //here return like "Today at 12:00"
                return "Today at " + DateFormat.format("HH:mm", neededTime);

            } else if (nowTime.get(Calendar.DATE) - neededTime.get(Calendar.DATE) == 1) {
                //here return like "Yesterday at 12:00"
                return "Yesterday at " + DateFormat.format("HH:mm", neededTime);

            } else {
                //here return like "May 31, 12:00"
                return DateFormat.format("MMMM d, HH:mm", neededTime).toString();
            }

        } else {
            //here return like "May 31, 12:00"
            return DateFormat.format("MMMM d, HH:mm", neededTime).toString();
        }

    } else {
        //here return like "May 31 2010, 12:00" - it's a different year we need to show it
        return DateFormat.format("MMMM dd yyyy, HH:mm", neededTime).toString();
    }
}
Choletski
fonte
4

Outra maneira de fazer isso. Em kotlin com a lib ThreeTen recomendada

  1. Adicionar três dez

    implementation 'com.jakewharton.threetenabp:threetenabp:1.1.0'
    
  2. Adicione extensões kotlin.

    fun LocalDate.isYesterday(): Boolean = this.isEqual(LocalDate.now().minusDays(1L))
    
    fun LocalDate.isToday(): Boolean = this.isEqual(LocalDate.now())
    
PsychedelicSubstance
fonte
Este deve ser o caminho a percorrer. A análise personalizada é simplesmente ruim.
XY de
4

Kotlin

Solução @Choletski mas com segundos e em Kotlin

 fun getMyPrettyDate(neededTimeMilis: Long): String? {
        val nowTime = Calendar.getInstance()
        val neededTime = Calendar.getInstance()
        neededTime.timeInMillis = neededTimeMilis
        return if (neededTime[Calendar.YEAR] == nowTime[Calendar.YEAR]) {
            if (neededTime[Calendar.MONTH] == nowTime[Calendar.MONTH]) {
                if (neededTime[Calendar.DATE] - nowTime[Calendar.DATE] == 1) {
                    //here return like "Tomorrow at 12:00"
                    "Tomorrow at " + DateFormat.format("HH:mm:ss", neededTime)
                } else if (nowTime[Calendar.DATE] == neededTime[Calendar.DATE]) {
                    //here return like "Today at 12:00"
                    "Today at " + DateFormat.format("HH:mm:ss", neededTime)
                } else if (nowTime[Calendar.DATE] - neededTime[Calendar.DATE] == 1) {
                    //here return like "Yesterday at 12:00"
                    "Yesterday at " + DateFormat.format("HH:mm:ss", neededTime)
                } else {
                    //here return like "May 31, 12:00"
                    DateFormat.format("MMMM d, HH:mm:ss", neededTime).toString()
                }
            } else {
                //here return like "May 31, 12:00"
                DateFormat.format("MMMM d, HH:mm:ss", neededTime).toString()
            }
        } else {
            //here return like "May 31 2010, 12:00" - it's a different year we need to show it
            DateFormat.format("MMMM dd yyyy, HH:mm:ss", neededTime).toString()
        }
    }

Você pode passar aqui date.getTime()para obter resultados como

Today at 18:34:45
Yesterday at 12:30:00
Tomorrow at 09:04:05
Gastón Saillén
fonte
2

Este é o método para obter valores como Hoje, Ontem e Data como o app Whtsapp tem

public String getSmsTodayYestFromMilli(long msgTimeMillis) {

        Calendar messageTime = Calendar.getInstance();
        messageTime.setTimeInMillis(msgTimeMillis);
        // get Currunt time
        Calendar now = Calendar.getInstance();

        final String strTimeFormate = "h:mm aa";
        final String strDateFormate = "dd/MM/yyyy h:mm aa";

        if (now.get(Calendar.DATE) == messageTime.get(Calendar.DATE)
                &&
                ((now.get(Calendar.MONTH) == messageTime.get(Calendar.MONTH)))
                &&
                ((now.get(Calendar.YEAR) == messageTime.get(Calendar.YEAR)))
                ) {

            return "today at " + DateFormat.format(strTimeFormate, messageTime);

        } else if (
                ((now.get(Calendar.DATE) - messageTime.get(Calendar.DATE)) == 1)
                        &&
                        ((now.get(Calendar.MONTH) == messageTime.get(Calendar.MONTH)))
                        &&
                        ((now.get(Calendar.YEAR) == messageTime.get(Calendar.YEAR)))
                ) {
            return "yesterday at " + DateFormat.format(strTimeFormate, messageTime);
        } else {
            return "date : " + DateFormat.format(strDateFormate, messageTime);
        }
    }

Use este método, basta passar milissegundos como

 getSmsTodayYestFromMilli(Long.parseLong("1485236534000"));
Rjz Satvara
fonte
Você testou este código do seu lado ou alguma referência?
androidXP
1
    Calendar now = Calendar.getInstance();
    long secs = (dateToCompare - now.getTime().getTime()) / 1000;
    if (secs > 0) {
        int hours = (int) secs / 3600;
        if (hours <= 24) {
            return today + "," + "a formatted day or empty";
        } else if (hours <= 48) {
            return yesterday + "," + "a formatted day or empty";
        }
    } else {
        int hours = (int) Math.abs(secs) / 3600;

        if (hours <= 24) {
            return tommorow + "," + "a formatted day or empty";
        }
    }
    return "a formatted day or empty";
Raluca Lucaci
fonte
0

eu posso sugerir uma coisa. Ao enviar o sms, armazene os detalhes em um banco de dados para que possa exibir a data e a hora em que o sms foi enviado na página de histórico.

Pateta
fonte
Sim, iam armazenando a hora no banco de dados. Mas preciso verificar se o tempo armazenado é hoje ou ontem ou ontem antes assim.
Manikandan,
se você está armazenando o tempo. então por que você não pode armazenar a data também?
Pateta de
Sim, eu posso, mas preciso mostrar como "Hoje 8:00" assim na visualização de texto
Manikandan
Você pode fazer isso ... pegue a data do Db e compare com a data de hoje. Se ela corresponder, exiba uma visualização de texto como "Hoje" se for a data atual - data revisada e exiba "Ontem"
Pateta
0

DateUtils.isToday()deve ser considerado obsoleto porque android.text.format.Timeagora está obsoleto. Até que eles atualizem o código-fonte para isToday, não há solução aqui que detecte hoje, ontem, lida com mudanças de / para o horário de verão e não use código obsoleto. Aqui está em Kotlin, usando um todaycampo que deve ser mantido atualizado periodicamente (por exemplo, onResumeetc):

@JvmStatic
fun dateString(ctx: Context, epochTime: Long): String {
    val epochMS = 1000*epochTime
    val cal = Calendar.getInstance()
    cal.timeInMillis = epochMS
    val yearDiff = cal.get(Calendar.YEAR) - today.get(Calendar.YEAR)
    if (yearDiff == 0) {
        if (cal.get(Calendar.DAY_OF_YEAR) >= today.get(Calendar.DAY_OF_YEAR))
            return ctx.getString(R.string.today)
    }
    cal.add(Calendar.DATE, 1)
    if (cal.get(Calendar.YEAR) == today.get(Calendar.YEAR)) {
        if (cal.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR))
            return ctx.getString(R.string.yesterday)
    }
    val flags = if (yearDiff == 0) DateUtils.FORMAT_ABBREV_MONTH else DateUtils.FORMAT_NUMERIC_DATE
    return DateUtils.formatDateTime(ctx, epochMS, flags)
}

Eu preenchi https://code.google.com/p/android/issues/detail?id=227694&thanks=227694&ts=1479155729 , vá votar

androidguy
fonte
0

Este é o código que terminei com agora:

import android.text.format.DateFormat

fun java.util.Date.asPrettyTime(context: Context): String {
    val nowTime = Calendar.getInstance()

    val dateTime = Calendar.getInstance().also { calendar ->
        calendar.timeInMillis = this.time
    }

    if (dateTime[Calendar.YEAR] != nowTime[Calendar.YEAR]) { // different year
        return DateFormat.format("MM.dd.yyyy.  ·  HH:mm", dateTime).toString()
    }

    if (dateTime[Calendar.MONTH] != nowTime[Calendar.MONTH]) { // different month
        return DateFormat.format("MM.dd.  ·  HH:mm", dateTime).toString()
    }

    return when {
        nowTime[Calendar.DATE] == dateTime[Calendar.DATE] -> { // today
            "${context.getString(R.string.today)}  ·  ${DateFormat.format("HH:mm", dateTime)}"
        }
        nowTime[Calendar.DATE] - dateTime[Calendar.DATE] == 1 -> { // yesterday
            "${context.getString(R.string.yesterday)}  ·  ${DateFormat.format("HH:mm", dateTime)}"
        }
        nowTime[Calendar.DATE] - dateTime[Calendar.DATE] == -1 -> { // tomorrow
            "${context.getString(R.string.tomorrow)}  ·  ${DateFormat.format("HH:mm", dateTime)}"
        }
        else -> { // other date this month
            DateFormat.format("MM.dd.  ·  HH:mm", dateTime).toString()
        }
    }
}
EpicPandaForce
fonte
0

Aqui está uma solução simples que eu uso:

public static boolean isTomorrow(Calendar c) {
    Calendar tomorrow = Calendar.getInstance();
    tomorrow.add(Calendar.DATE,1);
    return (tomorrow.get(Calendar.YEAR) == c.get(Calendar.YEAR)) && (tomorrow.get(Calendar.DAY_OF_YEAR) == (c.get(Calendar.DAY_OF_YEAR)));
}

public static boolean isToday(Calendar c) {
    Calendar today = Calendar.getInstance();
    return (today.get(Calendar.YEAR) == c.get(Calendar.YEAR)) && (today.get(Calendar.DAY_OF_YEAR) == c.get(Calendar.DAY_OF_YEAR));
}

Isso cobre todos os casos extremos que podem ocorrer.

Aman Raj Sundram
fonte
-1

Sem qualquer biblioteca e código simples, trabalhe em todos os projetos Kotlin

//Simple date format of the day
val sdfDate = SimpleDateFormat("dd/MM/yyyy")

//Create this 2 extensions of Date
fun Date.isToday() = sdfDate.format(this) == sdfDate.format(Date())
fun Date.isYesterday() =
    sdfDate.format(this) == sdfDate.format(Calendar.getInstance().apply { 
          add(Calendar.DAY_OF_MONTH, -1) }.time)
 
    
//And after everwhere in your code you can do
if(myDate.isToday()){
   ...
}
else if(myDate.isYesterday()) {
...
}
Anthone
fonte
A resposta fornecida foi marcada para revisão como uma postagem de baixa qualidade. Aqui estão algumas diretrizes para Como escrevo uma boa resposta? . A resposta fornecida pode se beneficiar de uma explicação. Respostas apenas em código não são consideradas "boas" respostas. Da avaliação .
Trenton McKinney