วิธีค้นหาเวลาคือวันนี้หรือเมื่อวานใน Android


89

เอี่ยมพัฒนาแอพพลิเคชั่นสำหรับส่ง sms Iam จัดเก็บเวลาปัจจุบันและแสดงในหน้าประวัติที่ส่งโดยการดึงเวลาจากฐานข้อมูล ในหน้าประวัติการส่งฉันต้องการแสดงเวลาที่ส่งข้อความ ที่นี่ฉันต้องการตรวจสอบว่าข้อความถูกส่งวันนี้หรือเมื่อวานนี้หรือเมื่อวานก่อนแบบนั้น ถ้าข้อความถูกส่งเมื่อวานหมายความว่าฉันต้องแสดง "เมื่อวาน 20:00" แบบนั้นและแม้แต่ข้อความก็ถูกส่งไปเมื่อวานก่อนก็หมายความว่า "วันจันทร์ 20:00 น." ฉันไม่รู้ว่ามันต้องทำยังไง โปรดช่วยฉันถ้าใครรู้


โปรดแสดงรหัสของคุณที่คุณได้ทำ ...
ขำ

@Keyser ช่วยบอกวิธีทำหน่อยได้ไหม?
มณีกานดา

2
เนื่องจากคุณยังไม่ได้ลองใช้รหัสใด ๆ คุณจึงไม่รู้ว่าคุณต้องการความช่วยเหลืออะไร การถามคำถามจะเกิดขึ้นก่อนเวลาอันควร รอจนกว่าคุณจะเห็นว่าอะไรทำให้คุณมีปัญหา
David Schwartz

เมื่อใดก็ตามที่คุณดึงข้อมูลจากฐานข้อมูลดึงข้อมูลครั้งสุดท้ายของการแปลงในกล่องที่ส่ง
Nirav Ranpara

@ user1498488 เพียงแค่ค้นหาบทเรียนเกี่ยวกับการจัดการวันที่ / เวลาของ Java
คีย์เซอร์

คำตอบ:


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
Daryn

4
คำตอบนี้ไม่ถูกต้อง ตามเอกสารประกอบ Calendar.DATE เป็นคำพ้องความหมายของ DAY_OF_MONTH ดังนั้นคุณจะไม่เปรียบเทียบทั้งปีหรือเดือน
Joao Sousa

ใช่มันไม่ถูกต้อง (Calendar.DATE) == smsTime.get (Calendar.DATE) ตรงกับวันที่เท่านั้นไม่ใช่เดือนและปี มันคืนค่าจริงสำหรับ 01.01.2012 และ 01.01.2017
Anjum

1
สำหรับข้อความ "วันนี้" วิธีแก้ปัญหานี้ถูกต้องเสมอ แต่สำหรับข้อความ "เมื่อวาน" ไม่ถูกต้องในวันแรกของเดือน Method get (Calendar.DATE) ส่งคืนวันของเดือนและตัวอย่างเช่น 1 - 31 = -30 แทน 1 สิ่งที่ควรแสดง "เมื่อวาน" - เนื่องจากวันที่ 31 ธันวาคมเป็นวันก่อนหน้าของวันที่ 1 มกราคม
lukjar

"วันนี้" และ "เมื่อวาน" จะต้องรวมเดือนและปีไว้ในเช็คไม่ใช่เฉพาะ Calendar.DATE
ZakariaBK

245

หากต้องการตรวจสอบว่าวันนี้เป็นวันที่หรือไม่ให้ใช้ไลบรารีโปรแกรมประยุกต์ของ Android

DateUtils.isToday(long timeInMilliseconds)

คลาส utils นี้ยังมีสตริงที่มนุษย์อ่านได้สำหรับเวลาสัมพัทธ์ ตัวอย่างเช่น,

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

คุณสามารถใช้พารามิเตอร์หลายตัวเพื่อกำหนดช่วงเวลาที่แม่นยำได้

ดูDateUtils


5
DateUtils.isToday (myDate.getTime ()) ทำงานได้ดีขอบคุณ!
Loenix

4
นี่ใช้เวลาท้องถิ่น (ไม่ใช่ UTC) หรือการประทับเวลา UTC เท่านั้นหรือไม่
Matthias

