in src/zonal/rule.py [0:0]
def vtimezone(self, vtz, zonerule, start, end, offsetfrom, offsetto, instanceCount):
"""
Generate a VTIMEZONE sub-component for this Rule.
@param vtz: VTIMEZONE to add to
@type vtz: L{VTimezone}
@param zonerule: the Zone rule line being used
@type zonerule: L{ZoneRule}
@param start: the start time for the first instance
@type start: L{DateTime}
@param end: the start time for the last instance
@type end: L{DateTime}
@param offsetfrom: the UTC offset-from
@type offsetfrom: C{int}
@param offsetto: the UTC offset-to
@type offsetto: C{int}
@param instanceCount: the number of instances in the set
@type instanceCount: C{int}
"""
# Determine type of component based on offset
dstoffset = self.getOffset()
if dstoffset == 0:
comp = Standard(parent=vtz)
else:
comp = Daylight(parent=vtz)
# Do offsets
tzoffsetfrom = UTCOffsetValue(offsetfrom)
tzoffsetto = UTCOffsetValue(offsetto)
comp.addProperty(Property(definitions.cICalProperty_TZOFFSETFROM, tzoffsetfrom))
comp.addProperty(Property(definitions.cICalProperty_TZOFFSETTO, tzoffsetto))
# Do TZNAME
if zonerule.format.find("%") != -1:
tzname = zonerule.format % (self.letter if self.letter != "-" else "",)
elif "/" in zonerule.format:
split_format = zonerule.format.split("/")
tzname = split_format[0] if dstoffset == 0 else split_format[1]
else:
tzname = zonerule.format
comp.addProperty(Property(definitions.cICalProperty_TZNAME, tzname))
# Do DTSTART
comp.addProperty(Property(definitions.cICalProperty_DTSTART, start))
if start == end:
instanceCount = 1
# Now determine the recurrences (use RDATE if only one year or
# number of instances is one)
if self.toYear != "only" and instanceCount != 1:
rrule = Recurrence()
rrule.setFreq(definitions.eRecurrence_YEARLY)
rrule.setByMonth((Rule.MONTH_NAME_TO_POS[self.inMonth],))
if self.onDay in Rule.LASTDAY_NAME_TO_RDAY:
# Need to check whether day has changed due to time shifting
dayOfWeek = start.getDayOfWeek()
indicatedDay = Rule.LASTDAY_NAME_TO_DAY[self.onDay]
if dayOfWeek == indicatedDay:
rrule.setByDay(((-1, Rule.LASTDAY_NAME_TO_RDAY[self.onDay]),))
elif dayOfWeek < indicatedDay or dayOfWeek == 6 and indicatedDay == 0:
# This is OK as we have moved back a day and thus no month transition
# could have occurred
fakeOffset = daysInMonth(start.getMonth(), start.getYear()) - 6
offset, rday, bymday = self.getOnDayDetails(start, indicatedDay, fakeOffset)
if bymday:
rrule.setByMonthDay(bymday)
rrule.setByDay(((offset, rday),))
else:
# This is bad news as we have moved forward a day possibly into the next month
# What we do is switch to using a BYYEARDAY rule with offset from the end of the year
rrule.setByMonth(())
daysBackStartOfMonth = (
365, 334, 306, 275, 245, 214, 184, 153, 122, 92, 61, 31, 0 # Does not account for leap year
)
rrule.setByYearDay([-(daysBackStartOfMonth[Rule.MONTH_NAME_TO_POS[self.inMonth]] + i) for i in range(7)])
rrule.setByDay(
((0, divmod(Rule.LASTDAY_NAME_TO_DAY[self.onDay] + 1, 7)[1]),),
)
elif self.onDay.find(">=") != -1:
indicatedDay, dayoffset = self.onDay.split(">=")
# Need to check whether day has changed due to time shifting
dayOfWeek = start.getDayOfWeek()
indicatedDay = Rule.DAY_NAME_TO_DAY[indicatedDay]
if dayOfWeek == indicatedDay:
offset, rday, bymday = self.getOnDayDetails(start, indicatedDay, int(dayoffset))
if bymday:
rrule.setByMonthDay(bymday)
rrule.setByDay(((offset, rday),))
elif dayoffset == 1 and divmod(dayoffset - indicatedDay, 7)[1] == 6:
# This is bad news as we have moved backward a day possibly into the next month
# What we do is switch to using a BYYEARDAY rule with offset from the end of the year
rrule.setByMonth(())
daysBackStartOfMonth = (
365, 334, 306, 275, 245, 214, 184, 153, 122, 92, 61, 31, 0 # Does not account for leap year
)
rrule.setByYearDay([-(daysBackStartOfMonth[Rule.MONTH_NAME_TO_POS[self.inMonth]] + i) for i in range(7)])
rrule.setByDay(
((0, divmod(indicatedDay + 1, 7)[1]),),
)
else:
# This is OK as we have moved forward a day and thus no month transition
# could have occurred
offset, rday, bymday = self.getOnDayDetails(start, indicatedDay, int(dayoffset))
if bymday:
rrule.setByMonthDay(bymday)
rrule.setByDay(((offset, rday),))
else:
try:
int(self.onDay)
except:
assert False, "onDay value is not recognized: %s" % (self.onDay,)
# Add any UNTIL
if zonerule.getUntilDate().dt.getYear() < 9999 or self.endYear() < 9999:
until = end.duplicate()
until.offsetSeconds(-offsetfrom)
until.setTimezoneUTC(True)
rrule.setUseUntil(True)
rrule.setUntil(until)
comp.addProperty(Property(definitions.cICalProperty_RRULE, rrule))
else:
comp.addProperty(Property(definitions.cICalProperty_RDATE, start))
comp.finalise()
vtz.addComponent(comp)