如何查找给定月份的日期范围

时间:2017-11-06 12:56:27

标签: java json date datetime simpledateformat

我想查找给定月份列表的日期范围。我写的代码是

List<String> allDates = new ArrayList<>();
                String maxDate = "2017-11-06";
                SimpleDateFormat monthDate = new SimpleDateFormat("yyyy-MM-dd");
                Calendar cal = Calendar.getInstance();
                cal.setTime(monthDate.parse(maxDate));

            for (int i = 1; i <= 14; i++) {
                    String month_name1 = monthDate.format(cal.getTime());
                    allDates.add(month_name1);
                    cal.add(Calendar.MONTH, -1);
                }
                for (int j = 0; j < allDates.size() - 1; j++) {
                    JSONObject dateRange = new JSONObject();
                    dateRange.put("until", allDates.get(j)); 
                    System.out.println("to date:"+allDates.get(j));
                    dateRange.put("since", allDates.get(j + 1));
                    System.out.println("from date:"+ allDates.get(j + 1));

                }

我来了:

to date:2017-11-06
from date:2017-10-06
to date:2017-10-06
from date:2017-09-06
to date:2017-09-06
from date:2017-08-06
to date:2017-08-06
from date:2017-07-06
to date:2017-07-06
from date:2017-06-06
to date:2017-06-06

但我想要这种格式:

to date:2017-11-06
from date:2017-10-06
to date:2017-10-05
from date:2017-09-05
to date:2017-09-04
from date:2017-08-04
to date:2017-08-03
from date:2017-07-03
to date:2017-07-02
from date:2017-06-02

3 个答案:

答案 0 :(得分:1)

您每月只在您的所有日期列表中存储一个字符串并尝试将其用作&#34;到目前为止&#34;和#34;从日期&#34;这两个日期将以相同的字符串结尾。你应该为每个添加&amp;从日期两个不同的字符串。我相应地修改了你的循环:

    for (int i = 1; i <= 14; i++) {              
        String month_name1 = monthDate.format(cal.getTime());            
        allDates.add(month_name1);
        cal.add(Calendar.MONTH, -1);
        month_name1 = monthDate.format(cal.getTime());
        allDates.add(month_name1);            
        cal.add(Calendar.DATE, -1);   
    }
    for (int j = 0; j < allDates.size() - 1; j+=2) {
        JSONObject dateRange = new JSONObject();
        dateRange.put("until", allDates.get(j)); 
        System.out.println("to date:"+allDates.get(j));
        dateRange.put("since", allDates.get(j + 1));
        System.out.println("from date:"+ allDates.get(j + 1));
    }

答案 1 :(得分:1)

每个范围只存储一个日期。标准方法是使用半开范围,以便每个范围从一个存储日期包含到下一个日期独占

我建议您存储日期而不是字符串。我发现每当需要字符串时格式化日期比在每次需要日期时解析字符串(并考虑解析的任何异常)更自然。

我全心全意地建议您跳过过时的课程SimpleDateFormatCalendar并使用the modern Java date and time API known as java.time or JSR-310。正如您将看到的那样,后者可以更好地使用。

LocalDate java.time类匹配我们需要非常好地存储日期。另一个优点是它的toString方法产生一个像2017-10-06这样的字符串,你在JSON对象中使用的格式,所以不再需要一个显式的格式化程序(这可能不是巧合:格式是ISO 8601标准的一部分,越来越多地用于交换日期和时间信息,尤其是在JSON中。只要您记住每次都创建一个新对象,使用LocalDate而不是Calendar更加自然地添加和减去一天和一个月。

    // store only the start date of each range
    List<LocalDate> allStartDates = new ArrayList<>();
    // add 1 day ot the last end date to obtain the start day of the following range
    LocalDate currentStartDate = LocalDate.of(2017, Month.NOVEMBER, 06).plusDays(1);

    for (int i = 1; i <= 14; i++) {
        allStartDates.add(currentStartDate);
        currentStartDate = currentStartDate.minusDays(1).minusMonths(1);
    }
    for (int j = 1; j < allStartDates.size(); j++) {
        JSONObject dateRange = new JSONObject();
        // subtract 1 day from the start day of the following range
        // to get the last day of this range 
        String endDate = allStartDates.get(j - 1).minusDays(1).toString();
        dateRange.put("until", endDate); 
        System.out.println("to date:" + endDate);
        String startDate = allStartDates.get(j).toString();
        dateRange.put("since", startDate);
        System.out.println("from date:" + startDate);
    }

输出是:

to date:2017-11-06
from date:2017-10-06
to date:2017-10-05
from date:2017-09-05
to date:2017-09-04
from date:2017-08-04
to date:2017-08-03
from date:2017-07-03
to date:2017-07-02
from date:2017-06-02
to date:2017-06-01
from date:2017-05-01
to date:2017-04-30
from date:2017-03-30
to date:2017-03-29
from date:2017-02-28
to date:2017-02-27
from date:2017-01-27
to date:2017-01-26
from date:2016-12-26
to date:2016-12-25
from date:2016-11-25
to date:2016-11-24
from date:2016-10-24
to date:2016-10-23
from date:2016-09-23

问题:我可以在Java版本中使用现代API吗?

如果至少使用Java 6 ,则可以。

答案 2 :(得分:0)

根据您的预期列表,您还希望减少日期。因此,您需要为DATE添加增量。

cal.add(Calendar.DATE, -1);