Как узнать время сегодня или вчера в android

87

Разрабатываю приложение для отправки смс. Я сохраняю текущее время и показываю его на отправленной странице истории, получая время из базы данных. На странице истории отправки я хочу отобразить время отправки сообщения. Здесь я хочу проверить, было ли сообщение отправлено сегодня, или вчера, или вчера, вот так. Если сообщение было отправлено вчера, значит, мне нужно отобразить «Вчера 20:00» таким образом, и даже сообщение было отправлено вчера, раньше означает «Понедельник 20:00». Я не знаю, как это сделать. Пожалуйста, помогите мне, если кто-нибудь знает.

Manikandan
источник
пожалуйста, покажите свой код, который вы сделали ...
Гуфи
@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) соответствует только дате, а не месяцу и году. возвращает true для 01.01.2012 и 01.01.2017
Anjum
1
Для текста «сегодня» это решение всегда верно, а для текста «вчера» оно неверно в первый день месяца. Метод get (Calendar.DATE) возвращает день месяца и, например, 1 - 31 = -30 вместо 1, что должно отображать «вчера», потому что 31 декабря - это предыдущий день 1 января.
lukjar
«Сегодня» и «вчера» должны включать месяц и год в чеке, а не только календарь.
ДАТА
242

Чтобы проверить, наступила ли дата сегодня, используйте библиотеку утилит Android.

DateUtils.isToday(long timeInMilliseconds)

Этот класс utils также предлагает удобочитаемые строки для относительного времени. Например,

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

Вот несколько параметров, с которыми вы можете поиграть, чтобы определить, насколько точным должен быть временной интервал.

См. DateUtils

Maragues
источник
5
DateUtils.isToday (myDate.getTime ()) работает нормально, спасибо!
Loenix 04
4
Используется ли только местное (не UTC) время или временные метки UTC?
Matthias
5
DateUtils.isToday(long millis)работает, как описано в @Maragues, но имейте в виду, что если вы используете этот метод в фрагменте кода, который хотите провести модульное тестирование (например, ViewModel или Presenter), вы получите исключение RuntimeException при выполнении ваших тестов. Это связано с тем, что файл android.jar, используемый для модульных тестов, не содержит кода. Ссылка
Kaskasi
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);
}
Thebaer
источник
Это должен быть принятый ответ. Легко читать и эффективно. Единственный способ сделать его еще более эффективным - написать методы для метки времени в миллисекундах, чтобы их можно было использовать с Calendar, Date или любым другим классом, который вы предпочитаете.
joe1806772
Это круто. Но по какой-то странной причине я не могу использовать это как функцию расширения в Котлине, например:fun DateUtils.isYesterday(d: Long): Boolean { return DateUtils.isToday(d + DateUtils.DAY_IN_MILLIS) }
Сайфур Рахман Мохсин,
Я думаю, что это лучшее решение буквально в двух строчках кода, оно выполняет свою работу
Амир Дора.
22

На сегодняшний день вы можете использовать DateUtils.isTodayиз Android 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);
}
Lujop
источник
@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

НИКАКИЕ библиотеки не используются


Вчера

Cегодня

Завтра

В этом году

В любой год

 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

Другой способ сделать это. В котлине с рекомендованной библиотекой 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, но с секундами и в Котлине

 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
Gastón Saillén
источник
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()
        }
    }
}
EpicPandaForce
источник
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()) {
...
}
Anthone
источник
Предоставленный ответ был отмечен для просмотра как сообщение низкого качества. Вот несколько советов о том, как написать хороший ответ? . Этот предоставленный ответ может выиграть от объяснения. Ответы только на код не считаются "хорошими" ответами. Из обзора .
Трентон МакКинни,