两天之间的Android天数

时间:2014-04-27 13:05:16

标签: android date calendar

我想比较我的Android应用程序的两个日期,但我有一个非常奇怪的问题。

例如:

如果我将back in the past日期设置为127天前:

this.dateEvent = System.currentTimeMillis() - (127 * 24 * 3600 * 1000)

然后将其与当前日期(天之间的天数)进行比较

    Calendar sDate = getDatePart(new Date(this.dateEvent));
    Calendar eDate = getDatePart(new Date(System.currentTimeMillis()));

    int daysBetween = 0;
    while (sDate.before(eDate))
    {
        sDate.add(Calendar.DAY_OF_MONTH, 1);
        daysBetween ++;
    }

    while (sDate.after(eDate))
    {
        eDate.add(Calendar.DAY_OF_MONTH, 1);
        daysBetween ++;
    }

    return daysBetween;

它将返回22,这完全不是预期的。

我是否犯了错误或是Calendar类的问题?

18 个答案:

答案 0 :(得分:95)

这是一个双线解决方案:

long msDiff = Calendar.getInstance().getTimeInMillis() - testCalendar.getTimeInMillis();
long daysDiff = TimeUnit.MILLISECONDS.toDays(msDiff);

在此示例中,它获取日期" testCalendar"之间的天数。和当前日期。

答案 1 :(得分:18)

请参阅此代码,这可能会对您有所帮助。

public String getCountOfDays(String createdDateString, String expireDateString) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());

    Date createdConvertedDate = null, expireCovertedDate = null, todayWithZeroTime = null;
    try {
        createdConvertedDate = dateFormat.parse(createdDateString);
        expireCovertedDate = dateFormat.parse(expireDateString);

        Date today = new Date();

        todayWithZeroTime = dateFormat.parse(dateFormat.format(today));
    } catch (ParseException e) {
        e.printStackTrace();
    }

    int cYear = 0, cMonth = 0, cDay = 0;

    if (createdConvertedDate.after(todayWithZeroTime)) {
        Calendar cCal = Calendar.getInstance();
        cCal.setTime(createdConvertedDate);
        cYear = cCal.get(Calendar.YEAR);
        cMonth = cCal.get(Calendar.MONTH);
        cDay = cCal.get(Calendar.DAY_OF_MONTH);

    } else {
        Calendar cCal = Calendar.getInstance();
        cCal.setTime(todayWithZeroTime);
        cYear = cCal.get(Calendar.YEAR);
        cMonth = cCal.get(Calendar.MONTH);
        cDay = cCal.get(Calendar.DAY_OF_MONTH);
    }


    /*Calendar todayCal = Calendar.getInstance();
    int todayYear = todayCal.get(Calendar.YEAR);
    int today = todayCal.get(Calendar.MONTH);
    int todayDay = todayCal.get(Calendar.DAY_OF_MONTH);
    */

    Calendar eCal = Calendar.getInstance();
    eCal.setTime(expireCovertedDate);

    int eYear = eCal.get(Calendar.YEAR);
    int eMonth = eCal.get(Calendar.MONTH);
    int eDay = eCal.get(Calendar.DAY_OF_MONTH);

    Calendar date1 = Calendar.getInstance();
    Calendar date2 = Calendar.getInstance();

    date1.clear();
    date1.set(cYear, cMonth, cDay);
    date2.clear();
    date2.set(eYear, eMonth, eDay);

    long diff = date2.getTimeInMillis() - date1.getTimeInMillis();

    float dayCount = (float) diff / (24 * 60 * 60 * 1000);

    return ("" + (int) dayCount + " Days");
}

答案 2 :(得分:9)

我终于找到了解决问题的最简单方法。这是我的代码:

public int getTimeRemaining()
{
    Calendar sDate = toCalendar(this.dateEvent);
    Calendar eDate = toCalendar(System.currentTimeMillis());

    // Get the represented date in milliseconds
    long milis1 = sDate.getTimeInMillis();
    long milis2 = eDate.getTimeInMillis();

    // Calculate difference in milliseconds
    long diff = Math.abs(milis2 - milis1);

    return (int)(diff / (24 * 60 * 60 * 1000));
}

private Calendar toCalendar(long timestamp)
{
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(timestamp);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar;
}

希望它有所帮助。

答案 3 :(得分:4)

public long Daybetween(String date1,String date2,String pattern)
{
    SimpleDateFormat sdf = new SimpleDateFormat(pattern,Locale.ENGLISH);
    Date Date1 = null,Date2 = null;
    try{
        Date1 = sdf.parse(date1);
        Date2 = sdf.parse(date2);
    }catch(Exception e)
    {
        e.printStackTrace();
    }
    return (Date2.getTime() - Date1.getTime())/(24*60*60*1000);
}

