user6096489
user6096489

Reputation:

How to Iterate through a range of dates?

I am trying to iterate through strings of dates. The strings are in the format like this 2000.07.28. I tried converting them to doubles but then it complains. I also need to keep the same format for the dates. Because I need to print certain dates. I tried this:

  String begDate = "1999.11.18";
  SimpleDateFormat sdf = new     SimpleDateFormat("yyyy.MM.dd");
  Date start = sdf.parse("2010.01.01");
  Date end = sdf.parse("2010.04.01");
  GregorianCalendar gcal = new GregorianCalendar();
  gcal.setTime(start);
  while (!gcal.getTime().after(end))
 {
      Date d = gcal.getTime();
      System.out.println(d);
      gcal.add(Calendar.MONTH, 1);
  }

But while it does iterate through the dates correctly it changes the date format.

Upvotes: 2

Views: 780

Answers (1)

Basil Bourque
Basil Bourque

Reputation: 338496

Date/Calendar have no format

You seem to be confusing the Date/Calendar object with the textual representation of its value generated as a String by the toString method. Neither Date nor Calendar have a format. Each has a toString method you are calling implicitly in your line System.out.println( d );. The format used by toString when generating a String is its own default format pattern, not the format pattern you specified while parsing.

This line:

System.out.println( d );

…is a shortcut for this next line, with the implicit call to toString made explicit:

System.out.println( d.toString() );

That toString method uses its own format (a clumsy, poorly designed format) of the form dow mon dd hh:mm:ss zzz yyyy.

java.time

You are using old legacy classes that have proven to be poorly design, confusing, and troublesome. They have been supplanted by the java.time framework built into Java 8 and later (and back-ported to Java 6 & 7 and to Android).

For a date-only value without time-of-day and without time zone, use the LocalDate class.

To specify a formatting pattern for parsing, use the DateTimeFormatter class.

This example code spits out LocalDate values represented textually in your desired format. At the same time this code collects each LocalDate in the sequence in a List.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy.MM.dd" );
LocalDate start = sdf.parse("2010.01.01");
LocalDate end = sdf.parse("2010.04.01");
LocalDate localDate = start;
List<LocalDate> dates = new ArrayList<>();
int i = 0;
while ( ! localDate.isAfter( end ) ) {
    i = i + 1;
    dates.add( localDate );
    String output = localDate.format( formatter );
    System.out.println( "LocalDate # " + i + " : " + output );
    // Set up next loop.
    localDate = localDate.plusDays( 1 );
}
System.out.println( "dates : " + dates.toString() );

When printing the List of LocalDate objects, notice each LocalDate object’s LocalDate::toString method generates a String using sensible formats from the ISO 8601 standard.

Tips:

  • Do most of your work in objects like LocalDate rather than Strings. For business logic, use smart objects. When you need to present user, then generate Strings in a certain format.
  • When exchanging data or serializing values, if at all possible, use standard ISO 8601 formats rather than inventing your own such as yyyy.MM.dd.

Upvotes: 2

Related Questions