Jak znaleźć czas jest dziś lub wczoraj w Androidzie


87

Zajmuję się tworzeniem aplikacji do wysyłania smsów. Przechowuję aktualny czas i wyświetlam go na stronie historii wysłanych, pobierając czas z bazy danych. Na stronie historii wysłanych chcę wyświetlić czas wysłania wiadomości. Tutaj chcę sprawdzić, czy wiadomość została wysłana dzisiaj, wczoraj lub wczoraj wcześniej. Jeśli wiadomość została wysłana wczoraj, oznacza to, że muszę wyświetlić „Wczoraj 20:00”, a nawet wiadomość wysłana wczoraj oznacza „Poniedziałek 20:00”. Nie wiem, jak to zrobić. Proszę, pomóż mi, jeśli ktoś wie.


proszę wyświetlić kod, który zrobiłeś ...
Goofy

@Keyser Czy możesz mi powiedzieć, jak to zrobić?
Manikandan

2
Ponieważ nie wypróbowałeś jeszcze żadnego kodu, nie wiesz, jakiej pomocy będziesz potrzebować. Zadanie pytania jest przedwczesne. Poczekaj, aż zobaczysz, co sprawia ci kłopoty.
David Schwartz

za każdym razem, gdy pobierasz dane z bazy danych, pobieraj ostatni czas konwersji w wysłanej skrzynce
Nirav Ranpara

@ user1498488 Wystarczy znaleźć kilka samouczków na temat obsługi daty / czasu w języku Java.
Keyser

Odpowiedzi:


51

Możesz to łatwo zrobić za pomocą klasy android.text.format.DateFormat. Spróbuj czegoś takiego.

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

Sprawdź http://developer.android.com/reference/java/text/DateFormat.html, aby uzyskać więcej informacji.


21
Czy na pewno jest to poprawne? Porównujesz tylko daty, a co z rokiem i miesiącem? Dzisiaj jest 20.11.2014, ale Twój kod pokazuje „Dzisiaj” dla 20.10.2010
Daryn

3
Ta odpowiedź jest nieprawidłowa. Zgodnie z dokumentacją Calendar.DATE jest synonimem DAY_OF_MONTH. Dlatego nie porównujecie ani roku, ani miesiąca.
Joao Sousa

Tak, to nieprawda. (Calendar.DATE) == smsTime.get (Calendar.DATE) dopasowuje tylko datę, a nie miesiąc i rok. zwraca prawdę dla 01.01.2012 i 01.01.2017
Anjum,

1
Dla tekstu „dzisiaj” to rozwiązanie jest zawsze poprawne, ale dla tekstu „wczoraj” Nie jest poprawne w pierwszym dniu miesiąca. Metoda get (Calendar.DATE) zwraca dzień miesiąca i na przykład 1 - 31 = -30 zamiast 1, co powinno wyświetlać „wczoraj” - ponieważ 31 grudnia to poprzedni dzień 1 stycznia.
lukjar

Pole „dzisiaj” i „wczoraj” musi zawierać w czeku miesiąc i rok, a nie tylko kalendarz.
DATA

242

Aby sprawdzić, czy data jest dzisiaj, skorzystaj z biblioteki narzędzi Androida

DateUtils.isToday(long timeInMilliseconds)

Ta klasa narzędzi oferuje również ciągi czytelne dla człowieka dla względnych czasów. Na przykład,

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

Istnieje kilka parametrów, którymi możesz się bawić, aby określić, jak dokładny powinien być przedział czasowy

Zobacz DateUtils


5
DateUtils.isToday (myDate.getTime ()) działa poprawnie, dziękuję!
Loenix

4
Czy to zużywa tylko czas lokalny (inny niż UTC) czy tylko znaczniki czasu UTC?
Matthias

5
DateUtils.isToday(long millis)działa zgodnie z opisem @Maragues, ale pamiętaj, że jeśli użyjesz tej metody w fragmencie kodu, który chcesz przetestować jednostkowo (np. ViewModel lub Presenter), podczas wykonywania testów otrzymasz RuntimeException. Wynika to z faktu, że plik android.jar używany do testów jednostkowych nie zawiera żadnego kodu. Aby uzyskać więcej informacji, link
Kaskasi

78

Jak wspomniano, DateUtils.isToday(d.getTime())będzie działać w celu ustalenia, czy Date djest dzisiaj. Ale niektóre odpowiedzi tutaj tak naprawdę nie odpowiadają, jak ustalić, czy data była wczorajsza. Możesz to również łatwo zrobić za pomocą DateUtils:

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

