Comment trouver l'heure d'aujourd'hui ou d'hier dans Android

87

Je développe une application d'envoi de sms. Je stocke l'heure actuelle et s'affiche dans la page d'historique envoyée en récupérant l'heure de la base de données. Dans la page d'historique des envois, je souhaite afficher l'heure à laquelle le message a été envoyé. Ici, je veux vérifier que le message a été envoyé aujourd'hui ou hier ou hier avant comme ça. Si le message a été envoyé hier signifie alors je dois afficher "Hier 20:00" comme ça et même le message a été envoyé hier avant signifie "Lundi 20:00". Je ne sais pas comment cela doit être fait. S'il vous plaît, aidez-moi si quelqu'un sait.

Manikandan
la source
s'il vous plaît afficher votre code que vous avez fait ...
Goofy
@Keyser Pouvez-vous me dire comment procéder?
Manikandan
2
Puisque vous n'avez encore essayé aucun code, vous ne savez pas de quelle aide vous aurez besoin. Poser une question est prématuré. Attendez de voir ce qui vous pose problème.
David Schwartz
chaque fois que vous récupérez des données de la base de données, récupérez la dernière heure de conversion dans la boîte d'envoi
Nirav Ranpara
@ user1498488 Trouvez simplement quelques didacticiels sur la gestion de la date / heure Java.
keyer

Réponses:

51

Vous pouvez le faire facilement en utilisant la classe android.text.format.DateFormat. Essayez quelque chose comme ça.

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

Consultez http://developer.android.com/reference/java/text/DateFormat.html pour en savoir plus.

Sudhanshu Gupta
la source
21
Etes-vous sûr que c'est correct? Vous ne comparez que les dates, qu'en est-il de l'année et du mois? Aujourd'hui, nous sommes le 20 novembre 2014, mais votre code indique "Aujourd'hui" pour
Daryn
3
Cette réponse n'est pas correcte. Selon la documentation, Calendar.DATE est un synonyme de DAY_OF_MONTH. Par conséquent, vous ne comparez ni l'année ni le mois.
Joao Sousa
Oui, ce n'est pas correct. (Calendar.DATE) == smsTime.get (Calendar.DATE) correspond uniquement à la date, pas au mois et à l'année. il retourne vrai pour le 01.01.2012 et le 01.01.2017
Anjum
1
Pour le texte "aujourd'hui", cette solution est toujours correcte mais pour le texte "hier", elle n'est pas correcte le premier jour du mois. La méthode get (Calendar.DATE) renvoie le jour du mois et par exemple 1 - 31 = -30 au lieu de 1 ce qui devrait afficher "hier" - car le 31 décembre est le jour précédent du 1er janvier.
lukjar
Le "aujourd'hui" et "hier" doivent inclure le mois et l'année dans le chèque, pas seulement le Calendar.DATE
ZakariaBK
242

Pour vérifier si la date est celle d'aujourd'hui, utilisez la bibliothèque d'utils Android

DateUtils.isToday(long timeInMilliseconds)

Cette classe utils propose également des chaînes lisibles par l'homme pour les heures relatives. Par exemple,

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

Il existe plusieurs paramètres avec lesquels vous pouvez jouer pour définir la précision de l'intervalle de temps

Voir DateUtils

Maragues
la source
5
DateUtils.isToday (myDate.getTime ()) fonctionne bien, merci!
Loenix le
4
Est-ce que cela consomme uniquement l'heure locale (non UTC) ou les horodatages UTC?
Matthias
5
DateUtils.isToday(long millis)fonctionne comme décrit par @Maragues, mais sachez que si vous utilisez cette méthode dans un morceau de code que vous souhaitez tester unitaire (comme un ViewModel ou un Presenter), vous obtiendrez une RuntimeException lors de l'exécution de vos tests. Cela est dû au fait que le fichier android.jar utilisé pour les tests unitaires ne contient aucun code. Pour plus d'informations, lien
Kaskasi
78

Comme mentionné, DateUtils.isToday(d.getTime())fonctionnera pour déterminer si Date dc'est aujourd'hui. Mais certaines réponses ici ne permettent pas de savoir comment déterminer si une date était hier. Vous pouvez également le faire facilement avec DateUtils:

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

Après cela, vous pouvez également déterminer si une date était demain:

