109

I am developing an application for sending SMS. I am storing the current time and showing in the sent history page by retrieving the time from the database. In the sent history page I want to display the time of the message was sent. Here I want to check that the message has been sent today or yesterday or the the day before yesterday like that. If the message was sent yesterday means then I need to display "Yesterday 20:00" like that and even the message was sent yesterday before means "Monday 20:00". I don't know how it has to be done. Please help me if anybody knows.

ganjaam
  • 1,030
  • 3
  • 17
  • 29
Manikandan
  • 1,802
  • 5
  • 20
  • 28

19 Answers19

277

To check if date is today, use Android utils library

DateUtils.isToday(long timeInMilliseconds)

This utils class also offers human readable strings for relative times. For example,

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

The are several parameters you can play with to define how precise the time span should be

See DateUtils

sHOLE
  • 343
  • 4
  • 15
Maragues
  • 37,861
  • 14
  • 95
  • 96
  • 5
    DateUtils.isToday(myDate.getTime()) is working fine, thank you ! – Loenix Jul 04 '15 at 18:40
  • 4
    Is this consuming the local (non-UTC) time or UTC-timestamps only? – Matthias Jul 19 '15 at 08:31
  • 7
    `DateUtils.isToday(long millis)` works as described by @Maragues, but be aware, that if you use this method in a piece of code that you want to unit test (like a ViewModel or a Presenter), you will get a RuntimeException when running your tests. This is due to the fact that the android.jar that is used for unit tests does not contain any code. For more info [link](http://g.co/androidstudio/not-mocked) – Kaskasi Nov 01 '16 at 07:13
  • after 24 hour it give yesterday but i want 1 day ago how i can get this kindly guide me about this – Adnan haider Mar 06 '21 at 06:42
109

As mentioned, DateUtils.isToday(d.getTime()) will work for determining if Date d is today. But some responses here don't actually answer how to determine if a date was yesterday. You can also do that easily with DateUtils:

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

Following that, you could also determine if a date was tomorrow:

public static boolean isTomorrow(Date d) {
    return DateUtils.isToday(d.getTime() - DateUtils.DAY_IN_MILLIS);
}
Matt Baer
  • 1,267
  • 1
  • 12
  • 11
  • 1
    This should be the accepted answer. Simple to read, and effective. Only way to make it even more effective would be to write the methods for a millis timestamp, so one can use it with Calendar, Date or whatever class you prefer. – joe1806772 Nov 13 '17 at 16:54
  • This is great. But for some weird reason I'm not able to use this as an extension function in Kotlin like: `fun DateUtils.isYesterday(d: Long): Boolean { return DateUtils.isToday(d + DateUtils.DAY_IN_MILLIS) }` – Saifur Rahman Mohsin Feb 21 '20 at 23:02
  • i think this is best solution in literally two lines of code it gets the job done – Amir Dora. Apr 15 '20 at 09:29
55

You can do that easily using android.text.format.DateFormat class. Try something like this.

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

Check http://developer.android.com/reference/java/text/DateFormat.html for further understanding.

Ben-J
  • 1,084
  • 8
  • 24
Sudhanshu Gupta
  • 1,889
  • 1
  • 17
  • 15
  • 23
    Are you sure that it is correct? You compare only dates, what about year and month? Today is 20.11.2014, but your code shows "Today" for 20.10.2010 – Daryn Nov 20 '14 at 05:44
  • 4
    This answer is not correct. As per documentation, Calendar.DATE is a synonym for DAY_OF_MONTH. Therefore you are not comparing neither the year nor the month. – Joao Sousa Oct 31 '16 at 08:55
  • Yes, it is not correct. (Calendar.DATE) == smsTime.get(Calendar.DATE) matches only date, not month and year. it returns true for 01.01.2012 and 01.01.2017 – Anjum Jan 24 '17 at 09:09
  • 1
    For "today" text this solution is always correct but for "yesterday" text It is not correct in the first day of the month. Method get(Calendar.DATE) returns day of the month and for example 1 - 31 = -30 instead 1 what should display "yesterday" - because 31th of December is the previous day of 1st of January. – lukjar Jan 01 '19 at 12:55
  • The "today" and "yesterday" needs to include the month and the year in the check, not only the Calendar.DATE – Zakaria Boukaddouss Sep 09 '20 at 06:58
22

For today you can use DateUtils.isToday from android API.

For yesterday you can use that 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
  • 13,504
  • 9
  • 62
  • 95
13

NO libs used


Yesterday

Today

Tomorrow

This year

Any year

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

Kotlin extension function:

fun Long.toPrettyDate(): String {
    val nowTime = Calendar.getInstance()
    val neededTime = Calendar.getInstance()
    neededTime.timeInMillis = this
    
    return if (neededTime[Calendar.YEAR] == nowTime[Calendar.YEAR]) {
        if (neededTime[Calendar.MONTH] == nowTime[Calendar.MONTH]) {
            when {
                neededTime[Calendar.DATE] - nowTime[Calendar.DATE] == 1 -> {
                    //here return like "Tomorrow at 12:00"
                    "Tomorrow at " +  SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date(this))
                }
                nowTime[Calendar.DATE] == neededTime[Calendar.DATE] -> {
                    //here return like "Today at 12:00"
                    "Today at " +  SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date(this))
                }
                nowTime[Calendar.DATE] - neededTime[Calendar.DATE] == 1 -> {
                    //here return like "Yesterday at 12:00"
                    "Yesterday at " +  SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date(this))
                }
                else -> {
                    //here return like "May 31, 12:00"
                    SimpleDateFormat("MMMM d, HH:mm", Locale.getDefault()).format(Date(this))
                }
            }
        } else {
            //here return like "May 31, 12:00"
            SimpleDateFormat("MMMM d, HH:mm", Locale.getDefault()).format(Date(this))
        }
    } else {
        //here return like "May 31 2022, 12:00" - it's a different year we need to show it
        SimpleDateFormat("MMMM dd yyyy, HH:mm", Locale.getDefault()).format(Date(this))
    }
}
Choletski
  • 7,074
  • 6
  • 43
  • 64
  • Hi! thanks for the code it really helped! it just have a minor issue that the condition for "Yesterday at " and ""Tomorrow at" are the same! the ""Tomorrow at" one should be -1 instead – ErfanDP Feb 07 '22 at 08:46
