简体   繁体   English

在 Android 中获取年、月和日中两个选定日期之间的正确差异

[英]Get correct difference between two selected dates in years, months and days in Android

How can i get difference between two selected dates from calendar in Android in days, months and years?如何从 Android 中的日历中获得两个选定日期的天数、月数和年数之间的差异? We know all that the months sometimes have 30 days and sometimes 31 days and in February 28 days just every 4 years come 29 days.我们都知道,每个月有时有 30 天,有时有 31 天,而在 2 月 28 天,每隔 4 年就有 29 天。 I want to get the result for example like this: 2 years and 6 months and 24 days.我想得到这样的结果:2 年 6 个月 24 天。 I try to use LocalDate so this is my code:我尝试使用LocalDate所以这是我的代码:

public void onSelectedDayChange(@NonNull CalendarView view,
        final int year, final int month, final int dayOfMonth) {

    textView.setText(String.valueOf(dateDiff(year,month,dayOfMonth)));
}

public Period dateDiff(int year,int month,int day){
    final int Day = c.get(Calendar.DAY_OF_MONTH);
    final int Month = c.get(Calendar.MONTH);
    final int Year = c.get(Calendar.YEAR);
    LocalDate localDate1 = LocalDate.of(year,month,day);
    LocalDate localDate2 = LocalDate.of(Year,Month,Day);

    Period period = Period.between(localDate2,localDate1);

    return period;
}

I tested the code but i got wrong result.我测试了代码,但我得到了错误的结果。 When i test it with days (02/05/2020) i got 8 days but the difference is 7 days because "April" has 30 days and for the selected day (02/07/2020) i got 2 months and 8 days or the correct answer are 2 months and 7 days.当我用天(2020 年 2 月 5 日)测试它时,我得到了 8 天,但差异是 7 天,因为“四月”有 30 天,而对于选定的日子(2020 年 2 月 7 日),我得到了 2 个月零 8 天或正确答案是2个月零7天。 I try to get first a correct result, if there is a function or a calculation formula to solve this wrong result, this will help me.我试着先得到一个正确的结果,如果有一个 function 或一个计算公式来解决这个错误的结果,这将对我有所帮助。

Finally i got in result each time something like (P2M8D) that's meaning 2 months and 8 days, or for example (P7D) that's mean 7 days, so how can i change this text to an understood one like 2 months and 8 days or 7 days like the 2 examples because i found problem in result because we have mixed between numbers and characters.最后我每次都得到结果,比如(P2M8D),意思是 2 个月零 8 天,或者例如(P7D),意思是 7 天,所以我怎样才能将此文本更改为可以理解的文本,例如 2 个月零 8 天或 7像这两个例子一样的日子,因为我发现结果有问题,因为我们混合了数字和字符。

