-2

I want to find the date range for given list of months. The code which I have written is

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));

                }

Here I am getting :

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

But I want in this format:

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
Jens
  • 67,715
  • 15
  • 98
  • 113
Komal Jain
  • 31
  • 1
  • 2
  • 8
  • 1
    Any particular reason why you are still struggling with the long outdated classes `SimpleDateFormat` and `Calendar`? [The modern Java date and time API known as JSR-310 or `java.time`](https://docs.oracle.com/javase/tutorial/datetime/) is so much nicer to work with. And even more so when it comes to date arithmetic like yours. – Ole V.V. Nov 06 '17 at 14:47
  • What do you want before the range from 2017-05-01 through 2017-06-01? One from 2017-04-30 through 2017-05-31?? – Ole V.V. Nov 06 '17 at 18:33

2 Answers2

1

You are storing only one string per month in your allDates list and trying to use it as "to date" and "from date" which will end in same String for both dates. You should add for each to & from date two different strings. I have modified your loops accordingly:

    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));
    }
Eritrean
  • 15,851
  • 3
  • 22
  • 28
1

It’s fine to store just one date per range. The standard way is to use half-open ranges so that each range goes from one stored date inclusive to the next date exclusive.

I suggest you store dates rather than strings. I find it more natural to format the date whenever a string is needed, than to parse the string (and consider any exceptions from parsing) every time a date is needed.

I wholeheartedly recommend skipping the outdated classes SimpleDateFormat and Calendar and using the modern Java date and time API known as java.time or JSR-310. The latter is so much nicer to work with, as you shall see.

The LocalDate class of java.time matches our need to store dates without time of day very nicely. One further advantage is its toString method produces a string like 2017-10-06, the format you use in your JSON object, so there is no longer any need for an explicit formatter (it’s probably no coincidence: the format is part of the ISO 8601 standard, which is increasingly used for interchange of date and time information, not least in JSON). Also adding and subtracting a day and a month goes more naturally with LocalDate than with Calendar, as long as you remember that a new object is created each time.

    // 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);
    }

Output is:

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

Question: Can I use the modern API with my Java version?

If using at least Java 6, you can.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161