Index: /tupper/trunk/tupper-site/src/main/java/org/kauriproject/tupper/resource/CalendarUtil.java
===================================================================
--- /tupper/trunk/tupper-site/src/main/java/org/kauriproject/tupper/resource/CalendarUtil.java	(revision 1423)
+++ /tupper/trunk/tupper-site/src/main/java/org/kauriproject/tupper/resource/CalendarUtil.java	(revision 1423)
@@ -0,0 +1,78 @@
+package org.kauriproject.tupper.resource;
+
+import java.util.Calendar;
+import java.util.Locale;
+import java.util.GregorianCalendar;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import static java.util.Calendar.*;
+
+public class CalendarUtil {
+    private static final String WEEK_PATTERN_STRING = "w([-\\d]+)y(\\d+)";
+    private static final Pattern WEEK_PATTERN = Pattern.compile("^" + WEEK_PATTERN_STRING + "$");
+    private static final Pattern WEEK_RANGE = Pattern.compile("^" + WEEK_PATTERN_STRING + "-" + WEEK_PATTERN_STRING + "$");
+
+    public static Calendar getCalendar() {
+        // The firstDayOfWeek and minimalDaysInFirstWeek fields
+        // are dependent on the Locale, we use the Belgian settings
+        return new GregorianCalendar(new Locale("nl", "BE"));
+    }
+
+    public static int getNumberOfWeeksInYear(int year) {
+        Calendar calendar = getCalendar();
+        calendar.set(Calendar.DAY_OF_YEAR, 1);
+        calendar.set(Calendar.YEAR, year);
+        return calendar.getActualMaximum(Calendar.WEEK_OF_YEAR);
+    }
+
+    public static Calendar getCalendar(int week, int year) {
+        Calendar calendar = getCalendar();
+        calendar.set(Calendar.DAY_OF_YEAR, 1);
+        calendar.set(Calendar.YEAR, year);
+        calendar.set(Calendar.WEEK_OF_YEAR, week);
+        return calendar;
+    }
+
+    public static String canonicizeWeekString(String weekSpec) {
+        Matcher matcher = WEEK_PATTERN.matcher(weekSpec);
+        if (!matcher.matches()) {
+            throw new RuntimeException("Invalid week string: " + weekSpec);
+        }
+
+        int week = Integer.parseInt(matcher.group(1));
+        int year = Integer.parseInt(matcher.group(2));
+
+        // Go via calendar to do a lenient interpretation of the values
+        Calendar cal = getCalendar(week, year);
+
+        return "w" + cal.get(WEEK_OF_YEAR) + "y" + cal.get(YEAR);
+    }
+
+    public static String getWeekString(int week, int year) {
+        return "w" + week + "y" + year;
+    }
+
+    public static int[] parseWeekRange(String week) {
+        Matcher matcher = WEEK_RANGE.matcher(week);
+        if (!matcher.matches()) {
+            throw new RuntimeException("Invalid week range: " + week);
+        }
+
+        int startWeek = Integer.parseInt(matcher.group(1));
+        int startYear = Integer.parseInt(matcher.group(2));
+        int endWeek = Integer.parseInt(matcher.group(3));
+        int endYear = Integer.parseInt(matcher.group(4));
+
+        // Go via calendar to do a lenient interpretation of the values
+
+        Calendar startCal = CalendarUtil.getCalendar(startWeek, startYear);
+        startWeek = startCal.get(WEEK_OF_YEAR);
+        startYear = startCal.get(YEAR);
+
+        Calendar endCal = CalendarUtil.getCalendar(endWeek, endYear);
+        endWeek = endCal.get(WEEK_OF_YEAR);
+        endYear = endCal.get(YEAR);
+
+        return new int[] {startWeek, startYear, endWeek, endYear};
+    }
+}