答案 4 :(得分:4)

    Date userDob = new SimpleDateFormat("yyyy-MM-dd").parse(dob);
    Date today = new Date();
    long diff =  today.getTime() - userDob.getTime();
    int numOfYear = (int) ((diff / (1000 * 60 * 60 * 24))/365);
    int numOfDays = (int) (diff / (1000 * 60 * 60 * 24));
    int hours = (int) (diff / (1000 * 60 * 60));
    int minutes = (int) (diff / (1000 * 60));
    int seconds = (int) (diff / (1000));

答案 5 :(得分:3)

最好的方法: -

        long fromCalender = Calender.getInstance();
        fromCalender.set...// set the from dates
        long toCalender = Calender.getInstance();
        fromCalender.set...// set the to dates

        long diffmili = fromCalender - toCalender;

        long hours = TimeUnit.MILLISECONDS.toHours(diffmili);
        long days = TimeUnit.MILLISECONDS.toDays(diffmili);
        long min = TimeUnit.MILLISECONDS.toMinutes(diffmili);
        long sec = TimeUnit.MILLISECONDS.toSeconds(diffmili);

答案 6 :(得分:3)

你永远不应该使用24 * 60 * 60 * 1000这样的公式!为什么?因为有节省时间,并且不是所有日子都有24小时,所以闰年也有+1天。这就是为什么有日历类的原因。 如果你不想像Jodatime那样把任何外部库放到你的项目中,你可以使用具有非常高效功能的纯Calendar类:

s = some_function.evalf(subs={x:a , y:b})

答案 7 :(得分:2)

我有同样的需求,最后我最终使用了Joda Time,它非常方便,并提供了许多附加功能,包括你正在寻找的功能。

您可以从here下载文件。

将jar文件包含到项目中后,您可以轻松完成以下操作:

int daysBetween = Days.daysBetween(new DateTime(sDate), new DateTime(eDate)).getDays();

答案 8 :(得分:1)

对我有用的最佳解决方案是:

private static int findDaysDiff(long unixStartTime,long unixEndTime)
    {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTimeInMillis(unixStartTime);
        calendar1.set(Calendar.HOUR_OF_DAY, 0);
        calendar1.set(Calendar.MINUTE, 0);
        calendar1.set(Calendar.SECOND, 0);
        calendar1.set(Calendar.MILLISECOND, 0);

        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTimeInMillis(unixEndTime);
        calendar2.set(Calendar.HOUR_OF_DAY, 0);
        calendar2.set(Calendar.MINUTE, 0);
        calendar2.set(Calendar.SECOND, 0);
        calendar2.set(Calendar.MILLISECOND, 0);

        return (int) ((calendar2.getTimeInMillis()-calendar1.getTimeInMillis())/(24 * 60 * 60 * 1000));

    }

因为它首先将HourMinuteSecondMillisecond转换为0,现在差异只会是几天。

答案 9 :(得分:1)

这样做,它支持所有Api级别

    Calendar cal = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy HH:mm:ss", 
    Locale.ENGLISH);
    try {
        String datestart="June 14 2018 16:02:37";
        cal.setTime(sdf.parse(datestart));// all done
         Calendar cal1=Calendar.getInstance();
        String formatted = sdf.format(cal1.getTime());//formatted date as i want
        cal1.setTime(sdf.parse(formatted));// all done

        long msDiff = cal1.getTimeInMillis() - cal.getTimeInMillis();
        long daysDiff = TimeUnit.MILLISECONDS.toDays(msDiff);
        Toast.makeText(this, "days="+daysDiff, Toast.LENGTH_SHORT).show();
    } catch (ParseException e) {
        e.printStackTrace();
    }

答案 10 :(得分:1)

Kotlin扩展名:

fun Date?.getDaysBetween(dest: Date?): Int {

    if(this == null || dest == null) return 0

    val diff = abs(this.time - dest.time)
    val dayCount = diff.toFloat() / (24 * 60 * 60 * 1000)
    return dayCount.toInt()
}

答案 11 :(得分:1)

java.time和ThreeTenABP

我想贡献一个现代的答案:使用java.time,现代的Java日期和时间API进行日期工作。如果是针对25级或更低级别的Android API进行开发,请通过Android的反向端口ThreeTenABP(底部链接)。

    LocalDate eDate = LocalDate.now(ZoneId.of("Europe/Paris"));
    LocalDate sDate = eDate.minusDays(127);

    long daysBetween = ChronoUnit.DAYS.between(sDate, eDate);
    System.out.println(daysBetween);

今天我运行这段代码时,输​​出是预期的结果:

127

请注意,代码不仅更短,而且只有一行可以找到差异。它也更加清晰自然。您使用的类DateCalendar设计得很差,而且已经过时了。我建议您不要使用它们。

您的代码出了什么问题?