Następnie możesz również określić, czy data jest jutro:

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

To powinna być akceptowana odpowiedź. Prosty do odczytania i skuteczny. Jedynym sposobem, aby uczynić go jeszcze bardziej efektywnym, byłoby napisanie metod dla datownika milisowego, aby można go było używać z kalendarzem, datą lub inną preferowaną klasą.
joe1806772

To jest świetne. Ale z jakiegoś dziwnego powodu nie mogę użyć tego jako funkcji rozszerzenia w Kotlinie, na przykład:fun DateUtils.isYesterday(d: Long): Boolean { return DateUtils.isToday(d + DateUtils.DAY_IN_MILLIS) }
Saifur Rahman Mohsin,

Myślę, że jest to najlepsze rozwiązanie w dosłownie dwóch wierszach kodu, które spełnia swoje zadanie
Amir Dora.

22

Na dziś możesz korzystać DateUtils.isTodayz Android API .

Od wczoraj możesz użyć tego kodu:

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

Powyższy kod z now.get (Calendar.MONTH) wydaje się zwracać poprzedni miesiąc !?
Tina

@tina powinno to nastąpić tylko pierwszego dnia miesiąca
lujop

9

Możesz spróbować tego:

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

7

Jeśli Twój poziom API to 26 lub wyższy, lepiej użyj klasy 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
}

Jeśli Twoja aplikacja ma niższy poziom interfejsu API, użyj

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

Brak używanych bibliotek


Wczoraj

Dzisiaj

Jutro

W tym roku

Każdego roku

 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

Inny sposób na zrobienie tego. W kotlinie z rekomendowaną biblioteką ThreeTen

  1. Dodaj ThreeTen

    implementation 'com.jakewharton.threetenabp:threetenabp:1.1.0'
    
  2. Dodaj rozszerzenia kotlin.

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

To powinna być droga. Niestandardowe parsowanie jest po prostu złe.
XY

4

Kotlin

Rozwiązanie @Choletski, ale z sekundami iw Kotlinie

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

Możesz przejść tutaj, date.getTime()aby uzyskać wyniki takie jak

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

2

Jest to metoda uzyskiwania wartości, takich jak dzisiaj, wczoraj i data, takie jak aplikacja 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);
        }
    }

Użyj tej metody, po prostu podaj milisekundę

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

Czy przetestowałeś ten kod na swojej stronie lub w jakimś odnośniku?
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

Mogę Ci zasugerować jedną rzecz. Kiedy wysyłasz sms, przechowuj szczegóły w bazie danych, abyś mógł wyświetlić datę i godzinę wysłania sms na stronie historii.


Tak, przechowuję czas w bazie danych. Ale muszę sprawdzić, czy zapisany czas jest dzisiaj, wczoraj lub wczoraj przed tak.
Manikandan

jeśli przechowujesz czas. to dlaczego nie możesz przechowywać również daty?
Goofy

Tak, mogę, ale muszę pokazać w widoku
tekstowym

Możesz to zrobić ... pobrać datę z Db i porównać z dzisiejszą datą. Jeśli pasuje, wyświetl tekst jako „Dzisiaj”, jeśli jest to data bieżąca - aktualna data, a następnie wyświetl „Wczoraj”
Goofy


0

DateUtils.isToday()należy uznać za przestarzałe, ponieważ android.text.format.Timejest teraz przestarzałe. Dopóki nie zaktualizują kodu źródłowego isToday, nie ma tutaj rozwiązania, które wykrywa dzisiaj, wczoraj, obsługuje zmiany do / z czasu letniego i nie używa kodu przestarzałego. Tutaj jest w Kotlinie, korzystając z todaypola, które należy okresowo aktualizować (np. onResumeItp.):

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

Złożyłem https://code.google.com/p/android/issues/detail?id=227694&thanks=227694&ts=1479155729 , zagłosuj na to


0

Oto kod, który na razie otrzymałem:

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

Oto proste rozwiązanie, którego używam:

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

Obejmuje to wszystkie skrajne przypadki, które mogą wystąpić.


-1

Bez biblioteki i prostego kodu pracuj nad każdym projektem 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()) {
...
}

Podana odpowiedź została oznaczona do sprawdzenia jako post niskiej jakości. Oto kilka wskazówek, jak napisać dobrą odpowiedź? . Ta udzielona odpowiedź mogłaby skorzystać z wyjaśnienia. Odpowiedzi zawierające tylko kod nie są uważane za „dobre” odpowiedzi. Z recenzji .
Trenton McKinney
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.