Come trovare il tempo è oggi o ieri in Android


89

Sto sviluppando un'applicazione per l'invio di sms. Sto memorizzando l'ora corrente e mostrandola nella pagina della cronologia inviata recuperando l'ora dal database. Nella pagina della cronologia inviata voglio visualizzare l'ora in cui il messaggio è stato inviato. Qui voglio controllare che il messaggio sia stato inviato oggi o ieri o ieri prima in questo modo. Se il messaggio è stato inviato ieri significa che devo visualizzare "Ieri 20:00" in questo modo e anche il messaggio è stato inviato ieri prima significa "lunedì 20:00". Non so come debba essere fatto. Per favore aiutami se qualcuno lo sa.


per favore mostra il tuo codice che hai fatto ...
— Pippo

@Keyser Puoi dirmi come farlo?
— Manikandan

2
Poiché non hai ancora provato alcun codice, non sai di quale aiuto avrai bisogno. Fare una domanda è prematuro. Aspetta di vedere cosa ti dà problemi.
— David Schwartz

ogni volta che recuperi i dati dal database, recupera l'ultima volta della conversione nella casella inviata
— Nirav Ranpara

@ user1498488 Basta trovare alcuni tutorial sulla gestione di data / ora Java.
— keyser

Risposte:


51

Puoi farlo facilmente usando la classe android.text.format.DateFormat. Prova qualcosa di simile.

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

Controlla http://developer.android.com/reference/java/text/DateFormat.html per ulteriori informazioni.


21
Sei sicuro che sia corretto? Confronta solo le date, che dire dell'anno e del mese? Oggi è il 20.11.2014, ma il tuo codice mostra "Oggi" per il 20.10.2010
— Daryn

4
Questa risposta non è corretta. Come da documentazione, Calendar.DATE è sinonimo di DAY_OF_MONTH. Quindi non stai confrontando né l'anno né il mese.
— Joao Sousa

Sì, non è corretto. (Calendar.DATE) == smsTime.get (Calendar.DATE) corrisponde solo alla data, non al mese e all'anno. ritorna vero per il 01.01.2012 e il 01.01.2017
— Anjum

1
Per il testo "oggi" questa soluzione è sempre corretta ma per il testo "ieri" non è corretta nel primo giorno del mese. Il metodo get (Calendar.DATE) restituisce il giorno del mese e ad esempio 1 - 31 = -30 invece di 1 ciò che dovrebbe visualizzare "ieri" - perché il 31 dicembre è il giorno precedente del 1 gennaio.
— lukjar

L '"oggi" e "ieri" devono includere il mese e l'anno nell'assegno, non solo il calendario.DATE
— ZakariaBK

245

Per verificare se la data è oggi, utilizza la libreria di utilità Android

DateUtils.isToday(long timeInMilliseconds)

Questa classe utils offre anche stringhe leggibili dall'uomo per tempi relativi. Per esempio,

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

Ci sono diversi parametri con cui puoi giocare per definire quanto dovrebbe essere preciso l'intervallo di tempo

Vedere DateUtils


5
DateUtils.isToday (myDate.getTime ()) funziona bene, grazie!
— Loenix

4
Questo consuma solo l'ora locale (non UTC) o i timestamp UTC?
— Matthias

5
DateUtils.isToday(long millis)funziona come descritto da @Maragues, ma tieni presente che se usi questo metodo in un pezzo di codice che vuoi testare (come un ViewModel o un Presenter), otterrai una RuntimeException durante l'esecuzione dei tuoi test. Ciò è dovuto al fatto che il file android.jar utilizzato per gli unit test non contiene alcun codice. Per maggiori informazioni link
— Kaskasi

82

Come accennato, DateUtils.isToday(d.getTime())funzionerà per determinare se Date dè oggi. Ma alcune risposte qui non rispondono effettivamente a come determinare se una data era ieri. Puoi anche farlo facilmente con DateUtils:

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

Successivamente, potresti anche determinare se una data era domani:

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

1
Questa dovrebbe essere la risposta accettata. Semplice da leggere ed efficace. L'unico modo per renderlo ancora più efficace sarebbe scrivere i metodi per un timestamp in millisecondi, quindi puoi usarlo con Calendar, Date o qualsiasi altra classe tu preferisca.
— joe1806772