从127天到毫秒的转换中,您的int溢出了。在数学中,127 * 24 * 3600 * 1000等于10 972 800000。由于您乘以的数字是int,因此Java在int中执行乘法,而最大的数字int可以保留为2 147 483 647,远远不够您的预期结果。在这种情况下,如果Java抛出异常或以其他方式使我们意识到该错误,那将是很好的。没错它默认丢弃高阶位,结果为-1 912 101888。从当前时间中减去此负数等效于增加22天零几个小时。这就解释了为什么要22。有趣的是,已经发布了13个答案,而且似乎没有人发现这个答案……

即使使用long类型进行乘法运算,它仍然无法正确计算127天。如果这127天跨越了到夏令时(DST)的过渡(法国在一年的365天中的254天就是这种情况),那么过渡天不是24小时,而是23或25小时。这导致错误的毫秒数。

您应该始终将日期数学留给经过验证的库方法。切勿自己编写代码。它比我们大多数人想象的要复杂,因此不正确地进行操作的风险很高。

问题:java.time是否不需要Android API级别26?

java.time在较新和较旧的Android设备上均可正常运行。它只需要至少 Java 6

  • 在Java 8和更高版本以及更新的Android设备(API级别26以上)中,内置了现代API。
  • 在非Android Java 6和7中,获得ThreeTen Backport,这是现代类的backport(JSR 310的ThreeTen;请参见底部的链接)。
  • 在旧版Android上,请使用Android版的ThreeTen Backport。称为ThreeTenABP。并确保使用子包从org.threeten.bp导入日期和时间类。

链接

答案 12 :(得分:0)

int difference in days=(present_year - oldyear) * 365 + (present_month - oldmonth)*30 + (present_date-olddate);

答案 13 :(得分:0)

我刚刚修改了一些最受欢迎的答案。 这是我的解决方案: daysBetween()-返回两个日期之间的天数。

public static long daysBetween(Date date1, Date date2) {
        long msDiff = resetTimeToDateStart(date1).getTime() - resetTimeToDateStart(date2).getTime();
        return TimeUnit.MILLISECONDS.toDays(msDiff);
    }
private static Date resetTimeToDateStart(Date dDate){
        if (Utils.isNull(dDate)){
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dDate);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

答案 14 :(得分:0)

这是Java 8 java.time版本,非常适合我。您可能需要确保将startDate和endDate设置为相同的时间,否则天数可能会因+-1而异! 这些是我刚刚复制/粘贴的Kotlin版本。

private fun getDawnOfDay(instant: Instant): Temporal =
        LocalDate.from(instant.atZone(ZoneOffset.UTC)).atStartOfDay()

fun getNumberOfDaysInBetween(startDate: Date, endDate: Date) =
        Duration.between(getDawnOfDay(startDate.toInstant()), getDawnOfDay(endDate.toInstant()))
            .toDays()

答案 15 :(得分:0)

我计算的是从上次提交日期到当前日期之间的天数,如果该天数小于零,那么学生将无法进行提交。我正在和科特琳一起工作。下面的代码可以帮助您。

 var calendar=Calendar.getInstance().time
 var dateFormat= SimpleDateFormat("dd/M/yyyy")
 var d2=dateFormat.parse(data.get("date").toString())
 var cd=dateFormat.format(calendar)
 var d1=dateFormat.parse(cd)
 var diff=d2.time-d1.time
 var ddd= TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS)

答案 16 :(得分:0)

fun TimeZone.daysBetween(from: Date, to: Date): Int {
    val offset = rawOffset + dstSavings
    return ((to.time + offset) / 86400000).toInt() - ((from.time + offset) / 86400000).toInt()
}

尝试一下:

    val f = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").apply {
        timeZone = TimeZone.getTimeZone("GMT")
    }
    val df = f.parse("2019-02-28 22:59:59")
    val dt = f.parse("2019-02-28 23:00:00")

    TimeZone.getTimeZone("GMT").daysBetween(df, dt)  // 0
    TimeZone.getTimeZone("GMT+1").daysBetween(df, dt) // 1

答案 17 :(得分:0)

在某些日期,答案是不正确的,例如" 2019/02/18" ," 2019/02/19"但我编辑并解决了错误

这是最好的方法:

 public int getCountOfDays(String createdDateString, String expireDateString) {

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        Date createdConvertedDate = null;
        Date expireCovertedDate = null;
        try {
            createdConvertedDate = dateFormat.parse(createdDateString);
            expireCovertedDate = dateFormat.parse(expireDateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }


        Calendar start = new GregorianCalendar();
        start.setTime(createdConvertedDate);

        Calendar end = new GregorianCalendar();
        end.setTime(expireCovertedDate);

        long diff = end.getTimeInMillis() - start.getTimeInMillis();

        float dayCount = (float) diff / (24 * 60 * 60 * 1000);


        return (int) (dayCount);
    }

享受,如果是helpefull +投票给这个答案;)