[CalendarServer-changes] [14193] PyCalendar/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Dec 1 08:50:49 PST 2014


Revision: 14193
          http://trac.calendarserver.org//changeset/14193
Author:   cdaboo at apple.com
Date:     2014-12-01 08:50:49 -0800 (Mon, 01 Dec 2014)
Log Message:
-----------
Undo r14191 which was meant to go on a branch.

Revision Links:
--------------
    http://trac.calendarserver.org//changeset/14191

Modified Paths:
--------------
    PyCalendar/trunk/.project
    PyCalendar/trunk/src/pycalendar/datetime.py
    PyCalendar/trunk/src/pycalendar/icalendar/definitions.py
    PyCalendar/trunk/src/pycalendar/icalendar/recurrence.py
    PyCalendar/trunk/src/pycalendar/icalendar/tests/test_recurrence.py
    PyCalendar/trunk/src/pycalendar/icalendar/xmldefinitions.py

Removed Paths:
-------------
    PyCalendar/trunk/src/pycalendar/icalendar/icudatetime.py
    PyCalendar/trunk/src/pycalendar/icalendar/recuriter.py
    PyCalendar/trunk/src/pycalendar/icalendar/tests/test_icudatetime.py
    PyCalendar/trunk/src/pycalendar/icalendar/tests/test_recuriter.py

Modified: PyCalendar/trunk/.project
===================================================================
--- PyCalendar/trunk/.project	2014-12-01 16:26:51 UTC (rev 14192)
+++ PyCalendar/trunk/.project	2014-12-01 16:50:49 UTC (rev 14193)
@@ -3,7 +3,6 @@
 	<name>pycalendar</name>
 	<comment></comment>
 	<projects>
-		<project>cffi</project>
 	</projects>
 	<buildSpec>
 		<buildCommand>

Modified: PyCalendar/trunk/src/pycalendar/datetime.py
===================================================================
--- PyCalendar/trunk/src/pycalendar/datetime.py	2014-12-01 16:26:51 UTC (rev 14192)
+++ PyCalendar/trunk/src/pycalendar/datetime.py	2014-12-01 16:50:49 UTC (rev 14193)
@@ -301,7 +301,7 @@
         self.changed()
 
 
-    def setYYMMDD(self, year, month, days, isleapmonth=False):
+    def setYYMMDD(self, year, month, days):
         if (self.mYear != year) or (self.mMonth != month) or (self.mDay != days):
             self.mYear = year
             self.mMonth = month
@@ -321,18 +321,14 @@
 
     def offsetYear(self, diff_year):
         self.mYear += diff_year
+        self.normalise()
 
-        # Do special normalization for this case to do a skip backwards if
-        # the new date is invalid
-        if self.mDay > utils.daysInMonth(self.mMonth, self.mYear):
-            self.mDay = utils.daysInMonth(self.mMonth, self.mYear)
 
-
     def getMonth(self):
         return self.mMonth
 
 
-    def setMonth(self, month, isleapmonth=False):
+    def setMonth(self, month):
         if self.mMonth != month:
             self.mMonth = month
             self.changed()
@@ -340,26 +336,9 @@
 
     def offsetMonth(self, diff_month):
         self.mMonth += diff_month
+        self.normalise()
 
-        # Normalise month
-        normalised_month = ((self.mMonth - 1) % 12) + 1
-        adjustment_year = (self.mMonth - 1) / 12
-        if (normalised_month - 1) < 0:
-            normalised_month += 12
-            adjustment_year -= 1
-        self.mMonth = normalised_month
-        self.mYear += adjustment_year
 
-        # Do special normalization for this case to do a skip backwards if
-        # the new date is invalid
-        if self.mDay > utils.daysInMonth(self.mMonth, self.mYear):
-            self.mDay = utils.daysInMonth(self.mMonth, self.mYear)
-
-
-    def getLeapMonth(self):
-        return False
-
-
     def getDay(self):
         return self.mDay
 
@@ -465,22 +444,16 @@
         # What day does the current year start on, and diff that with the current day
         temp = DateTime(year=self.mYear, month=1, day=1)
         first_day = temp.getDayOfWeek()
-        if first_day == 0:
-            first_day = 7
         current_day = self.getDayOfWeek()
-        if current_day == 0:
-            current_day = 7
 
         # Calculate and set yearday for start of week. The first week is the one that contains at least
         # four days (with week start defaulting to MONDAY), so that means the 1st of January would fall
         # on MO, TU, WE, TH.
         if first_day in (DateTime.MONDAY, DateTime.TUESDAY, DateTime.WEDNESDAY, DateTime.THURSDAY):
-            offset = 0
+            year_day = (weekno - 1) * 7 + current_day - first_day
         else:
-            offset = 1
+            year_day = weekno * 7 + current_day - first_day
 
-        year_day = (weekno - 1 + offset) * 7 + current_day - first_day
-
         # It is possible we have a negative offset which means go back to the prior year as part of
         # week #1 exists at the end of that year.
         if year_day < 0:
@@ -1170,16 +1143,6 @@
         jobject.append(self.getJSONText())
 
 
-    # When doing recurrence iteration we sometimes need to preserve an invalid value for
-    # either day or month (though month is never invalid for Gregorian calendars it can
-    # be for non-Gregorian). For this class we simply set the stored attributes to their
-    # invalid values.
-    def setInvalid(self, year, month, day, isleapmonth=False):
-        self.mYear = year
-        self.mMonth = month
-        self.mDay = day
-
-
     def invalid(self):
         """
         Are any of the current fields invalid.
@@ -1194,32 +1157,6 @@
         return False
 
 
-    def invalidSkip(self, skip):
-        """
-        If this is an invalid value skip backward or forward or not at all.
-
-        @param skip: the skip mode (yes, backward, forward)
-        @type skip: L{int}
-        """
-
-        if self.invalid():
-            if skip == definitions.eRecurrence_SKIP_YES:
-                # Leave it as invalid
-                pass
-            elif skip == definitions.eRecurrence_SKIP_BACKWARD:
-                if self.mDay <= 0:
-                    self.mDay = 1
-                    self.offsetDay(-1)
-                else:
-                    self.mDay = utils.daysInMonth(self.mMonth, self.mYear)
-            elif skip == definitions.eRecurrence_SKIP_FORWARD:
-                if self.mDay <= 0:
-                    self.mDay = 1
-                else:
-                    self.mDay = utils.daysInMonth(self.mMonth, self.mYear)
-                    self.offsetDay(1)
-
-
     def normalise(self):
         # Normalise seconds
         normalised_secs = self.mSeconds % 60

Modified: PyCalendar/trunk/src/pycalendar/icalendar/definitions.py
===================================================================
--- PyCalendar/trunk/src/pycalendar/icalendar/definitions.py	2014-12-01 16:26:51 UTC (rev 14192)
+++ PyCalendar/trunk/src/pycalendar/icalendar/definitions.py	2014-12-01 16:50:49 UTC (rev 14193)
@@ -230,8 +230,6 @@
 eRecurrence_BYMONTH = 11
 eRecurrence_BYSETPOS = 12
 eRecurrence_WKST = 13
-eRecurrence_RSCALE = 14
-eRecurrence_SKIP = 15
 
 cICalValue_RECUR_FREQ = "FREQ"
 cICalValue_RECUR_FREQ_LEN = 5
@@ -258,8 +256,6 @@
 cICalValue_RECUR_BYMONTH = "BYMONTH"
 cICalValue_RECUR_BYSETPOS = "BYSETPOS"
 cICalValue_RECUR_WKST = "WKST"
-cICalValue_RECUR_RSCALE = "RSCALE"
-cICalValue_RECUR_SKIP = "SKIP"
 
 eRecurrence_WEEKDAY_SU = 0
 eRecurrence_WEEKDAY_MO = 1
@@ -277,14 +273,6 @@
 cICalValue_RECUR_WEEKDAY_FR = "FR"
 cICalValue_RECUR_WEEKDAY_SA = "SA"
 
-eRecurrence_SKIP_YES = 0
-eRecurrence_SKIP_BACKWARD = 1
-eRecurrence_SKIP_FORWARD = 2
-
-cICalValue_RECUR_SKIP_YES = "YES"
-cICalValue_RECUR_SKIP_BACKWARD = "BACKWARD"
-cICalValue_RECUR_SKIP_FORWARD = "FORWARD"
-
 #     5545 Section 3.8.1.11
 eStatus_VEvent_None = 0
 eStatus_VEvent_Confirmed = 1

Deleted: PyCalendar/trunk/src/pycalendar/icalendar/icudatetime.py
===================================================================
--- PyCalendar/trunk/src/pycalendar/icalendar/icudatetime.py	2014-12-01 16:26:51 UTC (rev 14192)
+++ PyCalendar/trunk/src/pycalendar/icalendar/icudatetime.py	2014-12-01 16:50:49 UTC (rev 14193)
@@ -1,1005 +0,0 @@
-##
-#    Copyright (c) 2014 Cyrus Daboo. All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License");
-#    you may not use this file except in compliance with the License.
-#    You may obtain a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS,
-#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#    See the License for the specific language governing permissions and
-#    limitations under the License.
-##
-
-from cffi import FFI
-from __builtin__ import classmethod
-from pycalendar.datetime import DateTime
-from pycalendar.icalendar import definitions
-
-# Use cffi to get access to libicucore functions and constants
-ffi = FFI()
-hdr = """
-    //#define U_FAILURE(x) ((x)>U_ZERO_ERROR)
-
-    typedef double UDate;
-    UDate     ucal_getNow (void);
-
-    typedef void *        UCalendar;
-    typedef uint16_t    UChar;
-    enum      UCalendarType { UCAL_TRADITIONAL=0, UCAL_DEFAULT=0, UCAL_GREGORIAN, ... };
-    typedef enum UCalendarType UCalendarType;
-    enum UErrorCode {
-        U_ZERO_ERROR = 0
-    };
-    typedef enum UErrorCode UErrorCode;
-
-    enum UCalendarDaysOfWeek {
-      /** Sunday */
-      UCAL_SUNDAY = 1,
-      /** Monday */
-      UCAL_MONDAY,
-      /** Tuesday */
-      UCAL_TUESDAY,
-      /** Wednesday */
-      UCAL_WEDNESDAY,
-      /** Thursday */
-      UCAL_THURSDAY,
-      /** Friday */
-      UCAL_FRIDAY,
-      /** Saturday */
-      UCAL_SATURDAY
-    };
-
-    typedef enum UCalendarDaysOfWeek UCalendarDaysOfWeek;
-
-    enum UCalendarDateFields {
-      UCAL_ERA,
-      UCAL_YEAR,
-      UCAL_MONTH,
-      UCAL_WEEK_OF_YEAR,
-      UCAL_WEEK_OF_MONTH,
-      UCAL_DATE,
-      UCAL_DAY_OF_YEAR,
-      UCAL_DAY_OF_WEEK,
-      UCAL_DAY_OF_WEEK_IN_MONTH,
-      UCAL_AM_PM,
-      UCAL_HOUR,
-      UCAL_HOUR_OF_DAY,
-      UCAL_MINUTE,
-      UCAL_SECOND,
-      UCAL_MILLISECOND,
-      UCAL_ZONE_OFFSET,
-      UCAL_DST_OFFSET,
-      UCAL_YEAR_WOY,
-      UCAL_DOW_LOCAL,
-      UCAL_EXTENDED_YEAR,
-      UCAL_JULIAN_DAY,
-      UCAL_MILLISECONDS_IN_DAY,
-      UCAL_IS_LEAP_MONTH,
-      UCAL_FIELD_COUNT,
-      UCAL_DAY_OF_MONTH=5
-      };
-
-    typedef enum UCalendarDateFields UCalendarDateFields;
-
-    enum UCalendarMonths {
-      /** January */
-      UCAL_JANUARY,
-      /** February */
-      UCAL_FEBRUARY,
-      /** March */
-      UCAL_MARCH,
-      /** April */
-      UCAL_APRIL,
-      /** May */
-      UCAL_MAY,
-      /** June */
-      UCAL_JUNE,
-      /** July */
-      UCAL_JULY,
-      /** August */
-      UCAL_AUGUST,
-      /** September */
-      UCAL_SEPTEMBER,
-      /** October */
-      UCAL_OCTOBER,
-      /** November */
-      UCAL_NOVEMBER,
-      /** December */
-      UCAL_DECEMBER,
-      /** Value of the <code>UCAL_MONTH</code> field indicating the
-        * thirteenth month of the year. Although the Gregorian calendar
-        * does not use this value, lunar calendars do.
-        */
-      UCAL_UNDECIMBER
-    };
-    typedef enum UCalendarMonths UCalendarMonths;
-
-    UCalendar * ucal_open(const UChar *zoneID, int32_t len, const char *locale, UCalendarType type, UErrorCode *status);
-    void        ucal_close(UCalendar *cal);
-    UCalendar * ucal_clone(const UCalendar* cal, UErrorCode* status);
-    void        ucal_setDate(UCalendar *cal, int32_t year, int32_t month, int32_t date, UErrorCode *status);
-
-    const char* ucal_getTZDataVersion (UErrorCode *status);
-
-    UDate ucal_getMillis(const UCalendar* cal,
-               UErrorCode* status);
-    void  ucal_setMillis(UCalendar* cal,
-               UDate        dateTime,
-               UErrorCode*  status);
-
-    int32_t ucal_get(const UCalendar* cal,
-         UCalendarDateFields  field,
-         UErrorCode*          status);
-    void ucal_set(UCalendar*  cal,
-         UCalendarDateFields  field,
-         int32_t              value);
-    void ucal_add(UCalendar*  cal,
-         UCalendarDateFields  field,
-         int32_t              amount,
-         UErrorCode*          status);
-
-    enum UCalendarLimitType {
-      /** Minimum value */
-      UCAL_MINIMUM,
-      /** Maximum value */
-      UCAL_MAXIMUM,
-      /** Greatest minimum value */
-      UCAL_GREATEST_MINIMUM,
-      /** Leaest maximum value */
-      UCAL_LEAST_MAXIMUM,
-      /** Actual minimum value */
-      UCAL_ACTUAL_MINIMUM,
-      /** Actual maximum value */
-      UCAL_ACTUAL_MAXIMUM
-    };
-
-    typedef enum UCalendarLimitType UCalendarLimitType;
-
-    int32_t ucal_getLimit(const UCalendar*     cal,
-                  UCalendarDateFields  field,
-                  UCalendarLimitType   type,
-                  UErrorCode*          status);
-"""
-
-ffi.cdef(hdr)
-ffi.verify(hdr.replace(", ...", ""))
-
-ICU = ffi.dlopen("libicucore")
-
-class ICUDateTime(object):
-    """
-    An ICU-based L{DateTime} like class that supports non-Gregorian date-time values and arithmetic.
-    """
-
-    RSCALE_GREGORIAN = "gregorian"
-    RSCALE_HEBREW = "hebrew"
-
-    RSCALE_CALCODE = {
-        "gregorian": "",
-        "chinese": "C",
-        "islamic-civil": "I",
-        "hebrew": "H",
-        "ethiopic": "E",
-    }
-
-    def __init__(self, rscale, ucal):
-        """
-        Initialize using an ICU C{ucal} object and the name of the calendar scale.
-
-        @param rscale: calendar scale being used
-        @type rscale: L{str}
-        @param ucal: ICU ucal object
-        @type ucal: L{ICU.UCalendar*}
-        """
-        self.rscale = rscale
-        self.ucal = ucal
-
-        self.mHours = 0
-        self.mMinutes = 0
-        self.mSeconds = 0
-
-        self.mDateOnly = True
-
-        self.mTZUTC = False
-        self.mTZID = None
-        self.mTZOffset = None
-
-        self.mInvalid = None
-
-
-    def __del__(self):
-        """
-        Always close the ICU C{ucal} object.
-        """
-        ICU.ucal_close(self.ucal)
-        self.ucal = None
-
-
-    def duplicate(self):
-        """
-        Duplicate this object.
-        """
-
-        error = ffi.new("UErrorCode *", 0)
-        clone = ICU.ucal_clone(self.ucal, error)
-        dup = ICUDateTime(self.rscale, clone)
-        dup._transferHHMMSS(self, dup)
-        dup.mInvalid = self.mInvalid
-
-        return dup
-
-
-    def __repr__(self):
-        return "ICUDateTime: %s" % (self.getText(),)
-
-
-    def __hash__(self):
-        return hash(self.getPosixTime())
-
-
-    @classmethod
-    def fromDateTime(cls, dt, rscale):
-        """
-        Convert from a regular L{DateTime} to the specified calendar scale.
-
-        @param dt: the regular value to convert from
-        @type dt: L{DateTime}
-        @param rscale: the calendar scale to convert to
-        @type rscale: L{str}
-
-        @return: the new ICU object
-        @rtyope: L{ICUDateTime}
-        """
-
-        # Try to create the ICU object that represents this date
-        gregorian = cls.fromDateComponents(cls.RSCALE_GREGORIAN, dt.getYear(), dt.getMonth(), dt.getDay())
-        cls._transferHHMMSS(dt, gregorian)
-        return gregorian.convertTo(rscale)
-
-
-    def toDateTime(self):
-        """
-        Convert to a regular L{DateTime}.
-
-        @return: the converted object
-        @rtype: L{DateTime}
-        """
-
-        # Try to create the ICU object that represents this date
-        gregorian = self if self.rscale.lower() == self.RSCALE_GREGORIAN else self.convertTo(self.RSCALE_GREGORIAN)
-        dt = DateTime(gregorian.getYear(), gregorian.getMonth(), gregorian.getDay())
-        self._transferHHMMSS(self, dt)
-        return dt
-
-
-    @classmethod
-    def _newUcal(cls, rscale):
-        """
-        Create an ICU C{ucal} object for the specified calendar scale.
-
-        @param rscale: calendar scale to use
-        @type rscale: L{str}
-
-        @return: the ICU ucal object
-        @rtype: L{ICU.UCalendar*}
-        """
-        calsystem = "*@calendar={}".format(rscale)
-        error = ffi.new("UErrorCode *", 0)
-        ucal = ICU.ucal_open(ffi.NULL, -1, ffi.new("char[]", calsystem), ICU.UCAL_DEFAULT, error)
-        if error[0] != ICU.U_ZERO_ERROR:
-            raise ValueError("Unable to create ICU calendar for rscale '{}', code: {}".format(rscale, error))
-        return ucal
-
-
-    @classmethod
-    def fromDateComponents(cls, rscale, year, month, day, isleapmonth=False):
-        """
-        Create ICU calendar for the specified calendar scale with the specified components.
-
-        @param dt: the regular value to convert from
-        @type dt: L{DateTime}
-        @param rscale: the calendar scale to convert to
-        @type rscale: L{str}
-        @param year: the year component
-        @type year: L{int}
-        @param month: the month component
-        @type month: L{int}
-        @param day: the day component
-        @type day: L{int}
-        @param isleapmonth: the leap month component
-        @type isleapmonth: L{bool}
-
-        @return: the new object
-        @rtype: L{ICUDateTime}
-        """
-
-        # Try to create the ICU object that represents this date
-        ucal = cls._newUcal(rscale)
-
-        month, isleapmonth = cls._adjustToICULeapMonth(rscale, month, isleapmonth)
-
-        ICU.ucal_set(ucal, ICU.UCAL_EXTENDED_YEAR, year)
-        ICU.ucal_set(ucal, ICU.UCAL_MONTH, cls._numericMonthToICU(month))
-        ICU.ucal_set(ucal, ICU.UCAL_DAY_OF_MONTH, day)
-        ICU.ucal_set(ucal, ICU.UCAL_IS_LEAP_MONTH, isleapmonth)
-
-        return ICUDateTime(rscale, ucal)
-
-
-    @classmethod
-    def _numericMonthToICU(cls, month):
-        """
-        Map our month numbers (1..13) to ICU constants.
-
-        @param month: the month to map
-        @type month: L{int}
-
-        @return: the ICU constant
-        @rtype: L{ICU.UCalendarMonths}
-        """
-        return {
-            1: ICU.UCAL_JANUARY,
-            2: ICU.UCAL_FEBRUARY,
-            3: ICU.UCAL_MARCH,
-            4: ICU.UCAL_APRIL,
-            5: ICU.UCAL_MAY,
-            6: ICU.UCAL_JUNE,
-            7: ICU.UCAL_JULY,
-            8: ICU.UCAL_AUGUST,
-            9: ICU.UCAL_SEPTEMBER,
-            10: ICU.UCAL_OCTOBER,
-            11: ICU.UCAL_NOVEMBER,
-            12: ICU.UCAL_DECEMBER,
-            13: ICU.UCAL_UNDECIMBER,
-        }[month]
-
-
-    @classmethod
-    def _icuToNumericMonth(cls, month):
-        """
-        Map ICU constants to our month numbers (1..13).
-
-        @param month: the ICU constant to map
-        @type month: L{ICU.UCalendarMonths}
-
-        @return: the month
-        @rtype: L{int}
-        """
-        return {
-            ICU.UCAL_JANUARY: 1,
-            ICU.UCAL_FEBRUARY: 2,
-            ICU.UCAL_MARCH: 3,
-            ICU.UCAL_APRIL: 4,
-            ICU.UCAL_MAY: 5,
-            ICU.UCAL_JUNE: 6,
-            ICU.UCAL_JULY: 7,
-            ICU.UCAL_AUGUST: 8,
-            ICU.UCAL_SEPTEMBER: 9,
-            ICU.UCAL_OCTOBER: 10,
-            ICU.UCAL_NOVEMBER: 11,
-            ICU.UCAL_DECEMBER: 12,
-            ICU.UCAL_UNDECIMBER: 13,
-        }[month]
-
-
-    @classmethod
-    def _adjustToICULeapMonth(cls, rscale, month, isleapmonth):
-        """
-        For the Hebrew calendar, ICU uses a count of 13 months rather than 12 months
-        plus an "isleapmonth" indicator. So when converting to/from ICU we need to make
-        that adjustment as we always use 12 months + isleapmonth. This method converts
-        from our internal representation to what ICU uses.
-
-        @param rscale: calendar scale to convert to
-        @type rscale: L{str}
-        @param month: month number (12 month cycle)
-        @type month: L{int}
-        @param isleapmonth: is leap month indicator
-        @type isleapmonth: L{bool} of L{None}
-
-        @return: a tuple of the ICU-mapped month number and isleapmonth indicator
-        @rtype: L{tuple} of (L{int}, L{bool}
-        """
-
-        if rscale.lower() == cls.RSCALE_HEBREW:
-            if month == 5 and isleapmonth:
-                month = 6
-                isleapmonth = None
-            elif month >= 6:
-                month += 1
-        return (month, isleapmonth,)
-
-
-    @classmethod
-    def _adjustFromICULeapMonth(cls, rscale, month, isleapmonth):
-        """
-        For the Hebrew calendar, ISU uses a count of 13 months rather than 12 months
-        plus an "isleapmonth" indicator. So when converting to/from ICU we need to make
-        that adjustment as we always use 12 months + isleapmonth. This method converts
-        to our internal representation from what ICU uses.
-
-        @param rscale: calendar scale to convert from
-        @type rscale: L{str}
-        @param month: month number (13 month cycle)
-        @type month: L{int}
-        @param isleapmonth: is leap month indicator
-        @type isleapmonth: L{bool} of L{None}
-
-        @return: a tuple of the month number and isleapmonth indicator
-        @rtype: L{tuple} of (L{int}, L{bool}
-        """
-
-        if rscale.lower() == cls.RSCALE_HEBREW:
-            isleapmonth = False
-            if month == 6:
-                isleapmonth = True
-            elif month >= 6:
-                month -= 1
-        return (month, isleapmonth,)
-
-
-    @classmethod
-    def _transferHHMMSS(cls, from_dt, to_dt):
-        """
-        Transfer the time and timezone components from one L{ICUDateTime} to another.
-
-        @param from_dt: object to copy from
-        @type from_dt: L{ICUDateTime}
-        @param to_dt: object to copy to
-        @type to_dt: L{ICUDateTime}
-        """
-        if not from_dt.isDateOnly():
-            to_dt.setDateOnly(False)
-            to_dt.setHHMMSS(from_dt.getHours(), from_dt.getMinutes(), from_dt.getSeconds())
-            to_dt.setTimezoneID(from_dt.getTimezoneID())
-            to_dt.setTimezoneUTC(from_dt.getTimezoneUTC())
-
-
-    def convertTo(self, rscale):
-        """
-        Convert this L{ICUDateTime} into another one in the specified calendar scale.
-
-        @param rscale: calendar scale to convert to
-        @type rscale: L{str}
-
-        @return: the converted date
-        @rtype: L{ICUDateTime}
-        """
-        error = ffi.new("UErrorCode *", 0)
-        converted = self._newUcal(rscale)
-        millis = ICU.ucal_getMillis(self.ucal, error)
-        ICU.ucal_setMillis(converted, millis, error)
-        dt = ICUDateTime(rscale, converted)
-        self._transferHHMMSS(self, dt)
-
-        # For some reason this is needed to properly setup all the fields. Without this, I have
-        # noticed that ucal_getLimit does not return the correct day of month limit for a Chinese
-        # calendar.
-        dt.getDateComponents()
-
-        return dt
-
-
-    def getDateComponents(self):
-        """
-        Get the year, month, day, isleapmonth components in our internal format from
-        this ICU date.
-
-        @return: the date components
-        @rtype: L{tuple} of (L{int}, L{int}, L{int}, L{bool})
-        """
-        year = self.getYear()
-        month = self.getMonth()
-        day = self.getDay()
-        isleapmonth = self.getLeapMonth()
-
-        month, isleapmonth = self._adjustFromICULeapMonth(self.rscale, month, isleapmonth)
-
-        return (year, month, day, isleapmonth,)
-
-
-    def getPosixTime(self):
-        """
-        Return an integer representing a standard offset in seconds from a specific
-        epoch. This is used for sorting similar object.
-        """
-
-        # Use the ICU "millis" for this.
-        error = ffi.new("UErrorCode *", 0)
-        return ICU.ucal_getMillis(self.ucal, error)
-
-
-    def isDateOnly(self):
-        return self.mDateOnly
-
-
-    def setDateOnly(self, date_only):
-        self.mDateOnly = date_only
-
-
-    def setYYMMDD(self, year, month, day, isleapmonth=False):
-        self.setYear(year)
-        self.setMonth(month, isleapmonth)
-        self.setDay(day)
-
-        self.testInvalid(year, month, day, isleapmonth)
-
-
-    def getYear(self):
-        error = ffi.new("UErrorCode *", 0)
-        return ICU.ucal_get(self.ucal, ICU.UCAL_EXTENDED_YEAR, error)
-
-
-    def setYear(self, year):
-        _ignore_old_year, old_month, old_day, old_isleapmonth = self.getDateComponents()
-        ICU.ucal_set(self.ucal, ICU.UCAL_EXTENDED_YEAR, year)
-        self.testInvalid(year, old_month, old_day, old_isleapmonth)
-
-
-    def offsetYear(self, diff_year):
-        """
-        Offset the ICU date year component by the specified amount.
-
-        @param diff_year: amount to offset
-        @type diff_year: L{int}
-        """
-        error = ffi.new("UErrorCode *", 0)
-        ICU.ucal_add(self.ucal, ICU.UCAL_EXTENDED_YEAR, diff_year, error)
-
-
-    def getMonth(self):
-        error = ffi.new("UErrorCode *", 0)
-        return self._icuToNumericMonth(ICU.ucal_get(self.ucal, ICU.UCAL_MONTH, error))
-
-
-    def setMonth(self, month, isleapmonth=False):
-        old_year, _ignore_old_month, old_day, _ignore_old_isleapmonth = self.getDateComponents()
-        ICU.ucal_set(self.ucal, ICU.UCAL_MONTH, self._numericMonthToICU(month))
-        ICU.ucal_set(self.ucal, ICU.UCAL_IS_LEAP_MONTH, isleapmonth)
-        self.testInvalid(old_year, month, old_day, isleapmonth)
-
-
-    def offsetMonth(self, diff_month):
-        """
-        Offset the ICU date month component by the specified amount.
-
-        @param diff_year: amount to offset
-        @type diff_year: L{int}
-        """
-        error = ffi.new("UErrorCode *", 0)
-        ICU.ucal_add(self.ucal, ICU.UCAL_MONTH, diff_month, error)
-
-
-    def getLeapMonth(self):
-        error = ffi.new("UErrorCode *", 0)
-        return ICU.ucal_get(self.ucal, ICU.UCAL_IS_LEAP_MONTH, error) != 0
-
-
-    def getDay(self):
-        error = ffi.new("UErrorCode *", 0)
-        return ICU.ucal_get(self.ucal, ICU.UCAL_DAY_OF_MONTH, error)
-
-
-    def setDay(self, day):
-        old_year, old_month, _ignore_old_day, old_isleapmonth = self.getDateComponents()
-        ICU.ucal_set(self.ucal, ICU.UCAL_DAY_OF_MONTH, day)
-        self.testInvalid(old_year, old_month, day, old_isleapmonth)
-
-
-    def offsetDay(self, diff_day):
-        """
-        Offset the ICU date month component by the specified amount.
-
-        @param diff_year: amount to offset
-        @type diff_year: L{int}
-        """
-        error = ffi.new("UErrorCode *", 0)
-        ICU.ucal_add(self.ucal, ICU.UCAL_DAY_OF_MONTH, diff_day, error)
-
-
-    def setYearDay(self, day, allow_invalid=False):
-
-        # Find the limit for the current year
-        error = ffi.new("UErrorCode *", 0)
-        limit = ICU.ucal_getLimit(self.ucal, ICU.UCAL_DAY_OF_YEAR, ICU.UCAL_ACTUAL_MAXIMUM, error)
-
-        if day > 0:
-            ICU.ucal_set(self.ucal, ICU.UCAL_DAY_OF_YEAR, min(day, limit))
-            if day > limit and allow_invalid:
-                self.setInvalid(self.getYear(), 1, day)
-            else:
-                self.clearInvalid()
-        elif day < 0:
-            offset = limit + day + 1
-            ICU.ucal_set(self.ucal, ICU.UCAL_DAY_OF_YEAR, max(offset, 1))
-            if offset <= 0 and allow_invalid:
-                self.setInvalid(self.getYear(), 1, day)
-            else:
-                self.clearInvalid()
-
-
-    def getYearDay(self):
-        error = ffi.new("UErrorCode *", 0)
-        return ICU.ucal_get(self.ucal, ICU.UCAL_DAY_OF_YEAR, error)
-
-
-    def setMonthDay(self, day, allow_invalid=False):
-
-        # Find the limit for the current year
-        error = ffi.new("UErrorCode *", 0)
-        limit = ICU.ucal_getLimit(self.ucal, ICU.UCAL_DAY_OF_MONTH, ICU.UCAL_ACTUAL_MAXIMUM, error)
-
-        if day > 0:
-            ICU.ucal_set(self.ucal, ICU.UCAL_DAY_OF_MONTH, min(day, limit))
-            if day > limit and allow_invalid:
-                y, m, _ignore_d, l = self.getDateComponents()
-                self.setInvalid(y, m, day, l)
-            else:
-                self.clearInvalid()
-
-        elif day < 0:
-            offset = limit + day + 1
-            ICU.ucal_set(self.ucal, ICU.UCAL_DAY_OF_MONTH, max(offset, 1))
-            if offset <= 0 and allow_invalid:
-                y, m, _ignore_d, l = self.getDateComponents()
-                self.setInvalid(y, m, day, l)
-            else:
-                self.clearInvalid()
-
-
-    def isMonthDay(self, day):
-        if day > 0:
-            return self.getDay() == day
-        elif day < 0:
-            error = ffi.new("UErrorCode *", 0)
-            limit = ICU.ucal_getLimit(self.ucal, ICU.UCAL_DAY_OF_MONTH, ICU.UCAL_ACTUAL_MAXIMUM, error)
-            return self.getDay() - 1 - limit == day
-        else:
-            return False
-
-
-    def setWeekNo(self, weekno):
-        """
-        Set the current date to one with the same day of the week in the current year with the
-        specified week number. Note this might cause the year to shift backwards or forwards
-        if the date is at the boundary between two years.
-
-        @param weekno: the week number to set (currently must be positive)
-        @type weekno: C{int}
-        """
-
-        # Only supported for Gregorian calendars
-        if self.rscale.lower() != self.RSCALE_GREGORIAN:
-            raise ValueError("Week numbers only supported for Gregorian calendars")
-        dt = self.toDateTime()
-        dt.setWeekNo(weekno)
-        self.setYYMMDD(dt.getYear(), dt.getMonth(), dt.getDay())
-
-
-    def getWeekNo(self):
-        """
-        Return the ISO week number for the current date.
-        """
-
-        # Only supported for Gregorian calendars
-        if self.rscale.lower() != self.RSCALE_GREGORIAN:
-            raise ValueError("Week numbers only supported for Gregorian calendars")
-        dt = self.toDateTime()
-        return dt.getWeekNo()
-
-
-    def isWeekNo(self, weekno):
-        # This is the iso 8601 week number definition
-
-        if weekno > 0:
-            return self.getWeekNo() == weekno
-        else:
-            # This needs to calculate the negative offset from the last week in
-            # the current year
-            return False
-
-
-    def setDayOfWeekInYear(self, offset, day):
-        # Set to first day in year
-        self.setYYMMDD(self.getYear(), 1, 1, False)
-
-        # Determine first weekday in year
-        first_day = self.getDayOfWeek()
-
-        if offset > 0:
-            cycle = (offset - 1) * 7 + day
-            cycle -= first_day
-            if first_day > day:
-                cycle += 7
-            self.offsetDay(cycle)
-        elif offset < 0:
-            # Find the limit for the current year
-            error = ffi.new("UErrorCode *", 0)
-            limit = ICU.ucal_getLimit(self.ucal, ICU.UCAL_DAY_OF_YEAR, ICU.UCAL_ACTUAL_MAXIMUM, error)
-
-            first_day += limit - 1
-            first_day %= 7
-
-            cycle = (-offset - 1) * 7 - day
-            cycle += first_day
-            if day > first_day:
-                cycle += 7
-            self.offsetDay(limit - cycle - 1)
-
-        self.clearInvalid()
-
-
-    def setDayOfWeekInMonth(self, offset, day, allow_invalid=False):
-        # Set to first day in month
-        y, m, d, l = self.getDateComponents()
-        self.setYYMMDD(y, m, 1, l)
-
-        # Determine first weekday in month
-        first_day = self.getDayOfWeek()
-
-        if offset > 0:
-            cycle = (offset - 1) * 7 + day
-            cycle -= first_day
-            if first_day > day:
-                cycle += 7
-            mday = cycle + 1
-            self.offsetDay(cycle)
-        elif offset < 0:
-            # Find the limit for the current year
-            error = ffi.new("UErrorCode *", 0)
-            days_in_month = ICU.ucal_getLimit(self.ucal, ICU.UCAL_DAY_OF_MONTH, ICU.UCAL_ACTUAL_MAXIMUM, error)
-
-            first_day += days_in_month - 1
-            first_day %= 7
-
-            cycle = (-offset - 1) * 7 - day
-            cycle += first_day
-            if day > first_day:
-                cycle += 7
-            mday = days_in_month - cycle
-            self.offsetDay(days_in_month - cycle - 1)
-
-        if self.getDay() != mday and allow_invalid:
-            self.setInvalid(y, m, d, l)
-        else:
-            self.clearInvalid()
-
-
-    def isDayOfWeekInMonth(self, offset, day):
-        # First of the actual day must match
-        if self.getDayOfWeek() != day:
-            return False
-
-        # If there is no count the we match any of this day in the month
-        if offset == 0:
-            return True
-
-        # Create temp date-time with the appropriate parameters and then
-        # compare
-        temp = self.duplicate()
-        temp.setDayOfWeekInMonth(offset, day)
-
-        # Now compare dates
-        return self.getDateComponents() == temp.getDateComponents()
-
-
-    def getDayOfWeek(self):
-        error = ffi.new("UErrorCode *", 0)
-        return ICU.ucal_get(self.ucal, ICU.UCAL_DAY_OF_WEEK, error) - 1
-
-
-    def setHHMMSS(self, hours, minutes, seconds):
-        if (self.mHours != hours) or (self.mMinutes != minutes) or (self.mSeconds != seconds):
-            self.mHours = hours
-            self.mMinutes = minutes
-            self.mSeconds = seconds
-
-
-    def getHours(self):
-        return self.mHours
-
-
-    def setHours(self, hours):
-        if self.mHours != hours:
-            self.mHours = hours
-
-
-    def offsetHours(self, diff_hour):
-        self.mHours += diff_hour
-        self.normalise()
-
-
-    def getMinutes(self):
-        return self.mMinutes
-
-
-    def setMinutes(self, minutes):
-        if self.mMinutes != minutes:
-            self.mMinutes = minutes
-
-
-    def offsetMinutes(self, diff_minutes):
-        self.mMinutes += diff_minutes
-        self.normalise()
-
-
-    def getSeconds(self):
-        return self.mSeconds
-
-
-    def setSeconds(self, seconds):
-        if self.mSeconds != seconds:
-            self.mSeconds = seconds
-
-
-    def offsetSeconds(self, diff_seconds):
-        self.mSeconds += diff_seconds
-        self.normalise()
-
-
-    def getTimezoneUTC(self):
-        return self.mTZUTC
-
-
-    def setTimezoneUTC(self, utc):
-        if self.mTZUTC != utc:
-            self.mTZUTC = utc
-
-
-    def getTimezoneID(self):
-        return self.mTZID
-
-
-    def setTimezoneID(self, tzid):
-        self.mTZUTC = False
-        self.mTZID = tzid
-
-
-    # When doing recurrence iteration we sometimes need to preserve an invalid value for
-    # either day or month (though month is never invalid for Gregorian calendars it can
-    # be for non-Gregorian). For this class we simply set the stored attributes to their
-    # invalid values.
-    def setInvalid(self, year, month, day, isleapmonth=False):
-        self.mInvalid = (year, month, day, isleapmonth,)
-
-
-    def testInvalid(self, year, month, day, isleapmonth=False):
-        """
-        If the requested set of YYMMDDLL does not match the current set of YYMMDDLL then the requested
-        set was invalid.
-        """
-        components = self.getDateComponents()
-        if components != (year, month, day, isleapmonth,):
-            self.setInvalid(year, month, day, isleapmonth)
-        else:
-            self.clearInvalid()
-
-
-    def clearInvalid(self):
-        self.mInvalid = None
-
-
-    def invalid(self):
-        """
-        Are any of the current fields invalid.
-        """
-
-        # Right now we only care about invalid days of the month (e.g. February 30th). In the
-        # future we may also want to look for invalid times during a DST transition.
-
-        return self.mInvalid is not None
-
-
-    def invalidSkip(self, skip):
-        """
-        If this is an invalid value skip backward or forward or not at all.
-
-        @param skip: the skip mode (yes, backward, forward)
-        @type skip: L{int}
-        """
-
-        if self.mInvalid:
-            if skip == definitions.eRecurrence_SKIP_YES:
-                # Leave it as invalid
-                pass
-            else:
-                # Need to determine which component (day or month/leap) is invalid,
-                # and react accordingly
-                _ignore_y, m, d, l = self.getDateComponents()
-                if (m, l) != (self.mInvalid[1], self.mInvalid[3]):
-                    # Month/leap is invalid
-                    if skip == definitions.eRecurrence_SKIP_BACKWARD:
-                        # Defaults to skip backward
-                        pass
-                    elif skip == definitions.eRecurrence_SKIP_FORWARD:
-                        self.offsetDay(1)
-
-                elif d != self.mInvalid[2]:
-                    if skip == definitions.eRecurrence_SKIP_BACKWARD:
-                        if self.mInvalid[2] < 1:
-                            self.offsetDay(-1)
-                    elif skip == definitions.eRecurrence_SKIP_FORWARD:
-                        if self.mInvalid[2] > 0:
-                            self.offsetDay(1)
-
-                self.clearInvalid()
-
-
-    def normalise(self):
-        # Normalise seconds
-        normalised_secs = self.mSeconds % 60
-        adjustment_mins = self.mSeconds / 60
-        if normalised_secs < 0:
-            normalised_secs += 60
-            adjustment_mins -= 1
-        self.mSeconds = normalised_secs
-        self.mMinutes += adjustment_mins
-
-        # Normalise minutes
-        normalised_mins = self.mMinutes % 60
-        adjustment_hours = self.mMinutes / 60
-        if normalised_mins < 0:
-            normalised_mins += 60
-            adjustment_hours -= 1
-        self.mMinutes = normalised_mins
-        self.mHours += adjustment_hours
-
-        # Normalise hours
-        normalised_hours = self.mHours % 24
-        adjustment_days = self.mHours / 24
-        if normalised_hours < 0:
-            normalised_hours += 24
-            adjustment_days -= 1
-        self.mHours = normalised_hours
-
-        self.offsetDay(adjustment_days)
-
-        # Wipe the time if date only
-        if self.mDateOnly:
-            self.mSeconds = self.mMinutes = self.mHours = 0
-
-
-    def getText(self):
-        """
-        Generate an ISO-8601 string representation of this ICU date. Use a code
-        prefix for the calendar scale.
-
-        @return: the ISO-8601 text
-        @rtype L{str}
-        """
-        calcode = self.RSCALE_CALCODE.get(self.rscale.lower(), "{}:".format(self.rscale))
-        if calcode:
-            calcode = "{{{}}}".format(calcode)
-        year, month, day, isleapmonth = self.getDateComponents()
-        date = "{}{:04d}{:02d}{}{:02d}".format(calcode, year, month, "L" if isleapmonth else "", day)
-        if not self.isDateOnly():
-            date += "T{:02d}{:02d}{:02d}{}".format(self.mHours, self.mMinutes, self.mSeconds, "Z" if self.mTZUTC else "")
-        return date
-
-
-if __name__ == '__main__':
-    newyear = ICUDateTime.fromDateComponents("chinese", 4651, 1, 1, False)
-    print("From: {} to {}".format(
-        newyear.getText(),
-        newyear.convertTo("gregorian").getText(),
-    ))
-
-    for i in range(0):
-        newyear.offsetDay(1)
-        print("From: {} to {}".format(
-            newyear.getText(),
-            newyear.convertTo("gregorian").getText(),
-        ))
-
-    offset = 1
-    greg = ICUDateTime.fromDateComponents("gregorian", 2014, 1, 31, False)
-    greg.offsetMonth(offset)
-    print(greg.getText())
-
-    greg = DateTime(2014, 1, 31)
-    greg.offsetMonth(offset)
-    print(greg.getText())

Deleted: PyCalendar/trunk/src/pycalendar/icalendar/recuriter.py
===================================================================
--- PyCalendar/trunk/src/pycalendar/icalendar/recuriter.py	2014-12-01 16:26:51 UTC (rev 14192)
+++ PyCalendar/trunk/src/pycalendar/icalendar/recuriter.py	2014-12-01 16:50:49 UTC (rev 14193)
@@ -1,151 +0,0 @@
-##
-#    Copyright (c) 2014 Cyrus Daboo. All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License");
-#    you may not use this file except in compliance with the License.
-#    You may obtain a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS,
-#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#    See the License for the specific language governing permissions and
-#    limitations under the License.
-##
-
-from pycalendar.icalendar import definitions
-from pycalendar.icalendar.icudatetime import ICUDateTime
-import collections
-
-class RecurrenceIterator(collections.Iterator):
-    """
-    An iterator that iterates a simple recurrence pattern.
-    """
-
-    def __init__(self, start, freq, interval, rscale=None, skip=definitions.eRecurrence_SKIP_YES, allow_invalid=False):
-        """
-        @param start: the start date-time
-        @type start: L{DateTime} or L{ICUDateTime}
-        @param freq: the frequency of iteration
-        @type freq: L{int}
-        @param interval: the interval for each iteration
-        @type interval: L{int}
-        @param rscale: calendar scale to apply recurrence pattern to
-        @type rscale: L{str}
-        @param skip: skipping behavior for invalid dates
-        @type skip: L{int}
-        @param allow_invalid: whether or not invalid values are allowed
-        @type allow_invalid: L{InvalidDateTime}
-        """
-        self.start = start
-        self.freq = freq
-        self.interval = interval
-        self.rscale = rscale
-        self.skip = skip
-        self.allow_invalid = allow_invalid
-
-        self.step = 0
-
-        # If an RSCALE is set, the C{self.start} value is a normal L{DateTime} object but we want
-        # to have the recurrence apply to the non-Gregorian calendar. So convert the C{self.start}
-        # value into the corresponding L{ICUDateTime} object.
-        if self.rscale:
-            self.start = ICUDateTime.fromDateTime(self.start, self.rscale)
-
-
-    def __iter__(self):
-        return self
-
-
-    def next(self):
-        """
-        Iterate one step of the recurrence. Always return an L{DateTime} for an rscale based
-        recurrence.
-
-        @return: the resulting date-time - this object is not re-used by the iterator so can be used
-            directly by the caller without any need to copy it
-        @rtype L{DateTime}
-        """
-
-        dt = self.nextraw()
-
-        # Always return the L{DateTime} equivalent when using C{self.rscale}
-        return dt.toDateTime() if self.rscale else dt
-
-
-    def nextraw(self):
-        """
-        Iterate one step of the recurrence using the native date-time calendar scale, and return
-        the native value.
-
-        @return: the resulting date-time - this object is not re-used by the iterator so can be used
-            directly by the caller without any need to copy it
-        @rtype L{DateTime} or L{ICUDateTime}
-        """
-
-        dt = self.start.duplicate()
-
-        # Add appropriate interval
-        if self.freq == definitions.eRecurrence_SECONDLY:
-            dt.offsetSeconds(self.step)
-        elif self.freq == definitions.eRecurrence_MINUTELY:
-            dt.offsetMinutes(self.step)
-        elif self.freq == definitions.eRecurrence_HOURLY:
-            dt.offsetHours(self.step)
-        elif self.freq == definitions.eRecurrence_DAILY:
-            dt.offsetDay(self.step)
-        elif self.freq == definitions.eRecurrence_WEEKLY:
-            dt.offsetDay(7 * self.step)
-        elif self.freq == definitions.eRecurrence_MONTHLY:
-            dt.offsetMonth(self.step)
-
-            # Check whether the day matches the start - if not we stepped
-            # to an invalid date so apply skip behavior
-            if dt.getDay() != self.start.getDay():
-                if self.allow_invalid:
-                    dt.setInvalid(dt.getYear(), dt.getMonth(), self.start.getDay(), dt.getLeapMonth())
-                elif self.skip == definitions.eRecurrence_SKIP_YES:
-                    # Iterate until we have a valid month
-                    while dt.getDay() != self.start.getDay():
-                        self.step += self.interval
-                        dt = self.start.duplicate()
-                        dt.offsetMonth(self.step)
-                elif self.skip == definitions.eRecurrence_SKIP_BACKWARD:
-                    # Both ICU and PyCalendar skip back by default
-                    pass
-                elif self.skip == definitions.eRecurrence_SKIP_FORWARD:
-                    # Go one day forward
-                    dt.offsetDay(1)
-
-        elif self.freq == definitions.eRecurrence_YEARLY:
-            dt.offsetYear(self.step)
-
-            # Check whether the month/day matches the start - if not we stepped
-            # to an invalid date so apply skip behavior
-            if dt.getDay() != self.start.getDay() or dt.getMonth() != self.start.getMonth() or dt.getLeapMonth() != self.start.getLeapMonth():
-                if self.allow_invalid:
-                    dt.setInvalid(dt.getYear(), self.start.getMonth(), self.start.getDay(), self.start.getLeapMonth())
-                elif self.skip == definitions.eRecurrence_SKIP_YES:
-                    # Iterate until we have a valid date-time
-                    while dt.getDay() != self.start.getDay() or dt.getMonth() != self.start.getMonth() or dt.getLeapMonth() != self.start.getLeapMonth():
-                        self.step += self.interval
-                        dt = self.start.duplicate()
-                        dt.offsetYear(self.step)
-                elif self.skip == definitions.eRecurrence_SKIP_BACKWARD:
-                    # Both ICU and PyCalendar skip back by default
-                    pass
-                elif self.skip == definitions.eRecurrence_SKIP_FORWARD:
-                    # Go one day forward
-                    dt.offsetDay(1)
-
-        self.step += self.interval
-
-        return dt
-
-
-if __name__ == '__main__':
-    icudt = ICUDateTime.fromDateComponents("gregorian", 2014, 1, 31)
-    iter = RecurrenceIterator(icudt, definitions.eRecurrence_MONTHLY, 1, definitions.eRecurrence_SKIP_BACKWARD)
-    for i in range(12):
-        print(iter.next().getText())

Modified: PyCalendar/trunk/src/pycalendar/icalendar/recurrence.py
===================================================================
--- PyCalendar/trunk/src/pycalendar/icalendar/recurrence.py	2014-12-01 16:26:51 UTC (rev 14192)
+++ PyCalendar/trunk/src/pycalendar/icalendar/recurrence.py	2014-12-01 16:50:49 UTC (rev 14193)
@@ -21,7 +21,6 @@
 from pycalendar.valueutils import ValueMixin
 import cStringIO as StringIO
 import xml.etree.cElementTree as XML
-from pycalendar.icalendar.recuriter import RecurrenceIterator
 
 def WeekDayNumCompare_compare(w1, w2):
 
@@ -56,8 +55,6 @@
         definitions.cICalValue_RECUR_YEARLY   : definitions.eRecurrence_YEARLY,
     }
 
-    cFreqInverseMap = dict([(v, k) for k, v in cFreqMap.items()])
-
     cFreqToXMLMap = {
         definitions.eRecurrence_SECONDLY: xmldefinitions.recur_freq_secondly,
         definitions.eRecurrence_MINUTELY: xmldefinitions.recur_freq_minutely,
@@ -83,8 +80,6 @@
         definitions.cICalValue_RECUR_BYMONTH    : definitions.eRecurrence_BYMONTH,
         definitions.cICalValue_RECUR_BYSETPOS   : definitions.eRecurrence_BYSETPOS,
         definitions.cICalValue_RECUR_WKST       : definitions.eRecurrence_WKST,
-        definitions.cICalValue_RECUR_RSCALE     : definitions.eRecurrence_RSCALE,
-        definitions.cICalValue_RECUR_SKIP       : definitions.eRecurrence_SKIP,
     }
 
     cWeekdayMap = {
@@ -99,20 +94,6 @@
 
     cWeekdayRecurMap = dict([(v, k) for k, v in cWeekdayMap.items()])
 
-    cSkipMap = {
-        definitions.cICalValue_RECUR_SKIP_YES       : definitions.eRecurrence_SKIP_YES,
-        definitions.cICalValue_RECUR_SKIP_BACKWARD  : definitions.eRecurrence_SKIP_BACKWARD,
-        definitions.cICalValue_RECUR_SKIP_FORWARD   : definitions.eRecurrence_SKIP_FORWARD,
-    }
-
-    cSkipInverseMap = dict([(v, k) for k, v in cSkipMap.items()])
-
-    cSkipToXMLMap = {
-        definitions.eRecurrence_SKIP_YES: xmldefinitions.recur_skip_yes,
-        definitions.eRecurrence_SKIP_BACKWARD: xmldefinitions.recur_skip_backward,
-        definitions.eRecurrence_SKIP_FORWARD: xmldefinitions.recur_skip_forward,
-    }
-
     cUnknownIndex = -1
 
     def __init__(self):
@@ -122,7 +103,6 @@
     def duplicate(self):
         other = Recurrence()
 
-        other.mRscale = self.mRscale
         other.mFreq = self.mFreq
 
         other.mUseCount = self.mUseCount
@@ -132,9 +112,6 @@
             other.mUntil = self.mUntil.duplicate()
 
         other.mInterval = self.mInterval
-
-        other.mSkip = self.mSkip
-
         if self.mBySeconds is not None:
             other.mBySeconds = self.mBySeconds[:]
         if self.mByMinutes is not None:
@@ -168,8 +145,6 @@
 
 
     def init_Recurrence(self):
-
-        self.mRscale = None
         self.mFreq = definitions.eRecurrence_YEARLY
 
         self.mUseCount = False
@@ -179,9 +154,6 @@
         self.mUntil = None
 
         self.mInterval = 1
-
-        self.mSkip = None
-
         self.mBySeconds = None
         self.mByMinutes = None
         self.mByHours = None
@@ -202,14 +174,12 @@
 
     def __hash__(self):
         return hash((
-            self.mRscale,
             self.mFreq,
             self.mUseCount,
             self.mCount,
             self.mUseUntil,
             self.mUntil,
             self.mInterval,
-            self.mSkip,
             tuple(self.mBySeconds) if self.mBySeconds else None,
             tuple(self.mByMinutes) if self.mByMinutes else None,
             tuple(self.mByHours) if self.mByHours else None,
@@ -235,12 +205,10 @@
 
     def equals(self, comp):
         return (
-            (self.mRscale == comp.mRscale)
-            and (self.mFreq == comp.mFreq)
+            (self.mFreq == comp.mFreq)
             and (self.mUseCount == comp.mUseCount) and (self.mCount == comp.mCount)
             and (self.mUseUntil == comp.mUseUntil) and (self.mUntil == comp.mUntil)
             and (self.mInterval == comp.mInterval)
-            and (self.mSkip == comp.mSkip)
             and self.equalsNum(self.mBySeconds, comp.mBySeconds)
             and self.equalsNum(self.mByMinutes, comp.mByMinutes)
             and self.equalsNum(self.mByHours, comp.mByHours)
@@ -306,14 +274,6 @@
             setattr(self, attr, value)
 
 
-    def getRscale(self):
-        return self.mRscale
-
-
-    def setRscale(self, rscale):
-        self._setAndclearIfChanged("mRscale", rscale)
-
-
     def getFreq(self):
         return self.mFreq
 
@@ -362,24 +322,6 @@
         self._setAndclearIfChanged("mInterval", interval)
 
 
-    def getSkip(self):
-        return self.mSkip
-
-
-    def effectiveSkip(self):
-        """
-        The default skip value depends on whether RSCALE is used or not
-        """
-        if self.mSkip is None:
-            return definitions.eRecurrence_SKIP_YES if self.mRscale is None else definitions.eRecurrence_SKIP_BACKWARD
-        else:
-            return self.mSkip
-
-
-    def setSkip(self, skip):
-        self._setAndclearIfChanged("mSkip", skip)
-
-
     def getByMonth(self):
         return self.mByMonth
 
@@ -531,7 +473,7 @@
                 if self.mByMonth is not None:
                     raise ValueError("Recurrence: Only one BYMONTH allowed")
                 self.mByMonth = []
-                self.parseMonthNumList(tvalue, self.mByMonth, 1, 12, errmsg="Recurrence: Invalid BYMONTH value")
+                self.parseList(tvalue, self.mByMonth, 1, 12, errmsg="Recurrence: Invalid BYMONTH value")
 
             elif index == definitions.eRecurrence_BYSETPOS:
                 if self.mBySetPos is not None:
@@ -545,21 +487,7 @@
                     raise ValueError("Recurrence: Invalid WKST value")
                 self.mWeekstart = index
 
-            elif index == definitions.eRecurrence_RSCALE:
-                self.mRscale = tvalue.upper()
 
-            elif index == definitions.eRecurrence_SKIP:
-                # Get the SKIP value
-                index = Recurrence.cSkipMap.get(tvalue, Recurrence.cUnknownIndex)
-                if index == Recurrence.cUnknownIndex:
-                    raise ValueError("Recurrence: Invalid SKIP value")
-                self.mSkip = index
-
-        # Final validity checks
-        if self.mRscale is None and self.mSkip is not None:
-            raise ValueError("Recurrence: SKIP only allowed with RSCALE")
-
-
     def parseList(self, txt, list, min=None, max=None, allowNegative=False, errmsg=""):
 
         if "," in txt:
@@ -579,33 +507,6 @@
             list.append(value)
 
 
-    def parseMonthNumList(self, txt, list, min=None, max=None, allowNegative=False, errmsg=""):
-        """
-        Month numbers can include "L" leap month suffix.
-        """
-
-        if "," in txt:
-            tokens = txt.split(",")
-        else:
-            tokens = (txt,)
-
-        for token in tokens:
-            if token.endswith("L"):
-                suffix = True
-                token = token[:-1]
-            else:
-                suffix = False
-            value = int(token)
-            if not allowNegative and value < 0:
-                raise ValueError(errmsg)
-            avalue = abs(value)
-            if min is not None and avalue < min:
-                raise ValueError(errmsg)
-            if max is not None and avalue > max:
-                raise ValueError(errmsg)
-            list.append((value, suffix,))
-
-
     def parseListDW(self, txt, list, errmsg=""):
 
         if "," in txt:
@@ -641,16 +542,30 @@
 
     def generate(self, os):
         try:
-            if self.mRscale:
-                os.write(definitions.cICalValue_RECUR_RSCALE)
-                os.write("=")
-                os.write(self.mRscale.upper())
-                os.write(";")
-
             os.write(definitions.cICalValue_RECUR_FREQ)
             os.write("=")
-            os.write(self.cFreqInverseMap[self.mFreq])
 
+            if self.mFreq == definitions.eRecurrence_SECONDLY:
+                os.write(definitions.cICalValue_RECUR_SECONDLY)
+
+            elif self.mFreq == definitions.eRecurrence_MINUTELY:
+                os.write(definitions.cICalValue_RECUR_MINUTELY)
+
+            elif self.mFreq == definitions.eRecurrence_HOURLY:
+                os.write(definitions.cICalValue_RECUR_HOURLY)
+
+            elif self.mFreq == definitions.eRecurrence_DAILY:
+                os.write(definitions.cICalValue_RECUR_DAILY)
+
+            elif self.mFreq == definitions.eRecurrence_WEEKLY:
+                os.write(definitions.cICalValue_RECUR_WEEKLY)
+
+            elif self.mFreq == definitions.eRecurrence_MONTHLY:
+                os.write(definitions.cICalValue_RECUR_MONTHLY)
+
+            elif self.mFreq == definitions.eRecurrence_YEARLY:
+                os.write(definitions.cICalValue_RECUR_YEARLY)
+
             if self.mUseCount:
                 os.write(";")
                 os.write(definitions.cICalValue_RECUR_COUNT)
@@ -668,12 +583,6 @@
                 os.write("=")
                 os.write(str(self.mInterval))
 
-            if self.mSkip is not None:
-                os.write(";")
-                os.write(definitions.cICalValue_RECUR_SKIP)
-                os.write("=")
-                os.write(self.cSkipInverseMap[self.mSkip])
-
             self.generateList(os, definitions.cICalValue_RECUR_BYSECOND, self.mBySeconds)
             self.generateList(os, definitions.cICalValue_RECUR_BYMINUTE, self.mByMinutes)
             self.generateList(os, definitions.cICalValue_RECUR_BYHOUR, self.mByHours)
@@ -715,7 +624,7 @@
             self.generateList(os, definitions.cICalValue_RECUR_BYMONTHDAY, self.mByMonthDay)
             self.generateList(os, definitions.cICalValue_RECUR_BYYEARDAY, self.mByYearDay)
             self.generateList(os, definitions.cICalValue_RECUR_BYWEEKNO, self.mByWeekNo)
-            self.generateMonthNumList(os, definitions.cICalValue_RECUR_BYMONTH, self.mByMonth)
+            self.generateList(os, definitions.cICalValue_RECUR_BYMONTH, self.mByMonth)
             self.generateList(os, definitions.cICalValue_RECUR_BYSETPOS, self.mBySetPos)
 
             # MO is the default so we do not need it
@@ -763,31 +672,10 @@
                 os.write(str(e))
 
 
-    def generateMonthNumList(self, os, title, items):
-        """
-        Month numbers can include "L" leap month suffix.
-        """
-
-        if (items is not None) and (len(items) != 0):
-            os.write(";")
-            os.write(title)
-            os.write("=")
-            comma = False
-            for item in items:
-                if comma:
-                    os.write(",")
-                comma = True
-                os.write(str(item[0]) + ("L" if item[1] else ""))
-
-
     def writeXML(self, node, namespace):
 
         recur = XML.SubElement(node, xmlutils.makeTag(namespace, xmldefinitions.value_recur))
 
-        if self.mRscale:
-            freq = XML.SubElement(recur, xmlutils.makeTag(namespace, xmldefinitions.recur_rscale))
-            freq.text = self.mRscale
-
         freq = XML.SubElement(recur, xmlutils.makeTag(namespace, xmldefinitions.recur_freq))
         freq.text = self.cFreqToXMLMap[self.mFreq]
 
@@ -802,10 +690,6 @@
             interval = XML.SubElement(recur, xmlutils.makeTag(namespace, xmldefinitions.recur_interval))
             interval.text = str(self.mInterval)
 
-        if self.mSkip is not None:
-            skip = XML.SubElement(recur, xmlutils.makeTag(namespace, xmldefinitions.recur_skip))
-            skip.text = self.cSkipToXMLMap[self.mSkip]
-
         self.writeXMLList(recur, namespace, xmldefinitions.recur_bysecond, self.mBySeconds)
         self.writeXMLList(recur, namespace, xmldefinitions.recur_byminute, self.mByMinutes)
         self.writeXMLList(recur, namespace, xmldefinitions.recur_byhour, self.mByHours)
@@ -822,7 +706,7 @@
         self.writeXMLList(recur, namespace, xmldefinitions.recur_bymonthday, self.mByMonthDay)
         self.writeXMLList(recur, namespace, xmldefinitions.recur_byyearday, self.mByYearDay)
         self.writeXMLList(recur, namespace, xmldefinitions.recur_byweekno, self.mByWeekNo)
-        self.writeXMLMonthNumList(recur, namespace, xmldefinitions.recur_bymonth, self.mByMonth)
+        self.writeXMLList(recur, namespace, xmldefinitions.recur_bymonth, self.mByMonth)
         self.writeXMLList(recur, namespace, xmldefinitions.recur_bysetpos, self.mBySetPos)
 
         # MO is the default so we do not need it
@@ -838,17 +722,6 @@
                 child.text = str(item)
 
 
-    def writeXMLMonthNumList(self, node, namespace, name, items):
-        """
-        Month numbers can include "L" leap month suffix.
-        """
-
-        if items is not None and len(items) != 0:
-            for item in items:
-                child = XML.SubElement(node, xmlutils.makeTag(namespace, name))
-                child.text = str(item[0]) + ("L" if item[1] else "")
-
-
     def parseJSON(self, jobject):
         """
         jCal splits the value into components. We need to convert that back to the
@@ -877,9 +750,6 @@
         """
         jdict = {}
 
-        if self.mRscale:
-            jdict[xmldefinitions.recur_rscale] = self.mRscale
-
         jdict[xmldefinitions.recur_freq] = self.cFreqToXMLMap[self.mFreq]
 
         if self.mUseCount:
@@ -890,9 +760,6 @@
         if self.mInterval > 1:
             jdict[xmldefinitions.recur_interval] = self.mInterval
 
-        if self.mSkip is not None:
-            jdict[xmldefinitions.recur_skip] = self.cSkipToXMLMap[self.mSkip]
-
         if self.mBySeconds:
             jdict[xmldefinitions.recur_bysecond] = self.mBySeconds
         if self.mByMinutes:
@@ -917,7 +784,7 @@
         if self.mByWeekNo:
             jdict[xmldefinitions.recur_byweekno] = self.mByWeekNo
         if self.mByMonth:
-            jdict[xmldefinitions.recur_bymonth] = [(str(item[0]) + "L") if item[1] else item[0] for item in self.mByMonth]
+            jdict[xmldefinitions.recur_bymonth] = self.mByMonth
         if self.mBySetPos:
             jdict[xmldefinitions.recur_bysetpos] = self.mBySetPos
 
@@ -1058,7 +925,9 @@
         return limited
 
 
-    def simpleExpand(self, start, range, results, float_offset):
+    def simpleExpand(self, start, range, items, float_offset):
+        start_iter = start.duplicate()
+        ctr = 0
 
         if self.mUseUntil:
             float_until = self.mUntil.duplicate()
@@ -1066,30 +935,35 @@
                 float_until.setTimezoneID(0)
                 float_until.offsetSeconds(float_offset)
 
-        riter = RecurrenceIterator(start, self.mFreq, self.mInterval, self.mRscale, self.effectiveSkip())
         while True:
-            start_iter = riter.next()
-
             # Exit if after period we want
             if range.isDateAfterPeriod(start_iter):
                 return False
-            elif self.mUseUntil:
-                # Exit if next item is after until (it is OK if it is the same as
-                # UNTIL as UNTIL is inclusive)
-                if start_iter > float_until:
-                    return True
 
             # Add current one to list
-            results.append(start_iter)
+            items.append(start_iter.duplicate())
 
+            # Get next item
+            start_iter.recur(self.mFreq, self.mInterval, allow_invalid=True)
+            while start_iter.invalid():
+                start_iter.recur(self.mFreq, self.mInterval, allow_invalid=True)
+
             # Check limits
             if self.mUseCount:
-                # Exit if max count reached
-                if len(results) >= self.mCount:
+                # Bump counter and exit if over
+                ctr += 1
+                if ctr >= self.mCount:
                     return True
+            elif self.mUseUntil:
+                # Exit if next item is after until (its OK if its the same as
+                # UNTIL as UNTIL is inclusive)
+                if start_iter > float_until:
+                    return True
 
 
-    def complexExpand(self, start, range, results, float_offset):
+    def complexExpand(self, start, range, items, float_offset):
+        start_iter = start.duplicate()
+        ctr = 0
 
         if self.mUseUntil:
             float_until = self.mUntil.duplicate()
@@ -1097,15 +971,16 @@
                 float_until.setTimezoneID(None)
                 float_until.offsetSeconds(float_offset)
 
-        # Allow invalid values during the complex iteration as those may end up being coerced to a valid value
-        # when a BYxxx rule expands
-        riter = RecurrenceIterator(start, self.mFreq, self.mInterval, self.mRscale, self.effectiveSkip(), allow_invalid=True)
-        while True:
-            # Keep the iterated date-time value in its native calendar scale
-            start_iter = riter.nextraw()
+        # Always add the initial instance DTSTART
+        if self.mUseCount:
+            # Bump counter and exit if over
+            ctr += 1
+            if ctr >= self.mCount:
+                return True
 
-            # Each recurrence cycle may generate multiple items based on the frequency and other rule parts,
-            # but we need to limit based on until and range and count
+        # Need to re-initialise start based on BYxxx rules
+        while True:
+            # Behaviour is based on frequency
             set_items = []
 
             if self.mFreq == definitions.eRecurrence_SECONDLY:
@@ -1130,23 +1005,12 @@
                 self.generateYearlySet(start_iter, set_items)
 
             # Ignore if it is invalid
-            def _invalidMap(dt):
-                dt.invalidSkip(self.effectiveSkip())
-                return dt
-            set_items = map(lambda x: _invalidMap(x), set_items)
             set_items = filter(lambda x: not x.invalid(), set_items)
 
             # Always sort the set as BYxxx rules may not be sorted
             # set_items.sort(cmp=DateTime.sort)
             set_items.sort(key=lambda x: x.getPosixTime())
 
-            if (self.mBySetPos is not None) and (len(self.mBySetPos) != 0):
-                set_items[:] = self.bySetPosLimit(set_items)
-
-            # Remaining behavior requires L{DateTime} objects
-            if self.mRscale:
-                set_items[:] = map(lambda date: date.toDateTime(), set_items)
-
             # Process each one in the generated set
             for iter in set_items:
 
@@ -1163,22 +1027,34 @@
                     return False
 
                 # Exit if beyond the UNTIL limit
-                elif self.mUseUntil:
+                if self.mUseUntil:
                     # Exit if next item is after until (its OK if its the same
                     # as UNTIL as UNTIL is inclusive)
                     if iter > float_until:
                         return True
 
+                # Special for start instance
+                if (ctr == 1) and (start == iter):
+                    continue
+
                 # Add current one to list
-                results.append(iter)
+                items.append(iter)
 
                 # Check limits
                 if self.mUseCount:
-                    # Exit if max count reached
-                    if len(results) >= self.mCount:
+                    # Bump counter and exit if over
+                    ctr += 1
+                    if ctr >= self.mCount:
                         return True
 
+            # Exit if after period we want
+            if range.isDateAfterPeriod(start_iter):
+                return False
 
+            # Get next item
+            start_iter.recur(self.mFreq, self.mInterval, allow_invalid=True)
+
+
     def clear(self):
         self.mCached = False
         self.mFullyCached = False
@@ -1189,7 +1065,8 @@
     # IMPORTANT ExcludeFutureRecurrence assumes mCacheStart is setup with the
     # owning VEVENT's DTSTART
     # Currently this method is only called when a recurrence is being removed
-    # so the recurrence data should be cached
+    # so
+    # the recurrence data should be cached
 
     # Exclude dates on or after the chosen one
     def excludeFutureRecurrence(self, exclude):
@@ -1221,7 +1098,7 @@
         # All possible BYxxx are valid, though some combinations are not
 
         # Start with initial date-time
-        items.append(start)
+        items.append(start.duplicate())
 
         if (self.mByMonth is not None) and (len(self.mByMonth) != 0):
             items[:] = self.byMonthExpand(items)
@@ -1261,12 +1138,15 @@
         if (self.mBySeconds is not None) and (len(self.mBySeconds) != 0):
             items[:] = self.bySecondExpand(items)
 
+        if (self.mBySetPos is not None) and (len(self.mBySetPos) != 0):
+            items[:] = self.bySetPosLimit(items)
 
+
     def generateMonthlySet(self, start, items):
         # Cannot have BYYEARDAY and BYWEEKNO
 
         # Start with initial date-time
-        items.append(start)
+        items.append(start.duplicate())
 
         if (self.mByMonth is not None) and (len(self.mByMonth) != 0):
             # BYMONTH limits the range of possible values
@@ -1303,12 +1183,15 @@
         if ((self.mBySeconds is not None) and (len(self.mBySeconds) != 0)):
             items[:] = self.bySecondExpand(items)
 
+        if ((self.mBySetPos is not None) and (len(self.mBySetPos) != 0)):
+            items[:] = self.bySetPosLimit(items)
 
+
     def generateWeeklySet(self, start, items):
         # Cannot have BYYEARDAY and BYMONTHDAY
 
         # Start with initial date-time
-        items.append(start)
+        items.append(start.duplicate())
 
         if (self.mByMonth is not None) and (len(self.mByMonth) != 0):
             # BYMONTH limits the range of possible values
@@ -1337,12 +1220,15 @@
         if (self.mBySeconds is not None) and (len(self.mBySeconds) != 0):
             items[:] = self.bySecondExpand(items)
 
+        if (self.mBySetPos is not None) and (len(self.mBySetPos) != 0):
+            items[:] = self.bySetPosLimit(items)
 
+
     def generateDailySet(self, start, items):
         # Cannot have BYYEARDAY
 
         # Start with initial date-time
-        items.append(start)
+        items.append(start.duplicate())
 
         if (self.mByMonth is not None) and (len(self.mByMonth) != 0):
             # BYMONTH limits the range of possible values
@@ -1376,12 +1262,15 @@
         if (self.mBySeconds is not None) and (len(self.mBySeconds) != 0):
             items[:] = self.bySecondExpand(items)
 
+        if (self.mBySetPos is not None) and (len(self.mBySetPos) != 0):
+            items[:] = self.bySetPosLimit(items)
 
+
     def generateHourlySet(self, start, items):
         # Cannot have BYYEARDAY
 
         # Start with initial date-time
-        items.append(start)
+        items.append(start.duplicate())
 
         if (self.mByMonth is not None) and (len(self.mByMonth) != 0):
             # BYMONTH limits the range of possible values
@@ -1417,12 +1306,15 @@
         if (self.mBySeconds is not None) and (len(self.mBySeconds) != 0):
             items[:] = self.bySecondExpand(items)
 
+        if (self.mBySetPos is not None) and (len(self.mBySetPos) != 0):
+            items[:] = self.bySetPosLimit(items)
 
+
     def generateMinutelySet(self, start, items):
         # Cannot have BYYEARDAY
 
         # Start with initial date-time
-        items.append(start)
+        items.append(start.duplicate())
 
         if (self.mByMonth is not None) and (len(self.mByMonth) != 0):
             # BYMONTH limits the range of possible values
@@ -1460,12 +1352,15 @@
         if (self.mBySeconds is not None) and (len(self.mBySeconds) != 0):
             items[:] = self.bySecondExpand(items)
 
+        if (self.mBySetPos is not None) and (len(self.mBySetPos) != 0):
+            items[:] = self.bySetPosLimit(items)
 
+
     def generateSecondlySet(self, start, items):
         # Cannot have BYYEARDAY
 
         # Start with initial date-time
-        items.append(start)
+        items.append(start.duplicate())
 
         if (self.mByMonth is not None) and (len(self.mByMonth) != 0):
             # BYMONTH limits the range of possible values
@@ -1505,7 +1400,10 @@
             if (len(items) == 0):
                 return
 
+        if (self.mBySetPos is not None) and (len(self.mBySetPos) != 0):
+            items[:] = self.bySetPosLimit(items)
 
+
     def byMonthExpand(self, dates):
         # Loop over all input items
         output = []
@@ -1514,7 +1412,7 @@
             # insert into output
             for iter2 in self.mByMonth:
                 temp = iter1.duplicate()
-                temp.setMonth(*iter2)
+                temp.setMonth(iter2)
                 output.append(temp)
 
         return output
@@ -1683,40 +1581,125 @@
 
 
     def byMonthLimit(self, dates):
-        # Keep each date that matches a BYMONTH
-        return filter(lambda date: date.getMonth() in self.mByMonth, dates)
+        # Loop over all input items
+        output = []
+        for iter1 in dates:
+            # Loop over each BYMONTH and indicate keep if input month matches
+            keep = False
+            for iter2 in self.mByMonth:
+                keep = (iter1.getMonth() == iter2)
+                if keep:
+                    break
 
+            if keep:
+                output.append(iter1)
 
+        return output
+
+
     def byWeekNoLimit(self, dates):
-        # Keep each date that matches a BYWEEKNO
-        return filter(lambda date: any([date.isWeekNo(iter) for iter in self.mByWeekNo]), dates)
+        # Loop over all input items
+        output = []
+        for iter1 in dates:
+            # Loop over each BYWEEKNO and indicate keep if input month matches
+            keep = False
+            for iter2 in self.mByWeekNo:
+                keep = iter1.isWeekNo(iter2)
+                if keep:
+                    break
 
+            if keep:
+                output.append(iter1)
 
+        return output
+
+
     def byMonthDayLimit(self, dates):
-        # Keep each date that matches a BYMONTHDAY
-        return filter(lambda date: any([date.isMonthDay(iter) for iter in self.mByMonthDay]), dates)
+        # Loop over all input items
+        output = []
+        for iter1 in dates:
+            # Loop over each BYMONTHDAY and indicate keep if input month
+            # matches
+            keep = False
+            for iter2 in self.mByMonthDay:
+                keep = iter1.isMonthDay(iter2)
+                if keep:
+                    break
 
+            if keep:
+                output.append(iter1)
 
+        return output
+
+
     def byDayLimit(self, dates):
-        # Keep each date that matches a BYDAY
-        return filter(lambda date: any([date.isDayOfWeekInMonth(iter[0], iter[1]) for iter in self.mByDay]), dates)
+        # Loop over all input items
+        output = []
+        for iter1 in dates:
+            # Loop over each BYDAY and indicate keep if input month matches
+            keep = False
+            for iter2 in self.mByDay:
+                keep = iter1.isDayOfWeekInMonth(iter2[0], iter2[1])
+                if keep:
+                    break
 
+            if keep:
+                output.append(iter1)
 
+        return output
+
+
     def byHourLimit(self, dates):
-        # Keep each date that matches a BYHOUR
-        return filter(lambda date: date.getHours() in self.mByHours, dates)
+        # Loop over all input items
+        output = []
+        for iter1 in dates:
+            # Loop over each BYHOUR and indicate keep if input hour matches
+            keep = False
+            for iter2 in self.mByHours:
+                keep = (iter1.getHours() == iter2)
+                if keep:
+                    break
 
+            if keep:
+                output.append(iter1)
 
+        return output
+
+
     def byMinuteLimit(self, dates):
-        # Keep each date that matches a BYMINUTE
-        return filter(lambda date: date.getMinutes() in self.mByMinutes, dates)
+        # Loop over all input items
+        output = []
+        for iter1 in dates:
+            # Loop over each BYMINUTE and indicate keep if input minute matches
+            keep = False
+            for iter2 in self.mByMinutes:
+                keep = (iter1.getMinutes() == iter2)
+                if keep:
+                    break
 
+            if keep:
+                output.append(iter1)
 
+        return output
+
+
     def bySecondLimit(self, dates):
-        # Keep each date that matches a BYSECOND
-        return filter(lambda date: date.getSeconds() in self.mBySeconds, dates)
+        # Loop over all input items
+        output = []
+        for iter1 in dates:
+            # Loop over each BYSECOND and indicate keep if input second matches
+            keep = False
+            for iter2 in self.mBySeconds:
+                keep = (iter1.getSeconds() == iter2)
+                if keep:
+                    break
 
+            if keep:
+                output.append(iter1)
 
+        return output
+
+
     def bySetPosLimit(self, dates):
         # The input dates MUST be sorted in order for this to work properly
         # dates.sort(cmp=DateTime.sort)

Deleted: PyCalendar/trunk/src/pycalendar/icalendar/tests/test_icudatetime.py
===================================================================
--- PyCalendar/trunk/src/pycalendar/icalendar/tests/test_icudatetime.py	2014-12-01 16:26:51 UTC (rev 14192)
+++ PyCalendar/trunk/src/pycalendar/icalendar/tests/test_icudatetime.py	2014-12-01 16:50:49 UTC (rev 14193)
@@ -1,225 +0,0 @@
-# coding: utf-8
-##
-#    Copyright (c) 2007-2013 Cyrus Daboo. All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License");
-#    you may not use this file except in compliance with the License.
-#    You may obtain a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS,
-#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#    See the License for the specific language governing permissions and
-#    limitations under the License.
-##
-
-import unittest
-from pycalendar.datetime import DateTime
-from pycalendar.icalendar.icudatetime import ICUDateTime
-
-class TestICUDateTime(unittest.TestCase):
-    """
-    Test L{ICUDateTime}
-    """
-
-    def testRoundtripDateText(self):
-
-        data_date = (
-            ("gregorian", 2011, 1, 2, False, "20110102",),
-            ("gregorian", 1, 1, 2, False, "00010102",),
-            ("chinese", 4651, 1, 1, False, "{C}46510101",),
-            ("chinese", 4651, 9, 1, True, "{C}465109L01",),
-        )
-
-        for rscale, y, m, d, l, result in data_date:
-            dt = ICUDateTime.fromDateComponents(rscale, y, m, d, l)
-            self.assertEqual(dt.getText(), result, "Failed on: %s" % (result,))
-
-
-    def testRoundtripDateTime(self):
-
-        data = (
-            ("20110102", "gregorian", "20110102"),
-            ("20110102T010203Z", "gregorian", "20110102T010203Z"),
-            ("00010102", "gregorian", "00010102"),
-            ("20140102", "chinese", "{C}46501202"),
-            ("20140102T010203Z", "chinese", "{C}46501202T010203Z"),
-            ("20141025", "chinese", "{C}465109L02"),
-            ("20141025T010203", "chinese", "{C}465109L02T010203"),
-        )
-
-        for item, rscale, uitem in data:
-            dt = DateTime.parseText(item, False)
-            udt = ICUDateTime.fromDateTime(dt, rscale)
-            self.assertEqual(udt.getText(), uitem, "Failed on icu: %s" % (uitem,))
-            result = udt.toDateTime()
-            self.assertEqual(result.getText(), item, "Failed on dt: %s" % (item,))
-
-
-    def testSetYear(self):
-
-        data_date = (
-            ("gregorian", 2012, 1, 2, False, 2013, "20130102", False,),
-            ("gregorian", 2012, 2, 29, False, 2013, "20130301", True,),
-            ("gregorian", 2012, 2, 29, False, 2016, "20160229", False,),
-        )
-
-        for rscale, y, m, d, l, year, result, result_invalid in data_date:
-            dt = ICUDateTime.fromDateComponents(rscale, y, m, d, l)
-            dt.setYear(year)
-            self.assertEqual(dt.getText(), result, "Failed on: {} {} {}".format(year, result, result_invalid,))
-            self.assertEqual(dt.invalid(), result_invalid, "Failed invalid on: {} {} {}".format(year, result, result_invalid,))
-
-
-    def testOffsetYear(self):
-
-        data_date = (
-            ("gregorian", 2012, 1, 2, False, 1, "20130102", False,),
-            ("gregorian", 2012, 2, 29, False, 1, "20130228", False,),
-            ("gregorian", 2012, 2, 29, False, 4, "20160229", False,),
-        )
-
-        for rscale, y, m, d, l, year, result, result_invalid in data_date:
-            dt = ICUDateTime.fromDateComponents(rscale, y, m, d, l)
-            dt.offsetYear(year)
-            self.assertEqual(dt.getText(), result, "Failed on: {} {} {}".format(year, result, result_invalid,))
-            self.assertEqual(dt.invalid(), result_invalid, "Failed invalid on: {} {} {}".format(year, result, result_invalid,))
-
-
-    def testSetMonth(self):
-
-        data_date = (
-            ("gregorian", 2012, 1, 2, False, 2, "20120202", False,),
-            ("gregorian", 2012, 1, 29, False, 2, "20120229", False,),
-            ("gregorian", 2012, 1, 31, False, 2, "20120302", True,),
-            ("gregorian", 2012, 2, 29, False, 3, "20120329", False,),
-        )
-
-        for rscale, y, m, d, l, month, result, result_invalid in data_date:
-            dt = ICUDateTime.fromDateComponents(rscale, y, m, d, l)
-            dt.setMonth(month)
-            self.assertEqual(dt.getText(), result, "Failed on: {} {} {}".format(month, result, result_invalid,))
-            self.assertEqual(dt.invalid(), result_invalid, "Failed invalid on: {} {} {}".format(month, result, result_invalid,))
-
-
-    def testOffsetMonth(self):
-
-        data_date = (
-            ("gregorian", 2012, 1, 2, False, 1, "20120202", False,),
-            ("gregorian", 2012, 1, 29, False, 1, "20120229", False,),
-            ("gregorian", 2012, 1, 31, False, 1, "20120229", False,),
-            ("gregorian", 2012, 2, 29, False, 1, "20120329", False,),
-        )
-
-        for rscale, y, m, d, l, month, result, result_invalid in data_date:
-            dt = ICUDateTime.fromDateComponents(rscale, y, m, d, l)
-            dt.offsetMonth(month)
-            self.assertEqual(dt.getText(), result, "Failed on: {} {} {}".format(month, result, result_invalid,))
-            self.assertEqual(dt.invalid(), result_invalid, "Failed invalid on: {} {} {}".format(month, result, result_invalid,))
-
-
-    def testSetDay(self):
-
-        data_date = (
-            ("gregorian", 2012, 2, 1, False, 2, "20120202", False,),
-            ("gregorian", 2012, 2, 1, False, 29, "20120229", False,),
-            ("gregorian", 2012, 2, 1, False, 31, "20120302", True,),
-        )
-
-        for rscale, y, m, d, l, day, result, result_invalid in data_date:
-            dt = ICUDateTime.fromDateComponents(rscale, y, m, d, l)
-            dt.setDay(day)
-            self.assertEqual(dt.getText(), result, "Failed on: {} {} {}".format(day, result, result_invalid,))
-            self.assertEqual(dt.invalid(), result_invalid, "Failed invalid on: {} {} {}".format(day, result, result_invalid,))
-
-
-    def testOffsetDay(self):
-
-        data_date = (
-            ("gregorian", 2012, 2, 1, False, 1, "20120202", False,),
-            ("gregorian", 2012, 2, 1, False, 28, "20120229", False,),
-            ("gregorian", 2012, 2, 1, False, 30, "20120302", False,),
-        )
-
-        for rscale, y, m, d, l, day, result, result_invalid in data_date:
-            dt = ICUDateTime.fromDateComponents(rscale, y, m, d, l)
-            dt.offsetDay(day)
-            self.assertEqual(dt.getText(), result, "Failed on: {} {} {}".format(day, result, result_invalid,))
-            self.assertEqual(dt.invalid(), result_invalid, "Failed invalid on: {} {} {}".format(day, result, result_invalid,))
-
-
-    def testYearDay(self):
-
-        data_date = (
-            ("gregorian", 2012, 1, 2, False, 1, False, "20120101", False,),
-            ("gregorian", 2012, 1, 2, False, 60, False, "20120229", False,),
-            ("gregorian", 2012, 1, 2, False, 366, False, "20121231", False,),
-            ("gregorian", 2012, 1, 2, False, 367, False, "20121231", False,),
-            ("gregorian", 2012, 1, 2, False, 367, True, "20121231", True,),
-            ("gregorian", 2012, 1, 2, False, -1, False, "20121231", False,),
-            ("gregorian", 2012, 1, 2, False, -307, False, "20120229", False,),
-            ("gregorian", 2012, 1, 2, False, -366, False, "20120101", False,),
-            ("gregorian", 2012, 1, 2, False, -367, False, "20120101", False,),
-            ("gregorian", 2012, 1, 2, False, -367, True, "20120101", True,),
-        )
-
-        for rscale, y, m, d, l, yearday, allow_invalid, result, result_invalid in data_date:
-            dt = ICUDateTime.fromDateComponents(rscale, y, m, d, l)
-            dt.setYearDay(yearday, allow_invalid=allow_invalid)
-            self.assertEqual(dt.getText(), result, "Failed on: {} {} {}".format(yearday, result, result_invalid,))
-            self.assertEqual(dt.invalid(), result_invalid, "Failed invalid on: {} {} {}".format(yearday, result, result_invalid,))
-
-
-    def testMonthDay(self):
-
-        data_date = (
-            ("gregorian", 2012, 1, 2, False, 1, False, "20120101", False,),
-            ("gregorian", 2012, 1, 31, False, 1, False, "20120101", False,),
-            ("gregorian", 2012, 2, 1, False, 31, False, "20120229", False,),
-            ("gregorian", 2012, 2, 1, False, 31, True, "20120229", True,),
-            ("gregorian", 2012, 1, 2, False, -1, False, "20120131", False,),
-            ("gregorian", 2012, 2, 29, False, -29, False, "20120201", False,),
-            ("gregorian", 2012, 2, 29, False, -30, False, "20120201", False,),
-            ("gregorian", 2012, 2, 29, False, -30, True, "20120201", True,),
-        )
-
-        for rscale, y, m, d, l, monthday, allow_invalid, result, result_invalid in data_date:
-            dt = ICUDateTime.fromDateComponents(rscale, y, m, d, l)
-            dt.setMonthDay(monthday, allow_invalid=allow_invalid)
-            self.assertEqual(dt.getText(), result, "Failed on: {} {} {}".format(monthday, result, result_invalid,))
-            self.assertEqual(dt.invalid(), result_invalid, "Failed invalid on: {} {} {}".format(monthday, result, result_invalid,))
-
-
-    def testWeekNum(self):
-
-        data_date = (
-            ("gregorian", 2012, 1, 3, False, 1, 2, "20120110",),
-            ("gregorian", 2014, 1, 3, False, 1, 2, "20140110",),
-            ("gregorian", 2012, 1, 1, False, 52, 2, "20120115",),
-        )
-
-        for rscale, y, m, d, l, start_weekno, weekno, result in data_date:
-            dt = ICUDateTime.fromDateComponents(rscale, y, m, d, l)
-            self.assertEqual(dt.getWeekNo(), start_weekno)
-            dt.setWeekNo(weekno)
-            self.assertTrue(dt.isWeekNo(weekno))
-            self.assertEqual(dt.getText(), result, "Failed on: {} {} vs {}".format(weekno, result, dt.getText(),))
-
-
-    def testDayOfWeekInYear(self):
-
-        data_date = (
-            ("gregorian", 2012, 1, 3, False, 1, DateTime.SUNDAY, "20120101",),
-            ("gregorian", 2012, 1, 3, False, 1, DateTime.MONDAY, "20120102",),
-            ("gregorian", 2012, 1, 3, False, 2, DateTime.SUNDAY, "20120108",),
-            ("gregorian", 2012, 1, 3, False, 10, DateTime.SUNDAY, "20120304",),
-            ("gregorian", 2012, 1, 3, False, -1, DateTime.SUNDAY, "20121230",),
-            ("gregorian", 2012, 1, 3, False, -45, DateTime.SUNDAY, "20120226",),
-        )
-
-        for rscale, y, m, d, l, offset, day, result in data_date:
-            dt = ICUDateTime.fromDateComponents(rscale, y, m, d, l)
-            dt.setDayOfWeekInYear(offset, day)
-            self.assertEqual(dt.getText(), result, "Failed on: {} vs {}".format(result, dt.getText(),))

Deleted: PyCalendar/trunk/src/pycalendar/icalendar/tests/test_recuriter.py
===================================================================
--- PyCalendar/trunk/src/pycalendar/icalendar/tests/test_recuriter.py	2014-12-01 16:26:51 UTC (rev 14192)
+++ PyCalendar/trunk/src/pycalendar/icalendar/tests/test_recuriter.py	2014-12-01 16:50:49 UTC (rev 14193)
@@ -1,559 +0,0 @@
-# coding: utf-8
-##
-#    Copyright (c) 2007-2013 Cyrus Daboo. All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License");
-#    you may not use this file except in compliance with the License.
-#    You may obtain a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS,
-#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#    See the License for the specific language governing permissions and
-#    limitations under the License.
-##
-
-from pycalendar.datetime import DateTime
-from pycalendar.icalendar import definitions
-from pycalendar.icalendar.icudatetime import ICUDateTime
-from pycalendar.icalendar.recuriter import RecurrenceIterator
-import unittest
-
-class MonthlySkips(object):
-
-    def testMonthlySkipYes(self):
-
-        riter = RecurrenceIterator(self.dt, definitions.eRecurrence_MONTHLY, 1, rscale=self.rscale, skip=definitions.eRecurrence_SKIP_YES)
-        results = [riter.next().getText() for _ in range(12)]
-        self.assertEqual(
-            results,
-            [
-                "20140131",
-                "20140331",
-                "20140531",
-                "20140731",
-                "20140831",
-                "20141031",
-                "20141231",
-                "20150131",
-                "20150331",
-                "20150531",
-                "20150731",
-                "20150831",
-            ]
-        )
-
-
-    def testMonthlySkipForward(self):
-
-        riter = RecurrenceIterator(self.dt, definitions.eRecurrence_MONTHLY, 1, rscale=self.rscale, skip=definitions.eRecurrence_SKIP_FORWARD)
-        results = [riter.next().getText() for _ in range(12)]
-        self.assertEqual(
-            results,
-            [
-                "20140131",
-                "20140301",
-                "20140331",
-                "20140501",
-                "20140531",
-                "20140701",
-                "20140731",
-                "20140831",
-                "20141001",
-                "20141031",
-                "20141201",
-                "20141231",
-            ]
-        )
-
-
-    def testMonthlySkipBackward(self):
-
-        riter = RecurrenceIterator(self.dt, definitions.eRecurrence_MONTHLY, 1, rscale=self.rscale, skip=definitions.eRecurrence_SKIP_BACKWARD)
-        results = [riter.next().getText() for _ in range(12)]
-        self.assertEqual(
-            results,
-            [
-                "20140131",
-                "20140228",
-                "20140331",
-                "20140430",
-                "20140531",
-                "20140630",
-                "20140731",
-                "20140831",
-                "20140930",
-                "20141031",
-                "20141130",
-                "20141231",
-            ]
-        )
-
-
-    def testMonthlySkipBackwardLeap(self):
-
-        riter = RecurrenceIterator(self.dtleap, definitions.eRecurrence_MONTHLY, 1, rscale=self.rscale, skip=definitions.eRecurrence_SKIP_BACKWARD)
-        results = [riter.next().getText() for _ in range(12)]
-        self.assertEqual(
-            results,
-            [
-                "20160131",
-                "20160229",
-                "20160331",
-                "20160430",
-                "20160531",
-                "20160630",
-                "20160731",
-                "20160831",
-                "20160930",
-                "20161031",
-                "20161130",
-                "20161231",
-            ]
-        )
-
-
-
-class TestMonthlyDateTime(unittest.TestCase, MonthlySkips):
-
-    def setUp(self):
-        self.dt = DateTime(2014, 1, 31)
-        self.dtleap = DateTime(2016, 1, 31)
-        self.rscale = None
-
-
-
-class TestMonthlyGregorianICU(unittest.TestCase, MonthlySkips):
-
-    def setUp(self):
-        self.dt = ICUDateTime.fromDateComponents("gregorian", 2014, 1, 31)
-        self.dtleap = ICUDateTime.fromDateComponents("gregorian", 2016, 1, 31)
-        self.rscale = None
-
-
-
-class YearlySkipsOnLeapDay(object):
-
-    def testYearlySkipYes(self):
-
-        riter = RecurrenceIterator(self.dt, definitions.eRecurrence_YEARLY, 1, rscale=self.rscale, skip=definitions.eRecurrence_SKIP_YES)
-        results = [riter.next().getText() for _ in range(5)]
-        self.assertEqual(
-            results,
-            [
-                "20160229",
-                "20200229",
-                "20240229",
-                "20280229",
-                "20320229",
-            ]
-        )
-
-
-    def testYearlySkipForward(self):
-
-        riter = RecurrenceIterator(self.dt, definitions.eRecurrence_YEARLY, 1, rscale=self.rscale, skip=definitions.eRecurrence_SKIP_FORWARD)
-        results = [riter.next().getText() for _ in range(5)]
-        self.assertEqual(
-            results,
-            [
-                "20160229",
-                "20170301",
-                "20180301",
-                "20190301",
-                "20200229",
-            ]
-        )
-
-
-    def testYearlySkipBackward(self):
-
-        riter = RecurrenceIterator(self.dt, definitions.eRecurrence_YEARLY, 1, rscale=self.rscale, skip=definitions.eRecurrence_SKIP_BACKWARD)
-        results = [riter.next().getText() for _ in range(5)]
-        self.assertEqual(
-            results,
-            [
-                "20160229",
-                "20170228",
-                "20180228",
-                "20190228",
-                "20200229",
-            ]
-        )
-
-
-
-class TestYearlyDateTime(unittest.TestCase, YearlySkipsOnLeapDay):
-
-    def setUp(self):
-        self.dt = DateTime(2016, 2, 29)
-        self.rscale = None
-
-
-
-class TestYearlyGregorianICU(unittest.TestCase, YearlySkipsOnLeapDay):
-
-    def setUp(self):
-        self.dt = ICUDateTime.fromDateComponents("gregorian", 2016, 2, 29)
-        self.rscale = None
-
-
-
-class TestMonthlyChineseICU(unittest.TestCase):
-
-    def testMonthlyStartInLeapYearSkipYes(self):
-        dt = ICUDateTime.fromDateComponents("chinese", 4650, 12, 30)
-
-        riter = RecurrenceIterator(dt, definitions.eRecurrence_MONTHLY, 1, rscale=None, skip=definitions.eRecurrence_SKIP_YES)
-        results = []
-        while True:
-            result = riter.next()
-            if result.getYear() >= 4655:
-                break
-            results.append(result.getText())
-        self.assertEqual(
-            results,
-            [
-                "{C}46501230",
-                "{C}46510230",
-                "{C}46510430",
-                "{C}46510630",
-                "{C}46510830",
-                "{C}46510930",
-                "{C}46511030",
-                "{C}46511230",
-                "{C}46520230",
-                "{C}46520530",
-                "{C}46520730",
-                "{C}46520830",
-                "{C}46520930",
-                "{C}46521130",
-                "{C}46530130",
-                "{C}46530330",
-                "{C}46530630",
-                "{C}46530830",
-                "{C}46530930",
-                "{C}46531130",
-                "{C}46531230",
-                "{C}46540230",
-                "{C}46540430",
-                "{C}465406L30",
-                "{C}46540830",
-                "{C}46541030",
-                "{C}46541130",
-                "{C}46541230",
-            ]
-        )
-
-
-    def testMonthlyStartInLeapYearSkipForward(self):
-        dt = ICUDateTime.fromDateComponents("chinese", 4650, 12, 30)
-
-        riter = RecurrenceIterator(dt, definitions.eRecurrence_MONTHLY, 1, rscale=None, skip=definitions.eRecurrence_SKIP_FORWARD)
-        results = []
-        while True:
-            result = riter.next()
-            if result.getYear() >= 4655:
-                break
-            results.append(result.getText())
-        self.assertEqual(
-            results,
-            [
-                "{C}46501230",
-                "{C}46510201",
-                "{C}46510230",
-                "{C}46510401",
-                "{C}46510430",
-                "{C}46510601",
-                "{C}46510630",
-                "{C}46510801",
-                "{C}46510830",
-                "{C}46510930",
-                "{C}46511001",
-                "{C}46511030",
-                "{C}46511201",
-                "{C}46511230",
-                "{C}46520201",
-                "{C}46520230",
-                "{C}46520401",
-                "{C}46520501",
-                "{C}46520530",
-                "{C}46520701",
-                "{C}46520730",
-                "{C}46520830",
-                "{C}46520930",
-                "{C}46521101",
-                "{C}46521130",
-                "{C}46530101",
-                "{C}46530130",
-                "{C}46530301",
-                "{C}46530330",
-                "{C}46530501",
-                "{C}46530601",
-                "{C}46530630",
-                "{C}46530801",
-                "{C}46530830",
-                "{C}46530930",
-                "{C}46531101",
-                "{C}46531130",
-                "{C}46531230",
-                "{C}46540201",
-                "{C}46540230",
-                "{C}46540401",
-                "{C}46540430",
-                "{C}46540601",
-                "{C}465406L01",
-                "{C}465406L30",
-                "{C}46540801",
-                "{C}46540830",
-                "{C}46541001",
-                "{C}46541030",
-                "{C}46541130",
-                "{C}46541230",
-            ]
-        )
-
-
-    def testMonthlyStartInLeapYearSkipBackward(self):
-        dt = ICUDateTime.fromDateComponents("chinese", 4650, 12, 30)
-
-        riter = RecurrenceIterator(dt, definitions.eRecurrence_MONTHLY, 1, rscale=None, skip=definitions.eRecurrence_SKIP_BACKWARD)
-        results = []
-        while True:
-            result = riter.next()
-            if result.getYear() >= 4655:
-                break
-            results.append(result.getText())
-        self.assertEqual(
-            results,
-            [
-                "{C}46501230",
-                "{C}46510129",
-                "{C}46510230",
-                "{C}46510329",
-                "{C}46510430",
-                "{C}46510529",
-                "{C}46510630",
-                "{C}46510729",
-                "{C}46510830",
-                "{C}46510930",
-                "{C}465109L29",
-                "{C}46511030",
-                "{C}46511129",
-                "{C}46511230",
-                "{C}46520129",
-                "{C}46520230",
-                "{C}46520329",
-                "{C}46520429",
-                "{C}46520530",
-                "{C}46520629",
-                "{C}46520730",
-                "{C}46520830",
-                "{C}46520930",
-                "{C}46521029",
-                "{C}46521130",
-                "{C}46521229",
-                "{C}46530130",
-                "{C}46530229",
-                "{C}46530330",
-                "{C}46530429",
-                "{C}46530529",
-                "{C}46530630",
-                "{C}46530729",
-                "{C}46530830",
-                "{C}46530930",
-                "{C}46531029",
-                "{C}46531130",
-                "{C}46531230",
-                "{C}46540129",
-                "{C}46540230",
-                "{C}46540329",
-                "{C}46540430",
-                "{C}46540529",
-                "{C}46540629",
-                "{C}465406L30",
-                "{C}46540729",
-                "{C}46540830",
-                "{C}46540929",
-                "{C}46541030",
-                "{C}46541130",
-                "{C}46541230",
-            ]
-        )
-
-
-    def testMonthlyRscaleStartInLeapYearSkipYes(self):
-        dt = ICUDateTime.fromDateComponents("chinese", 4650, 12, 30).toDateTime()
-
-        riter = RecurrenceIterator(dt, definitions.eRecurrence_MONTHLY, 1, rscale="chinese", skip=definitions.eRecurrence_SKIP_YES)
-        results = []
-        while True:
-            result = riter.next()
-            if result.getYear() >= 2018:
-                break
-            results.append(result.getText())
-        self.assertEqual(
-            results,
-            [
-                "20140130",
-                "20140330",
-                "20140528",
-                "20140726",
-                "20140923",
-                "20141023",
-                "20141221",
-                "20150218",
-                "20150418",
-                "20150715",
-                "20150912",
-                "20151012",
-                "20151111",
-                "20160109",
-                "20160308",
-                "20160506",
-                "20160802",
-                "20160930",
-                "20161030",
-                "20161228",
-                "20170127",
-                "20170327",
-                "20170525",
-                "20170821",
-                "20171019",
-                "20171217",
-            ]
-        )
-
-
-    def testMonthlyRscaleStartInLeapYearSkipForward(self):
-        dt = ICUDateTime.fromDateComponents("chinese", 4650, 12, 30).toDateTime()
-
-        riter = RecurrenceIterator(dt, definitions.eRecurrence_MONTHLY, 1, rscale="chinese", skip=definitions.eRecurrence_SKIP_FORWARD)
-        results = []
-        while True:
-            result = riter.next()
-            if result.getYear() >= 2018:
-                break
-            results.append(result.getText())
-        self.assertEqual(
-            results,
-            [
-                "20140130",
-                "20140301",
-                "20140330",
-                "20140429",
-                "20140528",
-                "20140627",
-                "20140726",
-                "20140825",
-                "20140923",
-                "20141023",
-                "20141122",
-                "20141221",
-                "20150120",
-                "20150218",
-                "20150320",
-                "20150418",
-                "20150518",
-                "20150616",
-                "20150715",
-                "20150814",
-                "20150912",
-                "20151012",
-                "20151111",
-                "20151211",
-                "20160109",
-                "20160208",
-                "20160308",
-                "20160407",
-                "20160506",
-                "20160605",
-                "20160704",
-                "20160802",
-                "20160901",
-                "20160930",
-                "20161030",
-                "20161129",
-                "20161228",
-                "20170127",
-                "20170226",
-                "20170327",
-                "20170426",
-                "20170525",
-                "20170624",
-                "20170723",
-                "20170821",
-                "20170920",
-                "20171019",
-                "20171118",
-                "20171217",
-            ]
-        )
-
-
-    def testMonthlyRscaleStartInLeapYearSkipBackward(self):
-        dt = ICUDateTime.fromDateComponents("chinese", 4650, 12, 30).toDateTime()
-
-        riter = RecurrenceIterator(dt, definitions.eRecurrence_MONTHLY, 1, rscale="chinese", skip=definitions.eRecurrence_SKIP_BACKWARD)
-        results = []
-        while True:
-            result = riter.next()
-            if result.getYear() >= 2018:
-                break
-            results.append(result.getText())
-        self.assertEqual(
-            results,
-            [
-                "20140130",
-                "20140228",
-                "20140330",
-                "20140428",
-                "20140528",
-                "20140626",
-                "20140726",
-                "20140824",
-                "20140923",
-                "20141023",
-                "20141121",
-                "20141221",
-                "20150119",
-                "20150218",
-                "20150319",
-                "20150418",
-                "20150517",
-                "20150615",
-                "20150715",
-                "20150813",
-                "20150912",
-                "20151012",
-                "20151111",
-                "20151210",
-                "20160109",
-                "20160207",
-                "20160308",
-                "20160406",
-                "20160506",
-                "20160604",
-                "20160703",
-                "20160802",
-                "20160831",
-                "20160930",
-                "20161030",
-                "20161128",
-                "20161228",
-                "20170127",
-                "20170225",
-                "20170327",
-                "20170425",
-                "20170525",
-                "20170623",
-                "20170722",
-                "20170821",
-                "20170919",
-                "20171019",
-                "20171117",
-                "20171217",
-            ]
-        )

Modified: PyCalendar/trunk/src/pycalendar/icalendar/tests/test_recurrence.py
===================================================================
--- PyCalendar/trunk/src/pycalendar/icalendar/tests/test_recurrence.py	2014-12-01 16:26:51 UTC (rev 14192)
+++ PyCalendar/trunk/src/pycalendar/icalendar/tests/test_recurrence.py	2014-12-01 16:50:49 UTC (rev 14193)
@@ -51,14 +51,6 @@
         "FREQ=YEARLY;BYDAY=MO;BYWEEKNO=20",
         "FREQ=MONTHLY;COUNT=3;BYDAY=TU,WE,TH;BYSETPOS=3",
         "FREQ=DAILY;BYMINUTE=0,20,40;BYHOUR=9,10,11,12,13,14,15,16",
-
-        # RSCALE
-        "RSCALE=CHINESE;FREQ=DAILY",
-        "RSCALE=GREGORIAN;FREQ=YEARLY;COUNT=400;SKIP=YES",
-        "RSCALE=GREGORIAN;FREQ=YEARLY;COUNT=400;SKIP=BACKWARD",
-        "RSCALE=GREGORIAN;FREQ=YEARLY;COUNT=400;SKIP=FORWARD",
-        "RSCALE=CHINESE;FREQ=YEARLY;BYMONTH=5,6,6L,7",
-
     )
 
 
@@ -67,7 +59,7 @@
         for item in TestRecurrence.items:
             recur = Recurrence()
             recur.parse(item)
-            self.assertEqual(recur.getText(), item, "Failed to parse and re-generate '%s' '%s'" % (item, recur.getText()))
+            self.assertEqual(recur.getText(), item, "Failed to parse and re-generate '%s'" % (item,))
 
 
     def testParseInvalid(self):
@@ -86,8 +78,6 @@
             "FREQ=MONTHLY;BYDAY=+1,3MO",
             "FREQ=MONTHLY;BYHOUR=A",
             "FREQ=MONTHLY;BYHOUR=54",
-            "FREQ=MONTHLY;SKIP=YES",
-            "RSCALE=CHINESE;FREQ=MONTHLY;SKIP=NO",
         )
 
         for item in items:
@@ -128,618 +118,153 @@
 
     def testByWeekNoExpand(self):
 
-        rule = "FREQ=YEARLY;BYWEEKNO=1,2"
-        for rrule in (
-            rule,
-            "RSCALE=GREGORIAN;{};SKIP=YES".format(rule)
-        ):
-            recur = Recurrence()
-            recur.parse(rrule)
-            start = DateTime(2013, 1, 1, 0, 0, 0)
-            end = DateTime(2017, 1, 1, 0, 0, 0)
-            items = []
-            range = Period(start, end)
-            recur.expand(start, range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2013, 1, 1, 0, 0, 0),
-                    DateTime(2013, 1, 8, 0, 0, 0),
-                    DateTime(2014, 1, 1, 0, 0, 0),
-                    DateTime(2014, 1, 8, 0, 0, 0),
-                    DateTime(2015, 1, 1, 0, 0, 0),
-                    DateTime(2015, 1, 8, 0, 0, 0),
-                    DateTime(2016, 1, 8, 0, 0, 0),
-                    DateTime(2016, 1, 15, 0, 0, 0),
-                ],
-                msg="Failed: {}".format(rrule),
-            )
-
-
-    def testMonthlyInvalidStart(self):
-
-        rule = "FREQ=MONTHLY"
-        for rrule in (
-            rule,
-            "RSCALE=GREGORIAN;{};SKIP=YES".format(rule)
-        ):
-            recur = Recurrence()
-            recur.parse(rrule)
-            start = DateTime(2014, 1, 40, 12, 0, 0)
-            end = DateTime(2015, 1, 1, 0, 0, 0)
-            items = []
-            range = Period(start, end)
-            recur.expand(start, range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2014, 2, 9, 12, 0, 0),
-                    DateTime(2014, 3, 9, 12, 0, 0),
-                    DateTime(2014, 4, 9, 12, 0, 0),
-                    DateTime(2014, 5, 9, 12, 0, 0),
-                    DateTime(2014, 6, 9, 12, 0, 0),
-                    DateTime(2014, 7, 9, 12, 0, 0),
-                    DateTime(2014, 8, 9, 12, 0, 0),
-                    DateTime(2014, 9, 9, 12, 0, 0),
-                    DateTime(2014, 10, 9, 12, 0, 0),
-                    DateTime(2014, 11, 9, 12, 0, 0),
-                    DateTime(2014, 12, 9, 12, 0, 0),
-                ],
-                msg="Failed: {}".format(rrule),
-            )
-
-
-    def testWeeklyTwice(self):
-
-        rule = "FREQ=WEEKLY"
-        for rrule in (
-            rule,
-            "RSCALE=GREGORIAN;{};SKIP=YES".format(rule)
-        ):
-            recur = Recurrence()
-            recur.parse(rrule)
-            start = DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(utc=True))
-            end = DateTime(2014, 2, 1, 0, 0, 0, tzid=Timezone(utc=True))
-            items = []
-            range = Period(start, end)
-            recur.expand(DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")), range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 1, 8, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 1, 15, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 1, 22, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 1, 29, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-
-                ],
-                msg="Failed: {}".format(rrule),
-            )
-
-            start = DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(utc=True))
-            end = DateTime(2014, 3, 1, 0, 0, 0, tzid=Timezone(utc=True))
-            items = []
-            range = Period(start, end)
-            recur.expand(DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")), range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 1, 8, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 1, 15, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 1, 22, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 1, 29, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 2, 5, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 2, 12, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 2, 19, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 2, 26, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                ],
-                msg="Failed: {}".format(rrule),
-            )
-
-
-    def testMonthlyInUTC(self):
-
-        rule = "FREQ=MONTHLY"
-        for rrule in (
-            rule,
-            "RSCALE=GREGORIAN;{};SKIP=YES".format(rule)
-        ):
-            recur = Recurrence()
-            recur.parse(rrule)
-            start = DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(utc=True))
-            end = DateTime(2015, 1, 1, 0, 0, 0, tzid=Timezone(utc=True))
-            items = []
-            range = Period(start, end)
-            recur.expand(DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")), range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 2, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 3, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 4, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 5, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 6, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 7, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 8, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 9, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
-                    DateTime(2014, 10, 1, 12, 0, 0),
-                    DateTime(2014, 11, 1, 12, 0, 0),
-                    DateTime(2014, 12, 1, 12, 0, 0),
-                ],
-                msg="Failed: {}".format(rrule),
-            )
-
-
-    def testMonthlyStart31st(self):
-
-        rule = "FREQ=MONTHLY"
-        for rrule in (
-            rule,
-            "RSCALE=GREGORIAN;{};SKIP=YES".format(rule)
-        ):
-            recur = Recurrence()
-            recur.parse(rrule)
-            start = DateTime(2014, 1, 31, 12, 0, 0)
-            end = DateTime(2015, 1, 1, 0, 0, 0)
-            items = []
-            range = Period(start, end)
-            recur.expand(start, range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2014, 1, 31, 12, 0, 0),
-                    DateTime(2014, 3, 31, 12, 0, 0),
-                    DateTime(2014, 5, 31, 12, 0, 0),
-                    DateTime(2014, 7, 31, 12, 0, 0),
-                    DateTime(2014, 8, 31, 12, 0, 0),
-                    DateTime(2014, 10, 31, 12, 0, 0),
-                    DateTime(2014, 12, 31, 12, 0, 0),
-                ],
-                msg="Failed: {}".format(rrule),
-            )
-
-
-    def testMonthlyByMonthDay31(self):
-
-        rule = "FREQ=MONTHLY;BYMONTHDAY=31"
-        for rrule in (
-            rule,
-            "RSCALE=GREGORIAN;{};SKIP=YES".format(rule)
-        ):
-            recur = Recurrence()
-            recur.parse(rrule)
-            start = DateTime(2014, 1, 31, 12, 0, 0)
-            end = DateTime(2015, 1, 1, 0, 0, 0)
-            items = []
-            range = Period(start, end)
-            recur.expand(start, range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2014, 1, 31, 12, 0, 0),
-                    DateTime(2014, 3, 31, 12, 0, 0),
-                    DateTime(2014, 5, 31, 12, 0, 0),
-                    DateTime(2014, 7, 31, 12, 0, 0),
-                    DateTime(2014, 8, 31, 12, 0, 0),
-                    DateTime(2014, 10, 31, 12, 0, 0),
-                    DateTime(2014, 12, 31, 12, 0, 0),
-                ],
-                msg="Failed: {}".format(rrule),
-            )
-
-
-    def testMonthlyByMonthDayMinus31(self):
-
-        rule = "FREQ=MONTHLY;BYMONTHDAY=-31"
-        for rrule in (
-            rule,
-            "RSCALE=GREGORIAN;{};SKIP=YES".format(rule)
-        ):
-            recur = Recurrence()
-            recur.parse(rrule)
-            start = DateTime(2014, 1, 1, 12, 0, 0)
-            end = DateTime(2015, 1, 1, 0, 0, 0)
-            items = []
-            range = Period(start, end)
-            recur.expand(start, range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2014, 1, 1, 12, 0, 0),
-                    DateTime(2014, 3, 1, 12, 0, 0),
-                    DateTime(2014, 5, 1, 12, 0, 0),
-                    DateTime(2014, 7, 1, 12, 0, 0),
-                    DateTime(2014, 8, 1, 12, 0, 0),
-                    DateTime(2014, 10, 1, 12, 0, 0),
-                    DateTime(2014, 12, 1, 12, 0, 0),
-                ],
-                msg="Failed: {}".format(rrule),
-            )
-
-
-    def testMonthlyByLastFridayExpand(self):
-
-        rule = "FREQ=MONTHLY;BYDAY=-1FR"
-        for rrule in (
-            rule,
-            "RSCALE=GREGORIAN;{};SKIP=YES".format(rule)
-        ):
-            recur = Recurrence()
-            recur.parse(rrule)
-            start = DateTime(2014, 1, 31, 12, 0, 0)
-            end = DateTime(2015, 1, 1, 0, 0, 0)
-            items = []
-            range = Period(start, end)
-            recur.expand(start, range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2014, 1, 31, 12, 0, 0),
-                    DateTime(2014, 2, 28, 12, 0, 0),
-                    DateTime(2014, 3, 28, 12, 0, 0),
-                    DateTime(2014, 4, 25, 12, 0, 0),
-                    DateTime(2014, 5, 30, 12, 0, 0),
-                    DateTime(2014, 6, 27, 12, 0, 0),
-                    DateTime(2014, 7, 25, 12, 0, 0),
-                    DateTime(2014, 8, 29, 12, 0, 0),
-                    DateTime(2014, 9, 26, 12, 0, 0),
-                    DateTime(2014, 10, 31, 12, 0, 0),
-                    DateTime(2014, 11, 28, 12, 0, 0),
-                    DateTime(2014, 12, 26, 12, 0, 0),
-                ],
-                msg="Failed: {}".format(rrule),
-            )
-
-
-    def testMonthlyByFifthFridayExpand(self):
-
-        rule = "FREQ=MONTHLY;BYDAY=5FR"
-        for rrule in (
-            rule,
-            "RSCALE=GREGORIAN;{};SKIP=YES".format(rule)
-        ):
-            recur = Recurrence()
-            recur.parse(rrule)
-            start = DateTime(2014, 1, 31, 12, 0, 0)
-            end = DateTime(2015, 1, 1, 0, 0, 0)
-            items = []
-            range = Period(start, end)
-            recur.expand(start, range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2014, 1, 31, 12, 0, 0),
-                    DateTime(2014, 5, 30, 12, 0, 0),
-                    DateTime(2014, 8, 29, 12, 0, 0),
-                    DateTime(2014, 10, 31, 12, 0, 0),
-                ],
-                msg="Failed: {}".format(rrule),
-            )
-
-
-    def testYearlyLeapDay(self):
-
-        rule = "FREQ=YEARLY"
-        for rrule in (
-            rule,
-            "RSCALE=GREGORIAN;{};SKIP=YES".format(rule)
-        ):
-            recur = Recurrence()
-            recur.parse(rrule)
-            start = DateTime(2012, 2, 29, 12, 0, 0)
-            end = DateTime(2020, 1, 1, 0, 0, 0)
-            items = []
-            range = Period(start, end)
-            recur.expand(start, range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2012, 2, 29, 12, 0, 0),
-                    DateTime(2016, 2, 29, 12, 0, 0),
-                ],
-                msg="Failed: {}".format(rrule),
-            )
-
-
-    def testYearlyYearDay(self):
-
-        rule = "FREQ=YEARLY;BYYEARDAY=366"
-        for rrule in (
-            rule,
-            "RSCALE=GREGORIAN;{};SKIP=YES".format(rule)
-        ):
-            recur = Recurrence()
-            recur.parse(rrule)
-            start = DateTime(2012, 12, 31, 12, 0, 0)
-            end = DateTime(2020, 1, 1, 0, 0, 0)
-            items = []
-            range = Period(start, end)
-            recur.expand(start, range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2012, 12, 31, 12, 0, 0),
-                    DateTime(2016, 12, 31, 12, 0, 0),
-                ],
-                msg="Failed: {}".format(rrule),
-            )
-
-
-    def testClearOnChange(self):
-
         recur = Recurrence()
-        recur.parse("FREQ=DAILY")
-
+        recur.parse("FREQ=YEARLY;BYWEEKNO=1,2")
         start = DateTime(2013, 1, 1, 0, 0, 0)
         end = DateTime(2017, 1, 1, 0, 0, 0)
-        range = Period(start, end)
         items = []
+        range = Period(start, end)
         recur.expand(start, range, items)
-        self.assertTrue(recur.mCached)
-        self.assertTrue(len(items) > 100)
+        self.assertEqual(
+            items,
+            [
+                DateTime(2013, 1, 1, 0, 0, 0),
+                DateTime(2013, 1, 8, 0, 0, 0),
+                DateTime(2014, 1, 1, 0, 0, 0),
+                DateTime(2014, 1, 8, 0, 0, 0),
+                DateTime(2015, 1, 1, 0, 0, 0),
+                DateTime(2015, 1, 8, 0, 0, 0),
+                DateTime(2016, 1, 8, 0, 0, 0),
+                DateTime(2016, 1, 15, 0, 0, 0),
+            ],
+        )
 
-        recur.setUseCount(True)
-        recur.setCount(10)
-        self.assertFalse(recur.mCached)
-        items = []
-        recur.expand(start, range, items)
-        self.assertEqual(len(items), 10)
 
+    def testMonthlyInvalidStart(self):
 
-
-class TestRecurrenceRscale(unittest.TestCase):
-
-    def testMonthlyRscaleStartInLeapYearSkipYes(self):
-
         recur = Recurrence()
-        recur.parse("RSCALE=CHINESE;FREQ=MONTHLY;SKIP=YES")
-        start = DateTime(2014, 1, 30) # {C}46501230
-        end = DateTime(2018, 1, 1)
+        recur.parse("FREQ=MONTHLY")
+        start = DateTime(2014, 1, 40, 12, 0, 0)
+        end = DateTime(2015, 1, 1, 0, 0, 0)
         items = []
         range = Period(start, end)
         recur.expand(start, range, items)
         self.assertEqual(
             items,
             [
-                DateTime(2014, 1, 30),
-                DateTime(2014, 3, 30),
-                DateTime(2014, 5, 28),
-                DateTime(2014, 7, 26),
-                DateTime(2014, 9, 23),
-                DateTime(2014, 10, 23),
-                DateTime(2014, 12, 21),
-                DateTime(2015, 2, 18),
-                DateTime(2015, 4, 18),
-                DateTime(2015, 7, 15),
-                DateTime(2015, 9, 12),
-                DateTime(2015, 10, 12),
-                DateTime(2015, 11, 11),
-                DateTime(2016, 1, 9),
-                DateTime(2016, 3, 8),
-                DateTime(2016, 5, 6),
-                DateTime(2016, 8, 2),
-                DateTime(2016, 9, 30),
-                DateTime(2016, 10, 30),
-                DateTime(2016, 12, 28),
-                DateTime(2017, 1, 27),
-                DateTime(2017, 3, 27),
-                DateTime(2017, 5, 25),
-                DateTime(2017, 8, 21),
-                DateTime(2017, 10, 19),
-                DateTime(2017, 12, 17),
+                DateTime(2014, 2, 9, 12, 0, 0),
+                DateTime(2014, 3, 9, 12, 0, 0),
+                DateTime(2014, 4, 9, 12, 0, 0),
+                DateTime(2014, 5, 9, 12, 0, 0),
+                DateTime(2014, 6, 9, 12, 0, 0),
+                DateTime(2014, 7, 9, 12, 0, 0),
+                DateTime(2014, 8, 9, 12, 0, 0),
+                DateTime(2014, 9, 9, 12, 0, 0),
+                DateTime(2014, 10, 9, 12, 0, 0),
+                DateTime(2014, 11, 9, 12, 0, 0),
+                DateTime(2014, 12, 9, 12, 0, 0),
             ],
         )
 
 
-    def testMonthlyRscaleStartInLeapYearSkipForward(self):
+    def testWeeklyTwice(self):
 
         recur = Recurrence()
-        recur.parse("RSCALE=CHINESE;FREQ=MONTHLY;SKIP=FORWARD")
-        start = DateTime(2014, 1, 30) # {C}46501230
-        end = DateTime(2018, 1, 1)
+        recur.parse("FREQ=WEEKLY")
+        start = DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(utc=True))
+        end = DateTime(2014, 2, 1, 0, 0, 0, tzid=Timezone(utc=True))
         items = []
         range = Period(start, end)
-        recur.expand(start, range, items)
+        recur.expand(DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")), range, items)
         self.assertEqual(
             items,
             [
-                DateTime(2014, 1, 30),
-                DateTime(2014, 3, 1),
-                DateTime(2014, 3, 30),
-                DateTime(2014, 4, 29),
-                DateTime(2014, 5, 28),
-                DateTime(2014, 6, 27),
-                DateTime(2014, 7, 26),
-                DateTime(2014, 8, 25),
-                DateTime(2014, 9, 23),
-                DateTime(2014, 10, 23),
-                DateTime(2014, 11, 22),
-                DateTime(2014, 12, 21),
-                DateTime(2015, 1, 20),
-                DateTime(2015, 2, 18),
-                DateTime(2015, 3, 20),
-                DateTime(2015, 4, 18),
-                DateTime(2015, 5, 18),
-                DateTime(2015, 6, 16),
-                DateTime(2015, 7, 15),
-                DateTime(2015, 8, 14),
-                DateTime(2015, 9, 12),
-                DateTime(2015, 10, 12),
-                DateTime(2015, 11, 11),
-                DateTime(2015, 12, 11),
-                DateTime(2016, 1, 9),
-                DateTime(2016, 2, 8),
-                DateTime(2016, 3, 8),
-                DateTime(2016, 4, 7),
-                DateTime(2016, 5, 6),
-                DateTime(2016, 6, 5),
-                DateTime(2016, 7, 4),
-                DateTime(2016, 8, 2),
-                DateTime(2016, 9, 1),
-                DateTime(2016, 9, 30),
-                DateTime(2016, 10, 30),
-                DateTime(2016, 11, 29),
-                DateTime(2016, 12, 28),
-                DateTime(2017, 1, 27),
-                DateTime(2017, 2, 26),
-                DateTime(2017, 3, 27),
-                DateTime(2017, 4, 26),
-                DateTime(2017, 5, 25),
-                DateTime(2017, 6, 24),
-                DateTime(2017, 7, 23),
-                DateTime(2017, 8, 21),
-                DateTime(2017, 9, 20),
-                DateTime(2017, 10, 19),
-                DateTime(2017, 11, 18),
-                DateTime(2017, 12, 17),
+                DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 1, 8, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 1, 15, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 1, 22, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 1, 29, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+
             ],
         )
 
+        start = DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(utc=True))
+        end = DateTime(2014, 3, 1, 0, 0, 0, tzid=Timezone(utc=True))
+        items = []
+        range = Period(start, end)
+        recur.expand(DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")), range, items)
+        self.assertEqual(
+            items,
+            [
+                DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 1, 8, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 1, 15, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 1, 22, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 1, 29, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 2, 5, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 2, 12, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 2, 19, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 2, 26, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+            ],
+        )
 
-    def testMonthlyRscaleStartInLeapYearSkipBackwardDefault(self):
 
-        for rrule in (
-            "RSCALE=CHINESE;FREQ=MONTHLY;SKIP=BACKWARD",
-            "RSCALE=CHINESE;FREQ=MONTHLY"
-        ):
-            recur = Recurrence()
-            recur.parse(rrule)
-            start = DateTime(2014, 1, 30) # {C}46501230
-            end = DateTime(2018, 1, 1)
-            items = []
-            range = Period(start, end)
-            recur.expand(start, range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2014, 1, 30),
-                    DateTime(2014, 2, 28),
-                    DateTime(2014, 3, 30),
-                    DateTime(2014, 4, 28),
-                    DateTime(2014, 5, 28),
-                    DateTime(2014, 6, 26),
-                    DateTime(2014, 7, 26),
-                    DateTime(2014, 8, 24),
-                    DateTime(2014, 9, 23),
-                    DateTime(2014, 10, 23),
-                    DateTime(2014, 11, 21),
-                    DateTime(2014, 12, 21),
-                    DateTime(2015, 1, 19),
-                    DateTime(2015, 2, 18),
-                    DateTime(2015, 3, 19),
-                    DateTime(2015, 4, 18),
-                    DateTime(2015, 5, 17),
-                    DateTime(2015, 6, 15),
-                    DateTime(2015, 7, 15),
-                    DateTime(2015, 8, 13),
-                    DateTime(2015, 9, 12),
-                    DateTime(2015, 10, 12),
-                    DateTime(2015, 11, 11),
-                    DateTime(2015, 12, 10),
-                    DateTime(2016, 1, 9),
-                    DateTime(2016, 2, 7),
-                    DateTime(2016, 3, 8),
-                    DateTime(2016, 4, 6),
-                    DateTime(2016, 5, 6),
-                    DateTime(2016, 6, 4),
-                    DateTime(2016, 7, 3),
-                    DateTime(2016, 8, 2),
-                    DateTime(2016, 8, 31),
-                    DateTime(2016, 9, 30),
-                    DateTime(2016, 10, 30),
-                    DateTime(2016, 11, 28),
-                    DateTime(2016, 12, 28),
-                    DateTime(2017, 1, 27),
-                    DateTime(2017, 2, 25),
-                    DateTime(2017, 3, 27),
-                    DateTime(2017, 4, 25),
-                    DateTime(2017, 5, 25),
-                    DateTime(2017, 6, 23),
-                    DateTime(2017, 7, 22),
-                    DateTime(2017, 8, 21),
-                    DateTime(2017, 9, 19),
-                    DateTime(2017, 10, 19),
-                    DateTime(2017, 11, 17),
-                    DateTime(2017, 12, 17),
-                ],
-            )
+    def testMonthlyInUTC(self):
 
-
-    def testYearlyLeapDaySkipYes(self):
-
         recur = Recurrence()
-        recur.parse("RSCALE=GREGORIAN;FREQ=YEARLY;SKIP=YES;COUNT=5")
-        start = DateTime(2016, 2, 29)
-        end = DateTime(2100, 1, 1)
+        recur.parse("FREQ=MONTHLY")
+        start = DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(utc=True))
+        end = DateTime(2015, 1, 1, 0, 0, 0, tzid=Timezone(utc=True))
         items = []
         range = Period(start, end)
-        recur.expand(start, range, items)
+        recur.expand(DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")), range, items)
         self.assertEqual(
             items,
             [
-                DateTime(2016, 2, 29),
-                DateTime(2020, 2, 29),
-                DateTime(2024, 2, 29),
-                DateTime(2028, 2, 29),
-                DateTime(2032, 2, 29),
-            ]
+                DateTime(2014, 1, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 2, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 3, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 4, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 5, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 6, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 7, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 8, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 9, 1, 12, 0, 0, tzid=Timezone(tzid="America/New_York")),
+                DateTime(2014, 10, 1, 12, 0, 0),
+                DateTime(2014, 11, 1, 12, 0, 0),
+                DateTime(2014, 12, 1, 12, 0, 0),
+            ],
         )
 
 
-    def testYearlyLeapDaySkipForward(self):
+    def testMonthlyStart31st(self):
 
         recur = Recurrence()
-        recur.parse("RSCALE=GREGORIAN;FREQ=YEARLY;SKIP=FORWARD;COUNT=5")
-        start = DateTime(2016, 2, 29)
-        end = DateTime(2100, 1, 1)
+        recur.parse("FREQ=MONTHLY")
+        start = DateTime(2014, 1, 31, 12, 0, 0)
+        end = DateTime(2015, 1, 1, 0, 0, 0)
         items = []
         range = Period(start, end)
         recur.expand(start, range, items)
         self.assertEqual(
             items,
             [
-                DateTime(2016, 2, 29),
-                DateTime(2017, 3, 1),
-                DateTime(2018, 3, 1),
-                DateTime(2019, 3, 1),
-                DateTime(2020, 2, 29),
-            ]
+                DateTime(2014, 1, 31, 12, 0, 0),
+                DateTime(2014, 3, 31, 12, 0, 0),
+                DateTime(2014, 5, 31, 12, 0, 0),
+                DateTime(2014, 7, 31, 12, 0, 0),
+                DateTime(2014, 8, 31, 12, 0, 0),
+                DateTime(2014, 10, 31, 12, 0, 0),
+                DateTime(2014, 12, 31, 12, 0, 0),
+            ],
         )
 
 
-    def testYearlyLeapDaySkipBackwardDefault(self):
+    def testMonthlyByMonthDay31(self):
 
-        for rrule in (
-            "RSCALE=GREGORIAN;FREQ=YEARLY;SKIP=BACKWARD;COUNT=5",
-            "RSCALE=GREGORIAN;FREQ=YEARLY;COUNT=5",
-        ):
-            recur = Recurrence()
-            recur.parse(rrule)
-            start = DateTime(2016, 2, 29)
-            end = DateTime(2100, 1, 1)
-            items = []
-            range = Period(start, end)
-            recur.expand(start, range, items)
-            self.assertEqual(
-                items,
-                [
-                    DateTime(2016, 2, 29),
-                    DateTime(2017, 2, 28),
-                    DateTime(2018, 2, 28),
-                    DateTime(2019, 2, 28),
-                    DateTime(2020, 2, 29),
-                ]
-            )
-
-
-    def testChineseMonthlyByMonthDay30SkipYes(self):
-
-        rrule = "RSCALE=CHINESE;FREQ=MONTHLY;BYMONTHDAY=30;SKIP=YES"
         recur = Recurrence()
-        recur.parse(rrule)
-        start = DateTime(2014, 1, 30, 12, 0, 0)
+        recur.parse("FREQ=MONTHLY;BYMONTHDAY=31")
+        start = DateTime(2014, 1, 31, 12, 0, 0)
         end = DateTime(2015, 1, 1, 0, 0, 0)
         items = []
         range = Period(start, end)
@@ -747,24 +272,22 @@
         self.assertEqual(
             items,
             [
-                DateTime(2014, 1, 30, 12, 0, 0),
-                DateTime(2014, 3, 30, 12, 0, 0),
-                DateTime(2014, 5, 28, 12, 0, 0),
-                DateTime(2014, 7, 26, 12, 0, 0),
-                DateTime(2014, 9, 23, 12, 0, 0),
-                DateTime(2014, 10, 23, 12, 0, 0),
-                DateTime(2014, 12, 21, 12, 0, 0),
+                DateTime(2014, 1, 31, 12, 0, 0),
+                DateTime(2014, 3, 31, 12, 0, 0),
+                DateTime(2014, 5, 31, 12, 0, 0),
+                DateTime(2014, 7, 31, 12, 0, 0),
+                DateTime(2014, 8, 31, 12, 0, 0),
+                DateTime(2014, 10, 31, 12, 0, 0),
+                DateTime(2014, 12, 31, 12, 0, 0),
             ],
-            msg="Failed: {} {}".format(rrule, items,),
         )
 
 
-    def testChineseMonthlyByMonthDay30SkipBackward(self):
+    def testMonthlyByMonthDayMinus31(self):
 
-        rrule = "RSCALE=CHINESE;FREQ=MONTHLY;BYMONTHDAY=30;SKIP=BACKWARD"
         recur = Recurrence()
-        recur.parse(rrule)
-        start = DateTime(2014, 1, 30, 12, 0, 0)
+        recur.parse("FREQ=MONTHLY;BYMONTHDAY=-31")
+        start = DateTime(2014, 1, 1, 12, 0, 0)
         end = DateTime(2015, 1, 1, 0, 0, 0)
         items = []
         range = Period(start, end)
@@ -772,29 +295,22 @@
         self.assertEqual(
             items,
             [
-                DateTime(2014, 1, 30, 12, 0, 0),
-                DateTime(2014, 2, 28, 12, 0, 0),
-                DateTime(2014, 3, 30, 12, 0, 0),
-                DateTime(2014, 4, 28, 12, 0, 0),
-                DateTime(2014, 5, 28, 12, 0, 0),
-                DateTime(2014, 6, 26, 12, 0, 0),
-                DateTime(2014, 7, 26, 12, 0, 0),
-                DateTime(2014, 8, 24, 12, 0, 0),
-                DateTime(2014, 9, 23, 12, 0, 0),
-                DateTime(2014, 10, 23, 12, 0, 0),
-                DateTime(2014, 11, 21, 12, 0, 0),
-                DateTime(2014, 12, 21, 12, 0, 0),
+                DateTime(2014, 1, 1, 12, 0, 0),
+                DateTime(2014, 3, 1, 12, 0, 0),
+                DateTime(2014, 5, 1, 12, 0, 0),
+                DateTime(2014, 7, 1, 12, 0, 0),
+                DateTime(2014, 8, 1, 12, 0, 0),
+                DateTime(2014, 10, 1, 12, 0, 0),
+                DateTime(2014, 12, 1, 12, 0, 0),
             ],
-            msg="Failed: {} {}".format(rrule, items,),
         )
 
 
-    def testChineseMonthlyByMonthDay30SkipForward(self):
+    def testMonthlyByLastFridayExpand(self):
 
-        rrule = "RSCALE=CHINESE;FREQ=MONTHLY;BYMONTHDAY=30;SKIP=FORWARD"
         recur = Recurrence()
-        recur.parse(rrule)
-        start = DateTime(2014, 1, 30, 12, 0, 0)
+        recur.parse("FREQ=MONTHLY;BYDAY=-1FR")
+        start = DateTime(2014, 1, 31, 12, 0, 0)
         end = DateTime(2015, 1, 1, 0, 0, 0)
         items = []
         range = Period(start, end)
@@ -802,29 +318,27 @@
         self.assertEqual(
             items,
             [
-                DateTime(2014, 1, 30, 12, 0, 0),
-                DateTime(2014, 3, 1, 12, 0, 0),
-                DateTime(2014, 3, 30, 12, 0, 0),
-                DateTime(2014, 4, 29, 12, 0, 0),
-                DateTime(2014, 5, 28, 12, 0, 0),
+                DateTime(2014, 1, 31, 12, 0, 0),
+                DateTime(2014, 2, 28, 12, 0, 0),
+                DateTime(2014, 3, 28, 12, 0, 0),
+                DateTime(2014, 4, 25, 12, 0, 0),
+                DateTime(2014, 5, 30, 12, 0, 0),
                 DateTime(2014, 6, 27, 12, 0, 0),
-                DateTime(2014, 7, 26, 12, 0, 0),
-                DateTime(2014, 8, 25, 12, 0, 0),
-                DateTime(2014, 9, 23, 12, 0, 0),
-                DateTime(2014, 10, 23, 12, 0, 0),
-                DateTime(2014, 11, 22, 12, 0, 0),
-                DateTime(2014, 12, 21, 12, 0, 0),
+                DateTime(2014, 7, 25, 12, 0, 0),
+                DateTime(2014, 8, 29, 12, 0, 0),
+                DateTime(2014, 9, 26, 12, 0, 0),
+                DateTime(2014, 10, 31, 12, 0, 0),
+                DateTime(2014, 11, 28, 12, 0, 0),
+                DateTime(2014, 12, 26, 12, 0, 0),
             ],
-            msg="Failed: {} {}".format(rrule, items,),
         )
 
 
-    def testChineseMonthlyByMonthDayMinus30SkipYes(self):
+    def testMonthlyByFifthFridayExpand(self):
 
-        rrule = "RSCALE=CHINESE;FREQ=MONTHLY;BYMONTHDAY=-30;SKIP=YES"
         recur = Recurrence()
-        recur.parse(rrule)
-        start = DateTime(2014, 1, 30, 12, 0, 0)
+        recur.parse("FREQ=MONTHLY;BYDAY=5FR")
+        start = DateTime(2014, 1, 31, 12, 0, 0)
         end = DateTime(2015, 1, 1, 0, 0, 0)
         items = []
         range = Period(start, end)
@@ -832,72 +346,66 @@
         self.assertEqual(
             items,
             [
-                DateTime(2014, 3, 1, 12, 0, 0),
-                DateTime(2014, 4, 29, 12, 0, 0),
-                DateTime(2014, 6, 27, 12, 0, 0),
-                DateTime(2014, 8, 25, 12, 0, 0),
-                DateTime(2014, 9, 24, 12, 0, 0),
-                DateTime(2014, 11, 22, 12, 0, 0),
+                DateTime(2014, 1, 31, 12, 0, 0),
+                DateTime(2014, 5, 30, 12, 0, 0),
+                DateTime(2014, 8, 29, 12, 0, 0),
+                DateTime(2014, 10, 31, 12, 0, 0),
             ],
-            msg="Failed: {} {}".format(rrule, items,),
         )
 
 
-    def testChineseMonthlyByMonthDayMinus30SkipBackward(self):
+    def testYearlyLeapDay(self):
 
-        rrule = "RSCALE=CHINESE;FREQ=MONTHLY;BYMONTHDAY=-30;SKIP=BACKWARD"
         recur = Recurrence()
-        recur.parse(rrule)
-        start = DateTime(2014, 1, 30, 12, 0, 0)
-        end = DateTime(2015, 1, 1, 0, 0, 0)
+        recur.parse("FREQ=YEARLY")
+        start = DateTime(2012, 2, 29, 12, 0, 0)
+        end = DateTime(2020, 1, 1, 0, 0, 0)
         items = []
         range = Period(start, end)
         recur.expand(start, range, items)
         self.assertEqual(
             items,
             [
-                DateTime(2014, 1, 30, 12, 0, 0),
-                DateTime(2014, 3, 1, 12, 0, 0),
-                DateTime(2014, 3, 30, 12, 0, 0),
-                DateTime(2014, 4, 29, 12, 0, 0),
-                DateTime(2014, 5, 28, 12, 0, 0),
-                DateTime(2014, 6, 27, 12, 0, 0),
-                DateTime(2014, 7, 26, 12, 0, 0),
-                DateTime(2014, 8, 25, 12, 0, 0),
-                DateTime(2014, 9, 24, 12, 0, 0),
-                DateTime(2014, 10, 23, 12, 0, 0),
-                DateTime(2014, 11, 22, 12, 0, 0),
-                DateTime(2014, 12, 21, 12, 0, 0),
+                DateTime(2012, 2, 29, 12, 0, 0),
+                DateTime(2016, 2, 29, 12, 0, 0),
             ],
-            msg="Failed: {} {}".format(rrule, items,),
         )
 
 
-    def testChineseMonthlyByMonthDayMinus30SkipForward(self):
+    def testYearlyYearDay(self):
 
-        rrule = "RSCALE=CHINESE;FREQ=MONTHLY;BYMONTHDAY=-30;SKIP=FORWARD"
         recur = Recurrence()
-        recur.parse(rrule)
-        start = DateTime(2014, 1, 30, 12, 0, 0)
-        end = DateTime(2015, 1, 1, 0, 0, 0)
+        recur.parse("FREQ=YEARLY;BYYEARDAY=366")
+        start = DateTime(2012, 12, 31, 12, 0, 0)
+        end = DateTime(2020, 1, 1, 0, 0, 0)
         items = []
         range = Period(start, end)
         recur.expand(start, range, items)
         self.assertEqual(
             items,
             [
-                DateTime(2014, 1, 31, 12, 0, 0),
-                DateTime(2014, 3, 1, 12, 0, 0),
-                DateTime(2014, 3, 31, 12, 0, 0),
-                DateTime(2014, 4, 29, 12, 0, 0),
-                DateTime(2014, 5, 29, 12, 0, 0),
-                DateTime(2014, 6, 27, 12, 0, 0),
-                DateTime(2014, 7, 27, 12, 0, 0),
-                DateTime(2014, 8, 25, 12, 0, 0),
-                DateTime(2014, 9, 24, 12, 0, 0),
-                DateTime(2014, 10, 24, 12, 0, 0),
-                DateTime(2014, 11, 22, 12, 0, 0),
-                DateTime(2014, 12, 22, 12, 0, 0),
+                DateTime(2012, 12, 31, 12, 0, 0),
+                DateTime(2016, 12, 31, 12, 0, 0),
             ],
-            msg="Failed: {} {}".format(rrule, items,),
         )
+
+
+    def testClearOnChange(self):
+
+        recur = Recurrence()
+        recur.parse("FREQ=DAILY")
+
+        start = DateTime(2013, 1, 1, 0, 0, 0)
+        end = DateTime(2017, 1, 1, 0, 0, 0)
+        range = Period(start, end)
+        items = []
+        recur.expand(start, range, items)
+        self.assertTrue(recur.mCached)
+        self.assertTrue(len(items) > 100)
+
+        recur.setUseCount(True)
+        recur.setCount(10)
+        self.assertFalse(recur.mCached)
+        items = []
+        recur.expand(start, range, items)
+        self.assertEqual(len(items), 10)

Modified: PyCalendar/trunk/src/pycalendar/icalendar/xmldefinitions.py
===================================================================
--- PyCalendar/trunk/src/pycalendar/icalendar/xmldefinitions.py	2014-12-01 16:26:51 UTC (rev 14192)
+++ PyCalendar/trunk/src/pycalendar/icalendar/xmldefinitions.py	2014-12-01 16:50:49 UTC (rev 14193)
@@ -22,8 +22,6 @@
 
 value_recur = "recur"
 
-recur_rscale = "rscale"
-
 recur_freq = "freq"
 recur_freq_secondly = "SECONDLY"
 recur_freq_minutely = "MINUTELY"
@@ -37,11 +35,6 @@
 recur_until = "until"
 recur_interval = "interval"
 
-recur_skip = "skip"
-recur_skip_yes = "yes"
-recur_skip_backward = "backward"
-recur_skip_forward = "forward"
-
 recur_bysecond = "bysecond"
 recur_byminute = "byminute"
 recur_byhour = "byhour"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20141201/ea73932b/attachment-0001.html>


More information about the calendarserver-changes mailing list