Questo è fantastico. Ma per qualche strana ragione non sono in grado di usarlo come funzione di estensione in Kotlin come:fun DateUtils.isYesterday(d: Long): Boolean { return DateUtils.isToday(d + DateUtils.DAY_IN_MILLIS) }
— Saifur Rahman Mohsin

Penso che questa sia la soluzione migliore letteralmente in due righe di codice che fa il lavoro
— Amir Dora.

ha funzionato. Grazie: D !!
— ppreetikaa

22

Per oggi è possibile utilizzare DateUtils.isTodayda API di Android .

Per ieri puoi usare quel codice:

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

@lujpo perfection!
— swooby

Il codice sopra con now.get (Calendar.MONTH) sembra restituire il mese precedente !?
— Tina

@tina dovrebbe accadere solo il primo giorno del mese
— lujop

9

Puoi provare questo:

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

8

Se il tuo livello API è 26 o superiore, è meglio usare la 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 la tua app ha un livello API inferiore, usa

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

5

NESSUN libs utilizzato


Ieri

Oggi

Domani

Quest'anno

Ogni anno

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

4

Un altro modo per farlo. In kotlin con la libreria consigliata ThreeTen

  1. Aggiungi ThreeTen

    implementation 'com.jakewharton.threetenabp:threetenabp:1.1.0'
    
  2. Aggiungi estensioni kotlin.

    fun LocalDate.isYesterday(): Boolean = this.isEqual(LocalDate.now().minusDays(1L))
    
    fun LocalDate.isToday(): Boolean = this.isEqual(LocalDate.now())
    

Questa dovrebbe essere la strada da percorrere. L'analisi personalizzata è solo un male.
— XY

4

Kotlin

@ Soluzione Coletski ma con secondi e in 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()
        }
    }

Puoi passare qui date.getTime()per ottenere output come

Today at 18:34:45
Yesterday at 12:30:00
Tomorrow at 09:04:05

2

Questo è il metodo per ottenere valori come Oggi, Ieri e Data come l'app Whtsapp ha

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

Usa questo metodo solo per passare Millisecondi come

 getSmsTodayYestFromMilli(Long.parseLong("1485236534000"));

Hai testato questo codice dalla tua parte o qualsiasi riferimento?
— 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";

0

posso suggerirti una cosa. Quando si invia l'SMS, memorizzare i dettagli in un database in modo da poter visualizzare la data e l'ora in cui l'SMS è stato inviato nella pagina della cronologia.


Sì, sto memorizzando l'ora nel database. Ma ho bisogno di controllare se l'ora memorizzata è oggi o ieri o ieri prima in questo modo.
— Manikandan

se stai memorizzando l'ora, allora perché non puoi memorizzare anche la data?
— Pippo

Sì che posso, ma ho bisogno di mostrare come "Oggi 08:00" come quello nel TextView
— Manikandan

Puoi farlo ... prendi la data dal Db e confrontala con la data odierna. Se corrisponde, visualizza una vista di testo come "Oggi" se è la data corrente - data revious quindi visualizza "Ieri"
— Pippo


0

DateUtils.isToday()dovrebbe essere considerato deprecato perché android.text.format.Timeora è deprecato. Fino a quando non aggiorneranno il codice sorgente per isToday, non esiste alcuna soluzione che rilevi oggi, ieri, gestisca i turni da / per l'ora legale e non utilizzi codice deprecato. Eccolo in Kotlin, utilizzando un todaycampo che deve essere aggiornato periodicamente (es onResumeecc.):

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

Ho archiviato https://code.google.com/p/android/issues/detail?id=227694&thanks=227694&ts=1479155729 , vai a votarlo


0

Questo è il codice con cui mi sono ritrovato per ora:

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

0

Ecco una semplice soluzione che utilizzo:

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

Questo copre tutti i casi limite che possono verificarsi.


-1

Senza alcuna libreria e codice semplice, lavora su ogni progetto 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()) {
...
}

La risposta fornita è stata contrassegnata per la revisione come Post di bassa qualità. Ecco alcune linee guida per Come scrivere una buona risposta? . Questa risposta fornita potrebbe beneficiare di una spiegazione. Le risposte solo codice non sono considerate risposte "buone". Dalla recensione .
— Trenton McKinney
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.