Snippet: Kalender ausdrucken, Teil 2: von-bis

Die erste Version meines Kalenderprogramms druckte ein Kalender für ein Jahr. In Anwendungen dürfte häufiger vorkommen, dass es ein Start- und Enddatum gibt, das auch über Jahresgrenzen liegt. Das macht dieses Programm:

public static class CalLine
{
  public int year;
  public int weekOfYear;
  public int month = -1;  // 0 <= month <= 11
  public int[] day = { -1, -1, -1, -1, -1, -1, -1 };
}

public static List<CalLine> calenderOfTheYear( Date start, Date end )
{
  Calendar startCal = new GregorianCalendar();
  startCal.setTime( start );
  Calendar endCal = new GregorianCalendar();
  endCal.setTime( end );
  return calenderOfTheYear( startCal, endCal );
}

public static List<CalLine> calenderOfTheYear( Calendar start, Calendar end )
{
  List<CalLine> lines = new ArrayList<>();

  // Calender instances are mutable, so copy them
  Calendar startCal = (Calendar) start.clone(); 
  Calendar endCal   = (Calendar) end.clone(); 

  // For start date: first go backwards to the beginning of the month
  // then find monday of this week
  while ( startCal.get( Calendar.DAY_OF_MONTH ) != 1 )
    startCal.add( Calendar.DAY_OF_YEAR, -1 );
  while ( startCal.get( Calendar.DAY_OF_WEEK ) != Calendar.MONDAY )
    startCal.add( Calendar.DAY_OF_YEAR, -1 );

  // For end date: go forwards and find end of month
  // then find sunday of this week
  while ( endCal.get( Calendar.DAY_OF_MONTH ) != startCal.getActualMaximum( Calendar.DAY_OF_MONTH ) )
    endCal.add( Calendar.DAY_OF_YEAR, 1 );
  while ( endCal.get( Calendar.DAY_OF_WEEK ) != Calendar.SUNDAY )
    endCal.add( Calendar.DAY_OF_YEAR, 1 );
  endCal.add( Calendar.DAY_OF_YEAR, 1 );  // add 1 to test with < not <=

  CalLine line = new CalLine();

  while ( startCal.before( endCal ) ) {
    if ( line.year == 0 )
      line.year = startCal.get( Calendar.YEAR );
    if ( line.weekOfYear == 0 )
      line.weekOfYear = startCal.get( Calendar.WEEK_OF_YEAR );

    int dayOfMonth = startCal.get( Calendar.DAY_OF_MONTH );
    int dayOfWeek  = startCal.get( Calendar.DAY_OF_WEEK );

    if ( dayOfMonth == 1 )
      line.month = startCal.get( Calendar.MONTH );

    line.day[dayOfWeek - 1] = dayOfMonth;

    if ( dayOfWeek == Calendar.SUNDAY ) {
      // Days are Sun, Mon, ..., Sat. Rearange to Mon, ..., Sun 
      int first = line.day[ 0 ]; // This is faster then System.arraycopy()
      line.day[ 0 ] = line.day[ 1 ]; line.day[ 1 ] = line.day[ 2 ]; line.day[ 2 ] = line.day[ 3 ];
      line.day[ 3 ] = line.day[ 4 ]; line.day[ 4 ] = line.day[ 5 ]; line.day[ 5 ] = line.day[ 6 ];
      line.day[ 6 ] = first;

      lines.add( line );
      line = new CalLine();   // it ends always with SUN, last line is not added
    }

    startCal.add( Calendar.DAY_OF_YEAR, 1 );
  }

  return lines;
}

Beispielaufruf:

List<CalLine> lines = DateUtils.calenderOfTheYear( new GregorianCalendar( 2011, Calendar.NOVEMBER, 12 ), new GregorianCalendar( 2012, Calendar.JANUARY, 22 ) );

String[] monthNames = { "Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez" };
System.out.println( "KW        Mo Do Mi Do Fr Sa So" ); // to lazy for DateFormatSymbols here...

for ( CalLine l : lines ) {
  String monthStr = (l.month == -1) ? "   " : monthNames[ l.month ];
  String s = String.format( "%2d  %s   %(2d %(2d %(2d %(2d %(2d %(2d %(2d",
                            l.weekOfYear, monthStr,
                            l.day[0], l.day[1], l.day[2], l.day[3], l.day[4], l.day[5], l.day[6] ).replace( "(1)", "  " );
  System.out.println( s );
}

Das führt zu

KW        Mo Do Mi Do Fr Sa So
44  Nov   31  1  2  3  4  5  6
45         7  8  9 10 11 12 13
46        14 15 16 17 18 19 20
47        21 22 23 24 25 26 27
48  Dez   28 29 30  1  2  3  4
49         5  6  7  8  9 10 11
50        12 13 14 15 16 17 18
51        19 20 21 22 23 24 25
52  Jan   26 27 28 29 30 31  1
 1         2  3  4  5  6  7  8
 2         9 10 11 12 13 14 15
 3        16 17 18 19 20 21 22
 4        23 24 25 26 27 28 29
 5  Feb   30 31  1  2  3  4  5

Über Christian Ullenboom

Ich bin Christian Ullenboom und Autor der Bücher ›Java ist auch eine Insel. Einführung, Ausbildung, Praxis‹ und ›Java SE 8 Standard-Bibliothek. Das Handbuch für Java-Entwickler‹. Seit 1997 berate ich Unternehmen im Einsatz von Java. Sun ernannte mich 2005 zum ›Java-Champion‹.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.