Як знайти час сьогодні чи вчора в android


87

Iam розробляє додаток для відправки смс. Iam зберігає поточний час і показує на сторінці відправленої історії, отримуючи час із бази даних. На сторінці відправленої історії я хочу відобразити час надсилання повідомлення. Тут я хочу перевірити, чи повідомлення було надіслано сьогодні або вчора, або вчора раніше. Якщо повідомлення було надіслане вчора, це означає, що мені потрібно відобразити "Вчора 20:00" так, і навіть повідомлення було надіслане вчора перед тим, як означає "Понеділок 20:00". Я не знаю, як це потрібно робити. Будь ласка, допоможіть мені, якщо хтось знає.


будь ласка, покажіть свій код, який ви зробили ...
Гуфі

@Keyser Чи можете ви сказати мені, як це зробити?
Manikandan

2
Оскільки ви ще не спробували жодного коду, ви не знаєте, яка допомога вам знадобиться. Задавати питання передчасно. Зачекайте, поки не побачите, що доставляє вам клопоти.
Девід Шварц,

щоразу, коли ви отримуєте дані з бази даних, отримуйте останній час перетворення у надісланому вікні
Нірав Ранпара

@ user1498488 Просто знайдіть підручники з обробки дати та часу на Java.
keyser

Відповіді:


51

Ви можете легко це зробити, використовуючи клас android.text.format.DateFormat. Спробуйте щось подібне.

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

Перевірте http://developer.android.com/reference/java/text/DateFormat.html для подальшого розуміння.


21
Ви впевнені, що це правильно? Ви порівнюєте лише дати, а рік та місяць? Сьогодні 20.11.2014, але ваш код показує "Сьогодні" для 20.10.2010
Дарин

3
Ця відповідь не правильна. Згідно з документацією, Calendar.DATE є синонімом DAY_OF_MONTH. Тому ви не порівнюєте ні рік, ні місяць.
Жоао Соуса

Так, це неправильно. (Calendar.DATE) == smsTime.get (Calendar.DATE) відповідає лише даті, а не місяцю та році. це повертається вірним для 01.01.2012 та 01.01.2017
Anjum

1
Для тексту "сьогодні" це рішення завжди правильне, а для тексту "вчора" воно не є правильним у перший день місяця. Метод get (Calendar.DATE) повертає день місяця і, наприклад, 1 - 31 = -30 замість 1, що повинно відображати "вчора" - оскільки 31 грудня є попереднім днем ​​1 січня.
lukjar

"Сьогодні" та "вчора" повинні включати місяць і рік у чек, а не лише Календар.ДАТА
ZakariaBK

242

Щоб перевірити, чи є сьогодні дата, скористайтеся бібліотекою UtilS Android

DateUtils.isToday(long timeInMilliseconds)

Цей клас utils також пропонує зручні для читання рядки відносно часу. Наприклад,

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

Кілька параметрів, з якими можна грати, щоб визначити, наскільки точним повинен бути проміжок часу

Див. DateUtils


5
DateUtils.isToday (myDate.getTime ()) працює нормально, дякую!
Loenix

4
Це забирає лише місцевий час (не за UTC) або часові позначки за UTC?
Маттіас

5
DateUtils.isToday(long millis)працює, як описано @Maragues, але майте на увазі, що якщо ви використовуєте цей метод у фрагменті коду, який ви хочете модульно протестувати (наприклад, ViewModel або Presenter), ви отримаєте RuntimeException під час запуску тестів. Це пов’язано з тим, що android.jar, який використовується для модульних тестів, не містить коду. Для отримання додаткової інформації посилання
Каскасі

78

Як уже згадувалося, DateUtils.isToday(d.getTime())буде працювати для визначення, чи Date dє сьогодні. Але деякі відповіді тут насправді не дають відповіді, як визначити, чи була дата вчора. Ви також можете зробити це легко за допомогою DateUtils:

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

Після цього ви також можете визначити, чи була дата завтра:

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

