Java Android 计算两个日期之间的天数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42553017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:14:11  来源:igfitidea点击:

Android calculate days between two dates

javaandroiddatedatetimekotlin

提问by debo.stackoverflow

I have written the following code to find days between two dates

我编写了以下代码来查找两个日期之间的天数

    startDateValue = new Date(startDate);
    endDateValue = new Date(endDate);
    long diff = endDateValue.getTime() - startDateValue.getTime();
    long seconds = diff / 1000;
    long minutes = seconds / 60;
    long hours = minutes / 60;
    long days = (hours / 24) + 1;
    Log.d("days", "" + days);

When start and end date are 2/3/2017 and 3/3/2017 respectively the number of days showing is 29.Though when they are of the same day it is showing 1.(The number of days one takes a leave.So if one takes a single day leave,he has to select same start and end date.So in this case he has taken two days leave).

当开始日期和结束日期分别为 2/3/2017 和 3/3/2017 时,显示的天数为 29。虽然当它们是同一天时显示为 1。(一个人请假的天数。所以如果一个人休一天假,他必须选择相同的开始和结束日期。所以在这种情况下他休了两天假)。

What am I doing wrong? Thank you for your time.

我究竟做错了什么?感谢您的时间。

Note: Please don't use the date constructor. Check the accepted answer below. Use simpledateformat or Joda time. Date constructor is deprecated.

注意:请不要使用日期构造函数。检查下面接受的答案。使用 simpledateformat 或 Joda 时间。不推荐使用日期构造函数。

采纳答案by SachinSarawgi

Your code for generating date object:

您生成日期对象的代码:

Date date = new Date("2/3/2017"); //deprecated

You are getting 28 days as answer because according to Date(String)constructor it is thinking day = 3,month = 2 and year = 2017

您将得到 28 天作为答案,因为根据Date(String)构造函数,它正在考虑 day = 3,month = 2 and year = 2017

You can convert String to Date as follows:

您可以按如下方式将字符串转换为日期:

String dateStr = "2/3/2017";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date = sdf.parse(dateStr);

Use above template to make your Date object. Then use below code for calculating days in between two dates. Hope this clear the thing.

使用上面的模板来制作你的 Date 对象。然后使用下面的代码计算两个日期之间的天数。希望这清楚的事情。

It can de done as follows:

它可以按如下方式完成:

long diff = endDateValue.getTime() - startDateValue.getTime();
System.out.println ("Days: " + TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));

Please check link

请检查链接

If you use Joda Time it is much more simple:

如果您使用 Joda Time,它会简单得多:

int days = Days.daysBetween(date1, date2).getDays();

Please check JodaTime

请检查JodaTime

How to use JodaTime in Java Project

如何在 Java 项目中使用 JodaTime

回答by Jitendra virani

public static int getDaysDifference(Date fromDate,Date toDate)
{
if(fromDate==null||toDate==null)
return 0;

return (int)( (toDate.getTime() - fromDate.getTime()) / (1000 * 60 * 60 * 24));
}

回答by Anton Balaniuc

Does Androidfully support java-8? If yes you can simple use ChronoUnitclass

Android完全支持java-8?如果是,您可以简单地使用ChronoUnit

LocalDate start = LocalDate.of(2017,2,3);
LocalDate end = LocalDate.of(2017,3,3);

System.out.println(ChronoUnit.DAYS.between(start, end)); // 28

or same thing using formatter

或者同样的事情使用格式化程序

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/yyyy");
LocalDate start = LocalDate.parse("2/3/2017",formatter);
LocalDate end = LocalDate.parse("3/3/2017",formatter);

System.out.println(ChronoUnit.DAYS.between(start, end)); // 28

回答by Janice Kartika

What date format do you use? Is it d/M/yyyyor M/d/yyyy?

你使用什么日期格式?是d/M/yyyy还是M/d/yyyy

d = day, M = month, yyyy = year

d = 日,M = 月,yyyy = 年

