【问题标题】:Get correct difference between two selected dates in years, months and days in Android在 Android 中获取年、月和日中两个选定日期之间的正确差异
【发布时间】:2020-08-09 02:42:35
【问题描述】:

如何从 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天。 我试着先得到一个正确的结果,如果有一个函数或计算公式来解决这个错误的结果,这将对我有所帮助。

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

【问题讨论】:

  • 你的意思是我尝试使用Days.between() 方法?如果是的话,我认为这会使我的问题更加复杂,因为结果很长,所以我通常会在数月内遇到问题
  • 你试过你的调试器了吗?
  • 注意你的命名——为了清楚起见,遵循 Java 命名约定。变量应以小写字母开头。我建议修复此处显示的代码,以便其他人阅读。

标签: java android android-studio calendar localdate


【解决方案1】:

你走对了。

  1. 遵循 Java 命名约定。变量或参数名称以小写字母开头。总是。尤其令人困惑的是,您有参数year 和变量Year。这势必会在某些时候导致错误(尽管目前这似乎不是原因)。
  2. 由于您可以使用现代 Java 日期和时间 API java.time 中的 LocalDatePeriod,因此不要混入设计不佳和过时的 Calendar 类,这只会使事情复杂化。您对LocalDatePeriod 的使用基本上是正确的。要以LocalDate 获取当前日期,请使用LocalDate.now(ZoneId.systemDefault())(我们不再需要大写变量,一口气解决了两个问题)。
  3. 我不知道您的日期选择器,但我怀疑它可能使用从 0 开始的月份编号:0 表示 1 月,11 表示 12 月。如果是这样,您需要在创建 LocalDate 对象时将月份数加 1。

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

        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

【讨论】:

  • 感谢 Ole V.V 我在更改变量名称时解决了问题。
【解决方案2】:

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

顺便说一下,你可以试试这个把像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 方法。

【讨论】:

  • 感谢您的回答,但是当我使用 getDays、getMonths 和 getYears 方法时,我每次都会得到 0 的结果。每次当我选择我在 textView 中得到的日期时,我都会谈论错误的结果,我在我的问题中给出了一些像 P2M8D 这样的例子,这就是我在文本视图中得到的结果
  • 你能告诉我你是如何初始化变量 c 的吗?
  • 是的 Alberto Ursino,你是对的 我将 C 的变量命名为选择的名称,我只是将第一个字母改为大写字母,这让我的项目出现了一些问题。
猜你喜欢
  • 2022-10-02
  • 2014-04-07
  • 2013-07-17
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 2016-03-22
相关资源
最近更新 更多