Це має бути прийнятою відповіддю. Простий для читання та ефективний. Єдиним способом зробити його ще більш ефективним було б написання методів для мілімісової позначки часу, щоб можна було використовувати його з календарем, датою або іншим класом, який ви віддаєте перевагу.
joe1806772

Це чудово. Але з якоїсь дивної причини я не можу використовувати це як функцію розширення в fun DateUtils.isYesterday(d: Long): Boolean { return DateUtils.isToday(d + DateUtils.DAY_IN_MILLIS) }
Котліні,

Я думаю, що це найкраще рішення буквально у два рядки коду - це робить роботу
Амір Дора.

22

На сьогоднішній день ви можете використовувати DateUtils.isTodayз андроїд API .

На вчорашній день ви можете використовувати цей код:

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 досконалість!
swooby

Наведений вище код із now.get (Calendar.MONTH), здається, повертає попередній місяць !?
Тіна

@tina це повинно статися лише в перший день місяця
lujop

9

Ви можете спробувати це:

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

7

Якщо ваш рівень API становить 26 або вище, то краще використовувати клас 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
}

Якщо ваш додаток має нижчий рівень API, використовуйте

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

НЕ використовуються ваги


Вчора

Сьогодні

Завтра

Цього року

Будь-який рік

 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

Ще один спосіб зробити це. У котліні з рекомендованою lib ThreeTen

  1. Додайте ThreeTen

    implementation 'com.jakewharton.threetenabp:threetenabp:1.1.0'
    
  2. Додайте розширення kotlin.

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

Це має бути шлях. Спеціальний розбір - це просто погано.
XY

4

Котлін

@Choletski рішення, але з секундами і в 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()
        }
    }

Ви можете перейти сюди, date.getTime()щоб отримати такі результати, як

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

2

Це спосіб отримання таких значень, як Сьогодні, Вчора та Дата, як у додатку Whtsapp

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

Використовуйте цей метод, просто пропустіть мілісекунду, як

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

Ви перевіряли цей код на своєму боці чи будь-яке посилання?
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

я можу запропонувати вам одне. Коли ви надсилаєте sms, зберігайте деталі у базі даних, щоб ви могли відображати дату та час, коли sms було надіслано на сторінці історії.


Так, я зберігаю час у базі даних. Але мені потрібно перевірити, чи зберігається час сьогодні чи вчора чи вчора раніше.
Manikandan

якщо ти зберігаєш час. то чому не можеш також зберігати дату?
Гуфі

Так я можу , але мені потрібно , щоб показати , як «Сьогодні 8:00» як і в TextView
Manikandan

Ви можете це зробити ... отримати дату в базі даних і порівняти з сьогоднішньою датою. Якщо вона збігається, відобразити текстовий вигляд як "Сьогодні", якщо це поточна дата - попередня дата, а потім відобразити "Вчора"
Гуфі


0

DateUtils.isToday()слід вважати застарілою, оскільки android.text.format.Timeвона зараз застаріла. Поки вони не оновлять вихідний код для isToday, тут немає рішення, яке визначає сьогоднішній, вчорашній день, обробляє зміни на / з переходу на літній час і не використовує застарілий код. Ось це в Котліні, використовуючи todayполе, яке потрібно періодично оновлювати (наприклад, onResumeтощо):

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

Я подав https://code.google.com/p/android/issues/detail?id=227694&thanks=227694&ts=1479155729 , проголосуйте за нього


0

Це код, з яким я опинився зараз:

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

Ось просте рішення, яке я використовую:

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

Це охоплює всі випадки крайових ситуацій, які можуть виникнути.


-1

Не маючи бібліотеки та простого коду, працюйте над кожним проектом 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()) {
...
}

Надану відповідь було позначено для розгляду як повідомлення низької якості. Ось декілька вказівок щодо того, як написати хорошу відповідь? . Ця відповідь може отримати користь від пояснення. Відповіді лише за кодом не вважаються "хорошими" відповідями. З огляду .
Трентон Мак-Кінні
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.