public static boolean isTomorrow(Date d) {
    return DateUtils.isToday(d.getTime() - DateUtils.DAY_IN_MILLIS);
}
thebaer
la source
Cela devrait être la réponse acceptée. Simple à lire et efficace. Le seul moyen de le rendre encore plus efficace serait d'écrire les méthodes pour un horodatage en millisecondes, afin de pouvoir l'utiliser avec Calendar, Date ou n'importe quelle classe que vous préférez.
joe1806772
C'est bien. Mais pour une raison étrange, je ne peux pas utiliser cela comme une fonction d'extension dans Kotlin comme:fun DateUtils.isYesterday(d: Long): Boolean { return DateUtils.isToday(d + DateUtils.DAY_IN_MILLIS) }
Saifur Rahman Mohsin le
Je pense que c'est la meilleure solution en littéralement deux lignes de code, il fait le travail
Amir Dora.
22

Pour aujourd'hui , vous pouvez utiliser DateUtils.isTodayde l' API Android .

Pour hier, vous pouvez utiliser ce code:

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
la source
@lujpo perfection!
swooby le
Le code ci-dessus avec now.get (Calendar.MONTH) semble renvoyer le mois précédent !?
Tina
@tina cela ne devrait arriver que le premier jour du mois
lujop
9

Vous pouvez essayer ceci:

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

Si votre niveau d'API est de 26 ou plus, vous feriez mieux d'utiliser 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
}

Si votre application a un niveau d'API inférieur, utilisez

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)
} 
Константин Семочкин
la source
5

AUCUNE bibliothèque utilisée


Hier

Aujourd'hui

Demain

Cette année

N'importe quelle année

 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
la source
4

Une autre façon de le faire. En kotlin avec la lib ThreeTen recommandée

  1. Ajouter ThreeTen

    implementation 'com.jakewharton.threetenabp:threetenabp:1.1.0'
    
  2. Ajoutez des extensions kotlin.

    fun LocalDate.isYesterday(): Boolean = this.isEqual(LocalDate.now().minusDays(1L))
    
    fun LocalDate.isToday(): Boolean = this.isEqual(LocalDate.now())
    
PsychédéliqueSubstance
la source
Cela devrait être la voie à suivre. L'analyse personnalisée est tout simplement mauvaise.
XY
4

Kotlin

Solution @Choletski mais avec des secondes et à 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()
        }
    }

Vous pouvez passer ici date.getTime()pour obtenir des sorties comme

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

C'est une méthode pour obtenir des valeurs telles que Aujourd'hui, Hier et Date comme l'application Whtsapp a

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

Utilisez cette méthode, passez simplement la milliseconde comme

 getSmsTodayYestFromMilli(Long.parseLong("1485236534000"));
Rjz Satvara
la source
Avez-vous testé ce code de votre côté ou toute référence?
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
la source
0

je peux vous suggérer une chose. Lorsque vous envoyez le sms, stockez les détails dans une base de données afin que vous puissiez afficher la date et l'heure auxquelles le SMS a été envoyé dans la page d'historique.

Goofy
la source
Oui, je stocke l'heure dans la base de données. Mais j'ai besoin de vérifier si l'heure enregistrée est aujourd'hui ou hier ou hier avant comme ça.
Manikandan
Si vous stockez l'heure, pourquoi ne pouvez-vous pas stocker la date aussi?
Goofy
Oui, je peux, mais je dois montrer comme "Aujourd'hui 8:00" comme ça dans la vue de texte
Manikandan
U peut faire cela ... obtenir la date de la base de données et comparer avec la date d'aujourd'hui. Si elle correspond, afficher une vue texte comme "Aujourd'hui" si c'est la date actuelle - date révisée puis afficher "Hier"
Dingo
0

DateUtils.isToday()doit être considéré comme obsolète car il android.text.format.Timeest désormais obsolète. Jusqu'à ce qu'ils mettent à jour le code source pour isToday, il n'y a pas de solution ici qui détecte aujourd'hui, hier, gère les décalages vers / depuis l'heure d'été et n'utilise pas de code obsolète. Le voici à Kotlin, en utilisant un todaychamp qui doit être mis à jour périodiquement (par exemple, 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)
}

J'ai déposé https://code.google.com/p/android/issues/detail?id=227694&thanks=227694&ts=1479155729 , allez voter dessus

androidguy
la source
0

C'est le code avec lequel je me suis retrouvé pour l'instant:

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
la source
0

Voici une solution simple que j'utilise:

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

Cela couvre tous les cas marginaux qui peuvent se produire.

Aman Raj Sundram
la source
-1

Sans aucune bibliothèque ni code simple, travaillez sur tous les projets 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
la source
La réponse fournie a été signalée pour examen en tant que publication de faible qualité. Voici quelques conseils pour Comment rédiger une bonne réponse? . Cette réponse fournie pourrait bénéficier d'une explication. Les réponses codées uniquement ne sont pas considérées comme «bonnes». De Revue .
Trenton McKinney