10

If your API level is 26 or higher, then you better use LocalDate class:

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
}

If your app has lower API level, 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)
} 
Sergio
  • 725
  • 1
  • 7
  • 20
9

You can try this:

Calendar mDate = Calendar.getInstance(); // just for example
if (DateUtils.isToday(mDate.getTimeInMillis())) {
  //format one way
} else {
  //format in other way
}
Roman Golyshev
  • 1,486
  • 15
  • 15
8

Blow snippet useful in recycler view header section.

Kotlin Extension:

fun Date.isYesterday(): Boolean = DateUtils.isToday(this.time + DateUtils.DAY_IN_MILLIS)

fun Date.isToday(): Boolean = DateUtils.isToday(this.time)


fun Date.toDateString(): String {
   return when {
    this.isToday() -> {
        "Today"
    }
    this.isYesterday() -> {
        "Yesterday"
    }
    else -> {
        convetedDate.format(this)
    }
 }
}
Arul
  • 1,031
  • 13
  • 23
5

Another way to do it. In kotlin with recommended lib ThreeTen

  1. Add ThreeTen

    implementation 'com.jakewharton.threetenabp:threetenabp:1.1.0'
    
  2. Add kotlin extensions.

    fun LocalDate.isYesterday(): Boolean = this.isEqual(LocalDate.now().minusDays(1L))
    
    fun LocalDate.isToday(): Boolean = this.isEqual(LocalDate.now())
    
Jakub S.
  • 5,580
  • 2
  • 42
  • 37
5

Kotlin

@Choletski solution but with seconds and 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()
        }
    }

You can pass here date.getTime() to get outputs like

Today at 18:34:45
Yesterday at 12:30:00
Tomorrow at 09:04:05
Gastón Saillén
  • 12,319
  • 5
  • 67
  • 77
3

Also quite pretty using as kotlin extension:

fun Calendar.isToday() : Boolean {
    val today = Calendar.getInstance()
    return today[Calendar.YEAR] == get(Calendar.YEAR) && today[Calendar.DAY_OF_YEAR] == get(Calendar.DAY_OF_YEAR)
}

And using:

if (calendar.isToday()) {
    Log.d("Calendar", "isToday")
}
walkmn
  • 2,322
  • 22
  • 29
2

This is method for get Values like Today , Yesterday and Date like Whtsapp app have

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 this method just pass Millisecond like

 getSmsTodayYestFromMilli(Long.parseLong("1485236534000"));
