17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*
27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Copyright (C) 1996-2010, International Business Machines Corporation and    *
47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved.                                                *
57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.util;
97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Date;
117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/**
137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <b>Note:</b> The Holiday framework is a technology preview.
147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Despite its age, is still draft API, and clients should treat it as such.
157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Simple implementation of DateRule.
177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @draft ICU 2.8 (retainAll)
187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @provisional This API might change or be removed in a future release.
197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class SimpleDateRule implements DateRule
217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert{
227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Construct a rule for a fixed date within a month
247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param month         The month in which this rule occurs (0-based).
267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param dayOfMonth    The date in that month (1-based).
277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @draft ICU 2.8
287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @provisional This API might change or be removed in a future release.
297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public SimpleDateRule(int month, int dayOfMonth)
317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.month      = month;
337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.dayOfMonth = dayOfMonth;
347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.dayOfWeek  = 0;
357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // temporary
387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* package */SimpleDateRule(int month, int dayOfMonth, Calendar cal)
397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.month      = month;
417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.dayOfMonth = dayOfMonth;
427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.dayOfWeek  = 0;
437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.calendar   = cal;
447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Construct a rule for a weekday within a month, e.g. the first Monday.
487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param month         The month in which this rule occurs (0-based).
507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param dayOfMonth    A date within that month (1-based).
517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param dayOfWeek     The day of the week on which this rule occurs.
527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param after         If true, this rule selects the first dayOfWeek
537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                      on or after dayOfMonth.  If false, the rule selects
547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                      the first dayOfWeek on or before dayOfMonth.
557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @draft ICU 2.8
567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @provisional This API might change or be removed in a future release.
577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public SimpleDateRule(int month, int dayOfMonth, int dayOfWeek, boolean after)
597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.month      = month;
617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.dayOfMonth = dayOfMonth;
627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.dayOfWeek  = after ? dayOfWeek : -dayOfWeek;
637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Return the first occurrance of the event represented by this rule
677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * that is on or after the given start date.
687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param start Only occurrances on or after this date are returned.
707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return      The date on which this event occurs, or null if it
727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *              does not occur on or after the start date.
737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #firstBetween
757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @draft ICU 2.8
767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @provisional This API might change or be removed in a future release.
777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public Date firstAfter(Date start)
797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return doFirstBetween(start, null);
817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Return the first occurrance of the event represented by this rule
857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * that is on or after the given start date and before the given
867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * end date.
877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param start Only occurrances on or after this date are returned.
897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param end   Only occurrances before this date are returned.
907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return      The date on which this event occurs, or null if it
927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *              does not occur between the start and end dates.
937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see #firstAfter
957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @draft ICU 2.8
967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @provisional This API might change or be removed in a future release.
977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public Date firstBetween(Date start, Date end)
997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Pin to the min/max dates for this rule
1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return doFirstBetween(start, end);
1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Checks whether this event occurs on the given date.  This does
1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <em>not</em> take time of day into account; instead it checks
1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * whether this event and the given date are on the same day.
1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This is useful for applications such as determining whether a given
1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * day is a holiday.
1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param date  The date to check.
1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @return      true if this event occurs on the given date.
1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @draft ICU 2.8
1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @provisional This API might change or be removed in a future release.
1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public boolean isOn(Date date)
1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Calendar c = calendar;
1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        synchronized(c) {
1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            c.setTime(date);
1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int dayOfYear = c.get(Calendar.DAY_OF_YEAR);
1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            c.setTime(computeInYear(c.get(Calendar.YEAR), c));
1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//              System.out.println("  isOn: dayOfYear = " + dayOfYear);
1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//              System.out.println("        holiday   = " + c.get(Calendar.DAY_OF_YEAR));
1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return c.get(Calendar.DAY_OF_YEAR) == dayOfYear;
1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Check whether this event occurs at least once between the two
1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * dates given.
1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @draft ICU 2.8
1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @provisional This API might change or be removed in a future release.
1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public boolean isBetween(Date start, Date end)
1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return firstBetween(start, end) != null; // TODO: optimize?
1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private Date doFirstBetween(Date start, Date end)
1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Calendar c = calendar;
1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        synchronized(c) {
1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            c.setTime(start);
1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int year = c.get(Calendar.YEAR);
1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int mon = c.get(Calendar.MONTH);
1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // If the rule is earlier in the year than the start date
1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // we have to go to the next year.
1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (mon > this.month) {
1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                year++;
1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Figure out when the rule lands in the given year
1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Date result = computeInYear(year, c);
1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // If the rule is in the same month as the start date, it's possible
1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // to get a result that's before the start.  If so, go to next year.
1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (mon == this.month && result.before(start)) {
1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                result = computeInYear(year+1, c);
1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (end != null && result.after(end)) {
1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return null;
1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return result;
1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private Date computeInYear(int year, Calendar c)
1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        synchronized(c) {
1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            c.clear();
1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            c.set(Calendar.ERA, c.getMaximum(Calendar.ERA));
1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            c.set(Calendar.YEAR, year);
1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            c.set(Calendar.MONTH, month);
1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            c.set(Calendar.DATE, dayOfMonth);
1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //System.out.println("     computeInYear: start at " + c.getTime().toString());
1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (dayOfWeek != 0) {
1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                c.setTime(c.getTime());        // JDK 1.1.2 workaround
1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int weekday = c.get(Calendar.DAY_OF_WEEK);
1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                //System.out.println("                    weekday = " + weekday);
1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                //System.out.println("                    dayOfYear = " + c.get(Calendar.DAY_OF_YEAR));
1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int delta = 0;
1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (dayOfWeek > 0) {
1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // We want the first occurrance of the given day of the week
1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // on or after the specified date in the month.
1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    delta = (dayOfWeek - weekday + 7) % 7;
2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                else {
2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // We want the first occurrance of the (-dayOfWeek)
2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // on or before the specified date in the month.
2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    delta = -((dayOfWeek + weekday + 7) % 7);
2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                //System.out.println("                    adding " + delta + " days");
2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                c.add(Calendar.DATE, delta);
2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return c.getTime();
2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @draft ICU 2.8
2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @provisional This API might change or be removed in a future release.
2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//    public void setCalendar(Calendar c) {
2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        calendar = c;
2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//    }
2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static GregorianCalendar gCalendar = new GregorianCalendar();
2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private Calendar calendar = gCalendar;
2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private int     month;
2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private int     dayOfMonth;
2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private int     dayOfWeek;
2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}
230