繁体   English   中英

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

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

如何从 Android 中的日历中获得两个选定日期的天数、月数和年数之间的差异? 我们都知道,每个月有时有 30 天,有时有 31 天,而在 2 月 28 天,每隔 4 年就有 29 天。 我想得到这样的结果:2 年 6 个月 24 天。 我尝试使用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;
}

我测试了代码,但我得到了错误的结果。 当我用天(2020 年 2 月 5 日)测试它时,我得到了 8 天,但差异是 7 天,因为“四月”有 30 天,而对于选定的日子(2020 年 2 月 7 日),我得到了 2 个月零 8 天或正确答案是2个月零7天。 我试着先得到一个正确的结果,如果有一个 function 或一个计算公式来解决这个错误的结果,这将对我有所帮助。

最后我每次都得到结果,比如(P2M8D),意思是 2 个月零 8 天,或者例如(P7D),意思是 7 天,所以我怎样才能将此文本更改为可以理解的文本,例如 2 个月零 8 天或 7像这两个例子一样的日子,因为我发现结果有问题,因为我们混合了数字和字符。

你走在正确的道路上。

  1. 遵循 Java 命名约定。 变量或参数名称以小写字母开头。 总是。 您有参数year和变量Year尤其令人困惑。 这势必会在某些时候导致错误(尽管目前这似乎不是原因)。
  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. 您对LocalDatePeriod的使用基本上是正确的。 为了将当前日期作为LocalDate使用LocalDate.now(ZoneId.systemDefault()) (我们不再需要大写变量,一次性解决了两个问题)。
  3. 我不知道您的日期选择器,但我怀疑它可能使用基于 0 的月份编号:0 表示 1 月到 11 表示 12 月。 如果是这样,您需要在创建LocalDate object 时将月份数加 1。

要获得更易读的文本,请使用Period object 的方法来获取数字并组装您自己的字符串。 一个简单的例子是:

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

如果它们是 0,你会想要修改它以省略年份,如果它们是 0,则考虑月份。考虑如果所有数字都为 0,你想写什么文本。你会想要写一些东西,否则用户会感到困惑. 如果恰好有 1 ( 1 year而不是1 years等),则进一步可能的改进是使用单词的单数。 您可能会考虑使用StringJoiner并编写一个辅助方法,该方法返回一个带有数字和正确形式的名词的字符串,例如1 month2 months

编辑:格式化期间的代码

用代码说明我的建议,这是一种格式化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);

代码使用了这个辅助方法:

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

示例输出:

 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

我无法理解您对返回期间的“错误结果”的问题,如果可以的话,请更好地向我澄清。

顺便说一句,您可以尝试将 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);
}

你必须使用getDaysgetMonthsgetYears方法。

暂无
暂无

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

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