You're well on the right way.你走在正确的道路上。

  1. Follow the Java naming conventions.遵循 Java 命名约定。 A variable or parameter name begins with a lower case letter.变量或参数名称以小写字母开头。 Always.总是。 It's particularly confusing that you've got parameter year and variable Year .您有参数year和变量Year尤其令人困惑。 This is bound to lead to errors at some point (though this doesn't seem to be the reason at the moment).这势必会在某些时候导致错误(尽管目前这似乎不是原因)。
  2. Since you can use LocalDate and Period from java.time, the modern Java date and time API, don't mix in the poorly designed and outdated Calendar class too, it just complicates things. Since you can use LocalDate and Period from java.time, the modern Java date and time API, don't mix in the poorly designed and outdated Calendar class too, it just complicates things. Your use of LocalDate and Period is basically correct.您对LocalDatePeriod的使用基本上是正确的。 For getting the current date as a LocalDate use LocalDate.now(ZoneId.systemDefault()) (and we no longer need the uppercase variables, two problems solved in one shot).为了将当前日期作为LocalDate使用LocalDate.now(ZoneId.systemDefault()) (我们不再需要大写变量,一次性解决了两个问题)。
  3. I don't know your date picker, but I suspect that it may use 0-based month numbers: 0 for January through 11 for December.我不知道您的日期选择器,但我怀疑它可能使用基于 0 的月份编号:0 表示 1 月到 11 表示 12 月。 If this is so, you need to add 1 to the month number when creating the LocalDate object.如果是这样,您需要在创建LocalDate object 时将月份数加 1。

For a more readable text use the methods of the Period object to get numbers and assemble your own string.要获得更易读的文本,请使用Period object 的方法来获取数字并组装您自己的字符串。 A simple example is:一个简单的例子是:

        String periodText = "" + period.getYears() + " years "
                    + period.getMonths() + " months " + period.getDays() + " days";

You will want to modify it to leave out the years if they are 0 and the months if they are 0. Consider what text you want to write if all the numbers are 0. You will want to write something, or the user will be confused.如果它们是 0,你会想要修改它以省略年份,如果它们是 0,则考虑月份。考虑如果所有数字都为 0,你想写什么文本。你会想要写一些东西,否则用户会感到困惑. A further possible refinement will be to use singular of the words if there is exactly 1 ( 1 year rather than 1 years , etc.).如果恰好有 1 ( 1 year而不是1 years等),则进一步可能的改进是使用单词的单数。 You may look into using a StringJoiner and into writing an auxiliary method that returns a string with a number and the correct form of a noun, for example 1 month but 2 months .您可能会考虑使用StringJoiner并编写一个辅助方法,该方法返回一个带有数字和正确形式的名词的字符串,例如1 month2 months

Edit: Code for formatting the Period编辑:格式化期间的代码

Spelling out my suggestion in code, here's a way to format your Period :用代码说明我的建议,这是一种格式化Period的方法:

    StringJoiner joiner = new StringJoiner(" ");
    joiner.setEmptyValue("No time at all");
    if (period.getYears() != 0) {
        joiner.add(singularOrPlural(period.getYears(), "year", "years"));
    }
    if (period.getMonths() != 0) {
        joiner.add(singularOrPlural(period.getMonths(), "month", "months"));
    }
    if (period.getDays() != 0) {
        joiner.add(singularOrPlural(period.getDays(), "day", "days"));
    }
    String periodText = joiner.toString();

    System.out.println(periodText);

The code is using this auxiliary method:代码使用了这个辅助方法:

private static String singularOrPlural(int count, String singular, String plural) {
    if (count == -1 || count == 1) {
        return "" + count + ' ' + singular;
    } else {
        return "" + count + ' ' + plural;
    }
}

Example outputs:示例输出:

 No time at all 1 day 2 days 1 month 1 month 1 day 2 months 3 years 4 months 5 days -1 year -1 month -6 days

I can't understand the problem you have with the "wrong result" of the returned period, clarify it better to me if you can.我无法理解您对返回期间的“错误结果”的问题,如果可以的话,请更好地向我澄清。

By the way, you can try this to convert a format like P2M8D to 2 months and 8 days:顺便说一句,您可以尝试将 P2M8D 之类的格式转换为 2 个月零 8 天:

public static void main(String[] args) {
    int year = 2020, month = 7, day = 2;
    int yearDiff = dateDiff(year, month, day).getYears();
    int monthDiff = dateDiff(year, month, day).getMonths();
    int dayDiff = dateDiff(year, month, day).getDays();
    System.out.println("Period -> yyyy:" + yearDiff + " mm:" + monthDiff + " dd:" + dayDiff); // OUTPUT: Period -> yyyy:0 mm:3 dd:7
}


static Period dateDiff(int year, int month, int day) {
    Calendar c = Calendar.getInstance();
    final int Day = c.get(Calendar.DAY_OF_MONTH);
    final int Month = c.get(Calendar.MONTH);
    final int Year = c.get(Calendar.YEAR);
    LocalDate localDate1 = LocalDate.of(year, month, day);
    LocalDate localDate2 = LocalDate.of(Year, Month, Day);

    return Period.between(localDate2, localDate1);
}

You have to use getDays , getMonths and getYears methods.你必须使用getDaysgetMonthsgetYears方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM