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