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.