5
DateUtils.isToday(long millis)ทำงานตามที่ @Maragues อธิบายไว้ แต่โปรดทราบว่าหากคุณใช้วิธีนี้ในโค้ดส่วนหนึ่งที่คุณต้องการทดสอบหน่วย (เช่น ViewModel หรือ Presenter) คุณจะได้รับ RuntimeException เมื่อเรียกใช้การทดสอบของคุณ เนื่องจาก android.jar ที่ใช้สำหรับการทดสอบหน่วยไม่มีรหัสใด ๆ สำหรับลิงค์
Kaskasi

82

ดังที่ได้กล่าวไว้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);
}

1
นี่ควรเป็นคำตอบที่ได้รับการยอมรับ อ่านง่ายและมีประสิทธิภาพ วิธีเดียวที่จะทำให้มีประสิทธิภาพมากขึ้นคือการเขียนวิธีการประทับเวลามิลลิวินาทีเพื่อให้สามารถใช้กับปฏิทินวันที่หรือชั้นเรียนใดก็ได้ที่คุณต้องการ
joe1806772

นี่มันเยี่ยมมาก แต่ด้วยเหตุผลแปลก ๆ ฉันไม่สามารถใช้สิ่งนี้เป็นฟังก์ชันส่วนขยายใน Kotlin เช่น:fun DateUtils.isYesterday(d: Long): Boolean { return DateUtils.isToday(d + DateUtils.DAY_IN_MILLIS) }
Saifur Rahman Mohsin

ฉันคิดว่านี่เป็นทางออกที่ดีที่สุดในสองบรรทัดของโค้ดที่ทำให้งานสำเร็จ
Amir Dora

มันได้ผล ขอบคุณ: D !!
ppreetikaa

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

@tina น่าจะเกิดขึ้นในวันแรกของเดือนเท่านั้น
lujop

9

คุณสามารถลองสิ่งนี้:

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

8

หากระดับ 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

ไม่มีการใช้ libs


เมื่อวานนี้

วันนี้

พรุ่งนี้

ปีนี้

ปีใดก็ได้

 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

อีกวิธีหนึ่งที่จะทำได้ ในkotlinด้วย 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

Kotlin

โซลูชัน @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 ในหน้าประวัติได้


ใช่ฉันเก็บเวลาไว้ในฐานข้อมูล แต่ฉันต้องตรวจสอบว่าเวลาที่เก็บไว้คือวันนี้หรือเมื่อวานหรือเมื่อวานก่อนแบบนั้น
มณีกานดา

ถ้าคุณเก็บเวลาแล้วทำไมคุณไม่สามารถเก็บเขาวันที่ด้วย?
ขำ

ใช่ฉันทำได้ แต่ฉันต้องแสดง "วันนี้ 8:00" แบบนั้นใน textview
Manikandan

คุณสามารถทำได้ ... รับวันที่จาก Db และเปรียบเทียบกับวันที่ของวันนี้หากตรงกันจากนั้นจะแสดงมุมมองข้อความเป็น "วันนี้" หากเป็นวันที่ปัจจุบัน - วันที่ย้อนกลับจากนั้นแสดง "เมื่อวาน"
ขำ


0

DateUtils.isToday()ควรถือว่าเลิกใช้งานแล้วเพราะandroid.text.format.Timeตอนนี้เลิกใช้งานแล้ว จนกว่าพวกเขาจะอัปเดตซอร์สโค้ดสำหรับ isToday ไม่มีวิธีแก้ปัญหาใดที่ตรวจพบวันนี้เมื่อวานจัดการกะเป็น / จากเวลาออมแสงและไม่ใช้รหัสที่เลิกใช้แล้ว ที่นี่อยู่ใน Kotlin โดยใช้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()) {
...
}

คำตอบที่ให้ไว้ถูกระบุว่าเป็นโพสต์คุณภาพต่ำ คำแนะนำบางประการสำหรับฉันจะเขียนคำตอบที่ดีได้อย่างไร . คำตอบที่ให้มานี้จะได้ประโยชน์จากคำอธิบาย คำตอบที่ใช้โค้ดเท่านั้นไม่ถือว่าเป็นคำตอบที่ "ดี" จากรีวิว .
Trenton McKinney
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.