(see: https://developer.android.com/reference/java/text/SimpleDateFormat.html)

(参见:https: //developer.android.com/reference/java/text/SimpleDateFormat.html

Then the codes:

然后是代码:

public static final String DATE_FORMAT = "d/M/yyyy";  //or use "M/d/yyyy"   

public static long getDaysBetweenDates(String start, String end) {
    SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH);
    Date startDate, endDate;
    long numberOfDays = 0;
    try {
        startDate = dateFormat.parse(start);
        endDate = dateFormat.parse(end);
        numberOfDays = getUnitBetweenDates(startDate, endDate, TimeUnit.DAYS);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return numberOfDays;
}

And for getUnitBetweenDatesmethod:

对于getUnitBetweenDates方法:

private static long getUnitBetweenDates(Date startDate, Date endDate, TimeUnit unit) {
    long timeDiff = endDate.getTime() - startDate.getTime();
    return unit.convert(timeDiff, TimeUnit.MILLISECONDS);
}

回答by Mr. Mad

Have look at this code , this is helpful for me ,hope it will help you.

看看这段代码,这对我有帮助,希望它能帮助你。

public String get_count_of_days(String Created_date_String, String Expire_date_String) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());

Date Created_convertedDate = null, Expire_CovertedDate = null, todayWithZeroTime = null;
try {
    Created_convertedDate = dateFormat.parse(Created_date_String);
    Expire_CovertedDate = dateFormat.parse(Expire_date_String);

    Date today = new Date();

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

int c_year = 0, c_month = 0, c_day = 0;

if (Created_convertedDate.after(todayWithZeroTime)) {
    Calendar c_cal = Calendar.getInstance();
    c_cal.setTime(Created_convertedDate);
    c_year = c_cal.get(Calendar.YEAR);
    c_month = c_cal.get(Calendar.MONTH);
    c_day = c_cal.get(Calendar.DAY_OF_MONTH);

} else {
    Calendar c_cal = Calendar.getInstance();
    c_cal.setTime(todayWithZeroTime);
    c_year = c_cal.get(Calendar.YEAR);
    c_month = c_cal.get(Calendar.MONTH);
    c_day = c_cal.get(Calendar.DAY_OF_MONTH);
}


/*Calendar today_cal = Calendar.getInstance();
int today_year = today_cal.get(Calendar.YEAR);
int today = today_cal.get(Calendar.MONTH);
int today_day = today_cal.get(Calendar.DAY_OF_MONTH);
*/

Calendar e_cal = Calendar.getInstance();
e_cal.setTime(Expire_CovertedDate);

int e_year = e_cal.get(Calendar.YEAR);
int e_month = e_cal.get(Calendar.MONTH);
int e_day = e_cal.get(Calendar.DAY_OF_MONTH);

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

date1.clear();
date1.set(c_year, c_month, c_day);
date2.clear();
date2.set(e_year, e_month, e_day);

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

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

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

}

}

回答by fuzzKitty

Very simple, just use Calendar, create two instances for the two dates, convert to milliseconds, subtract and convert to days (rounded up)... like this, basically:

很简单,只需使用Calendar,为两个日期创建两个实例,转换为毫秒,减去并转换为天(四舍五入)......像这样,基本上:

Calendar startDate = Calendar.getInstance();
startDate.set(mStartYear, mStartMonth, mStartDay);
long startDateMillis = startDate.getTimeInMillis();

Calendar endDate = Calendar.getInstance();
endDate.set(mEndYear, mEndMonth, mEndDay);
long endDateMillis = endDate.getTimeInMillis();

long differenceMillis = endDateMillis - startDateMillis;
int daysDifference = (int) (differenceMillis / (1000 * 60 * 60 * 24));

回答by grabarz121

Be carefur if you'd like to use received integer e.g. to indicate specific day in custom calendar implementation. For example, I tried to go in m app from monthly calendar view to daily view and show daily content, by calculating dates from 1970-01-01 to selected one, and each 25-31th day of month shows me as one day earlier, because datesDifferenceInMillis / (24 * 60 * 60 * 1000);may return something like 17645,95833333333, and casting this to int you'll get value lower by 1. In this case correctly number of days you'll get by rounding received float by using NumberFormat class. Here's my code:

如果您想使用接收到的整数,例如在自定义日历实现中指示特定日期,请小心。例如,我尝试在 m app 中从月历视图进入每日视图并显示每日内容,通过计算从 1970-01-01 到选定日期的日期,每个月的第 25-31 天将我显示为前一天,因为datesDifferenceInMillis / (24 * 60 * 60 * 1000);可能会返回类似 17645,95833333333 的内容,并将其转换为 int,您将得到的值降低 1。在这种情况下,您可以通过使用 NumberFormat 类对接收到的浮点数进行四舍五入来获得正确的天数。这是我的代码:

NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault());
numberFormat.setRoundingMode(RoundingMode.HALF_UP);
numberFormat.setMaximumFractionDigits(0);
numberFormat.setMinimumFractionDigits(0);
int days = numberFormat.parse(numberFormat.format(value)).intValue();

I hope it will be helpful.

我希望它会有所帮助。

回答by William Hu

Kotlin

科特林

Here is the example to calculate days from today to some date:

