簡體   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