Rajesh Satvara
  • 3,842
  • 2
  • 30
  • 50
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
  • 2,058
  • 3
  • 20
  • 37
1

In Kotlin

Result:

Today's Date --> Today

Yesterday Date -> Yesterday

This Year Date -> 20 Jun

Not This Year Date -> 01 Feb 2019

fun Context.toReadableDateFormat(date: Long, comparableDate: Long = System.currentTimeMillis()): String{
   val comparableDateTime = comparableDate.getCalendar()
   val itemDateTime = date.getCalendar()
   return if(
    comparableDateTime.get(Calendar.DAY_OF_MONTH) == itemDateTime.get(Calendar.DAY_OF_MONTH) &&
    comparableDateTime.get(Calendar.MONTH) == itemDateTime.get(Calendar.MONTH) &&
    comparableDateTime.get(Calendar.YEAR) == itemDateTime.get(Calendar.YEAR)
)
       "Today"
   else if(isYesterday(date).orFalse())
       "Yesterday"
   else if(comparableDateTime.get(Calendar.YEAR) == itemDateTime.get(Calendar.YEAR))
       itemDateTime.toFormat("dd MMM")
   else
       itemDateTime.toFormat("dd MMM yyyy")

}

To check yesterday

fun isYesterday(date: Long, comparableDate: Long = System.currentTimeMillis()): Boolean {
   val comparableDateTime = comparableDate.getCalendar()
   val itemDateTime = date.getCalendar()
   comparableDateTime.add(Calendar.DATE, -1)
   return comparableDateTime.get(Calendar.DAY_OF_MONTH) ==
        itemDateTime.get(Calendar.DAY_OF_MONTH) &&
        comparableDateTime.get(Calendar.MONTH) ==
        itemDateTime.get(Calendar.MONTH) &&
        comparableDateTime.get(Calendar.YEAR) ==
        itemDateTime.get(Calendar.YEAR) 
}



fun Long.getCalendar() = Calendar.getInstance().apply {
   timeInMillis = this@getCalendar
}

To call above function use this syntax

context.toReadableDateFormat(1687342714503) // your date in timestamp 
Tippu Fisal Sheriff
  • 2,177
  • 11
  • 19
0

i can suggest you one thing. When u send the sms store the details into a database so that u can display the date and time on which the sms was sent in the history page.

Goofy
  • 6,098
  • 17
  • 90
  • 156
  • Yes iam storing the time in the database. But i need to check whether the stored time is today or yesterday or yesterday before like that. – Manikandan Oct 10 '12 at 12:03
  • if ur storing the time.then why cant u store he date also? – Goofy Oct 10 '12 at 12:04
  • Yes i can but I need to show like "Today 8:00" like that in the textview – Manikandan Oct 10 '12 at 12:06
  • U can do that... get the date from the Db and compare with todays date.if the it matches then display a text view as "Today" if it is current date - revious date then display "Yesterday" – Goofy Oct 10 '12 at 12:08
  • http://stackoverflow.com/questions/2811121/date-comparison-using-java http://java2everyone.blogspot.in/2009/02/compare-current-date-with-user-input.html http://www.roseindia.net/java/example/java/util/CompareDate.shtml – Goofy Oct 10 '12 at 12:14
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/17814/discussion-between-user1498488-and-goofy) – Manikandan Oct 10 '12 at 12:31
0

DateUtils.isToday() should be considered deprecated because android.text.format.Time is now deprecated. Until they update the source code for isToday, there is no solution here that detects today, yesterday, handles shifts to/from daylight saving time, and does not use deprecated code. Here it is in Kotlin, using a today field that must be kept up to date periodically (e.g. onResume etc):

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

I filed https://code.google.com/p/android/issues/detail?id=227694&thanks=227694&ts=1479155729, go vote on it

androidguy
  • 3,005
  • 2
  • 27
  • 38
0

This is the code I ended up with for now:

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
  • 79,669
  • 27
  • 256
  • 428
0

Here is a simple solution that I use:

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

This covers all the edge-cases that may occur.

-2

Without any library and simple code, work on every Kotlin project

//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
  • 2,156
  • 21
  • 26
  • 1
    The provided answer was flagged for review as a Low Quality Post. Here are some guidelines for [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer). This provided answer could benefit from an explanation. Code only answers are not considered "good" answers. From [Review](https://stackoverflow.com/review/low-quality-posts/27297702). – Trenton McKinney Oct 02 '20 at 15:01