以下是计算从今天到某个日期的天数的示例:

 val millionSeconds = yourDate.time - Calendar.getInstance().timeInMillis
 leftDays.text = TimeUnit.MILLISECONDS.toDays(millionSeconds).toString() + "days"

If you want to calculate two days, then change:

如果要计算两天,则更改:

val millionSeconds = yourDate1.time - yourDate2.time

should work.

应该管用。

回答by MaK

I modified Jitendra's answer in Kotlin:

我在 Kotlin 中修改了 Jitendra 的回答:

fun getDaysBetweenDates(firstDateValue: String, secondDateValue: String, format: String): String
{
    val sdf = SimpleDateFormat(format, Locale.getDefault())

    val firstDate = sdf.parse(firstDateValue)
    val secondDate = sdf.parse(secondDateValue)

    if (firstDate == null || secondDate == null)
        return 0.toString()

    return (((secondDate.time - firstDate.time) / (1000 * 60 * 60 * 24)) + 1).toString()
}

and call it like

并称之为

val days = getDaysBetweenDates("31-03-2020", "24-04-2020","dd-MM-yyyy")

回答by Ole V.V.

java.time and ThreeTenABP

java.time 和 ThreeTenABP

If I understand correctly, you want the number of days from start day through end date inclusive.

如果我理解正确,您需要从开始日期到结束日期的天数(包括)

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("d/M/u");

    String startDate = "2/3/2017";
    String endDate = "3/3/2017";

    LocalDate startDateValue = LocalDate.parse(startDate, dateFormatter);
    LocalDate endDateValue = LocalDate.parse(endDate, dateFormatter);
    long days = ChronoUnit.DAYS.between(startDateValue, endDateValue) + 1;

    System.out.println("Days: " + days);

Output:

输出:

Days: 2

天数:2

ChronoUnit.DAYS.between()gives us a count of days from start date inclusive to end date exclusive. So to include the end date too we needed to add 1 day just as you did in the question.

ChronoUnit.DAYS.between()为我们提供了从开始日期到结束日期包括的天数。因此,为了也包括结束日期,我们需要像您在问题中所做的那样添加 1 天。

What went wrong in your code?

你的代码出了什么问题?

You are using the Date(String)constructor. This constructor has been deprecated since 1997 because it works unreliably across time zones, so don't use it. Also it's kind of magical: at least I never really know what I get. Apparently it takes 2/3/2017to mean February 3, 2017, where you intended 2 March 2017. From February 3 to March 3 inclusive is 29 days (since 2017 wasn't a leap year). This explains why you got 29. (If necessary, we could spell our way through the documentation and find out why 2/3/2017is interpreted the way it is, only I'd find that a pointless waste of time to do.)

您正在使用Date(String)构造函数。自 1997 年以来,此构造函数已被弃用,因为它跨时区工作不可靠,因此请勿使用它。这也有点神奇:至少我从来不知道我得到了什么。显然,这2/3/2017意味着 2017 年 2 月 3 日,也就是您原定的 2017 年 3 月 2 日。从 2 月 3 日到 3 月 3 日(含)是 29 天(因为 2017 年不是闰年)。这解释了为什么你得到了 29。(如果有必要,我们可以通过文档拼写我们的方式并找出为什么2/3/2017解释它的方式,只有我会发现这是毫无意义的浪费时间。)

You can't convert from milliseconds.Please also note that not only the question but also the very many answers that convert from milliseconds to days are incorrect. Such a conversion assumes that a day is always 24 hours. Because of summer time (DST) and other time anomalies a day is not always 24 hours. All of those answers will count a day too few for example if the leave crosses the spring gapor spring forwardwhen summer time begins.

你不能从毫秒转换。另请注意,不仅是问题,而且从毫秒转换为天的许多答案都是不正确的。这种转换假设一天总是 24 小时。由于夏令时 (DST) 和其他时间异常,一天并不总是 24 小时。例如,如果休假跨越春季间隙或在夏季开始时向前推进,那么所有这些答案都将计入太少的一天。

Question: Doesn't java.time require Android API level 26?

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

java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

java.time 在较旧和较新的 Android 设备上都能很好地工作。它只需要至少Java 6

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It's called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bpwith subpackages.
  • 在 Java 8 及更高版本和更新的 Android 设备(从 API 级别 26)中,现代 API 是内置的。
  • 在非 Android Java 6 和 7 中获得 ThreeTen Backport,现代类的 backport(ThreeTen for JSR 310;请参阅底部的链接)。
  • 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从org.threeten.bp子包中导入日期和时间类。

Links

链接