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