1

我可以对我正在尝试制作的这种方法使用一些帮助。我有一个问题对象,它有一个目标日期,与今天的日期相比,我需要找出这个问题延迟了多少天。

想象这种情况:假设今天的日期是05-02-2013

ID  Target date
P1  02-02-2013
P2  27-01-2013
P3  26-01-2013
P4  05-12-2012

这意味着在接下来的几个月中,每个问题都延迟了这么多天:

    DEC JAN FEB
P1          3
P2      4   5
P3      5   5
P4  26  31  5

问题不能超过 12 个月。

现在我需要一种方法来汇总这些数字,存储月份名称和迟到的总和。如果目标月份和现在月份相同,这是一个简单的情况,因为我可以减去天数并存储月份,但如果不是这样怎么办?我有以下代码:

List<Problem> problems = problemQuery.getResultList(); //Problems list is already filtered and contain only late problems. 

Calendar now = Calendar.getInstance();
Calendar before = Calendar.getInstance();
Map<Integer, Integer> newMap = new TreeMap<Integer, Integer>(); //map that contains month number and daysLateCount

for (Problem p : problems) {
    before.setTime(p.getTarget_date());
    int nowMonth = now.get(Calendar.MONTH);
    int beforeMonth = before.get(Calendar.MONTH);
    if (beforeMonth == nowMonth) { //easy case when both dates have same month
        int result = now.get(Calendar.DAY_OF_MONTH) - before.get(Calendar.DAY_OF_MONTH);
        if (newMap.containsKey(nowMonth)) {
            int newLateDaysValue = newMap.get(nowMonth)+result; //get old result and add the new
            newMap.put(nowMonth, newLateDaysValue);
        }                   
        else {
            newMap.put(nowMonth, result);
        }
    }
    else {
                         //What to do here???
    }
}

也许我什至可以跳过 if-else 子句并制作一个可以处理这两种情况的算法?我不知道请帮忙:)

4

4 回答 4

3

最好的方法是使用 Joda Time 库:http ://www.joda.org/joda-time/

Java 日期/时间 API 对于此类目的不是很好,也不是很有用。

于 2013-10-25T09:19:31.083 回答
1

如果只想知道二月有多少天,就需要一年。

    for (Problem p : problems) {
        int nowYear = now.get(Calendar.YEAR);
        int nowMonth = now.get(Calendar.MONTH);
        int nowDay = now.get(Calendar.DAY_OF_MONTH);

        before.setTime(p.getTarget_date());
        int beforeYear = before.get(Calendar.YEAR);
        int beforeMonth = before.get(Calendar.MONTH);
        int beforeDay = before.get(Calendar.DAY_OF_MONTH);
        while (beforeYear < nowYear || beforeMonth < nowMonth) {
            int daysInMonth =
                before.getActualMaximum(Calendar.DAY_OF_MONTH);
            int result = daysInMonth - beforeDay;

            Integer oldLateDaysValue = newMap.get(beforeMonth);
            newMap.put(beforeMonth,
                oldLateDaysValue == null ?
                    result : (oldLateDaysValue + result));

            // For all subsequent months, calculate using entire month.
            beforeDay = 0;

            before.add(Calendar.MONTH, 1);
            beforeYear = before.get(Calendar.YEAR);
            beforeMonth = before.get(Calendar.MONTH);
        }

        int result = nowDay - beforeDay;

        Integer oldLateDaysValue = newMap.get(beforeMonth);
        newMap.put(beforeMonth,
            oldLateDaysValue == null ?
                result : (oldLateDaysValue + result));
    }

    System.out.println(newMap);
}
于 2013-10-25T13:05:40.813 回答
1

使用Joda-Time的解决方案:

LocalDate today = new LocalDate(2013, 2, 5);
LocalDate targetDate = new LocalDate(2012, 12, 5); // example with target date P4

LocalDate begin = targetDate;
LocalDate end = begin.dayOfMonth().withMaximumValue();

while (end.isBefore(today)) {
    Days days = Days.daysBetween(begin, end);
    if (days.getDays() > 0) {
        System.out.println(end.monthOfYear().getAsText() + ": " + days.getDays());
    }

    begin = end;
    end = begin.plusDays(1).dayOfMonth().withMaximumValue();
}

end = today;
Days days = Days.daysBetween(begin, end);
if (days.getDays() > 0) {
    System.out.println(end.monthOfYear().getAsText() + ": " + days.getDays());
}

为目标日期 P4 打印以下结果:

12 月:1 月 26
日:2 月 31
日:5

于 2013-10-25T14:01:15.673 回答
1

我觉得有一个比较简单的解决方案,算法如下:

import java.util.Calendar;

public class test {

    public static void main(String[] args){

        Calendar today = Calendar.getInstance();
        Calendar problemDate = Calendar.getInstance();

        today.set(2013, 01, 05);
        problemDate.set(2012, 11, 05);
        System.out.println(today.getTime());
        System.out.println(problemDate.getTime());

        // This might need further validation to make sure today >= problemDate
        int diffYear = today.get(Calendar.YEAR) - problemDate.get(Calendar.YEAR);
        int differenceInMonths = diffYear * 12 + today.get(Calendar.MONTH) - problemDate.get(Calendar.MONTH);
        //int differenceInMonths = today.get(Calendar.MONTH) - problemDate.get(Calendar.MONTH);

        for(int i = 0; i <= differenceInMonths; i++) {
          int daysDifference;

          if (differenceInMonths == 0) {
             daysDifference = today.get(Calendar.DAY_OF_MONTH) - problemDate.get(Calendar.DAY_OF_MONTH);
          } else {
            if ( i == 0) { // first month
              daysDifference = problemDate.getActualMaximum(Calendar.DAY_OF_MONTH) - problemDate.get(Calendar.DAY_OF_MONTH);
            }
            else if( i == differenceInMonths ) { // last month
              daysDifference = today.get(Calendar.DAY_OF_MONTH);
            }
            else {
              Calendar cal= Calendar.getInstance();
              cal.set(Calendar.MONTH, problemDate.get(Calendar.MONTH) + i);
              daysDifference = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
            } 
                  }

          System.out.println(daysDifference);
        }
    }
}

哪个输出:

Tue Feb 05 14:35:43 GMT 2013
Wed Dec 05 14:35:43 GMT 2012
26
31
5

您应该能够将它包装到您的代码中,并且相当容易地在一个循环中,并且还可以删除打印语句以插入到您拥有的任何数据结构中。

于 2013-10-25T13:41:27.743 回答