private void addTransitions(VComponent timeRule, long from, long to) throws Exception { int offset; int previousOffset; String start; long startTime; long time; String transitionName; Property tzName = timeRule.getProperty("TZNAME"); Property tzOffsetFrom = timeRule.getProperty("TZOFFSETFROM"); Property tzOffsetTo = timeRule.getProperty("TZOFFSETTO"); Property tzDtStart = timeRule.getProperty("DTSTART"); Property tzRRule = timeRule.getProperty("RRULE"); Property tzRDate = timeRule.getProperty("RDATE"); if (tzDtStart != null) { start = tzDtStart.getValue(); startTime = parseDateTime(start); } else { throw new Exception("Required property DTSTART (of a time zone) is missing"); } if (tzOffsetTo != null) { offset = parseOffset(tzOffsetTo.getValue()); } else { throw new Exception("Required property TZOFFSETTO is missing"); } if (tzOffsetFrom != null) { previousOffset = parseOffset(tzOffsetFrom.getValue()); } else { throw new Exception("Required property TZOFFSETFROM is missing"); } if (tzName != null) { transitionName = tzName.getValue(); } else { transitionName = ""; } if (tzRDate != null) { String[] rDates = tzRDate.getValue().split(","); for (String rDate : rDates) { time = parseDateTime(rDate); transitions.add(new TimeZoneTransition(offset, time, transitionName)); } } if (tzRRule != null) { RecurrencePattern rrule = VCalendarContentConverter.getRecurrencePattern( start, null, tzRRule.getValue(), null, // as of specs false); // iCalendar if (((rrule.getTypeId() == RecurrencePattern.TYPE_MONTH_NTH) && (rrule.getInterval() == 12)) || ((rrule.getTypeId() == RecurrencePattern.TYPE_YEAR_NTH) && (rrule.getInterval() == 1))) { // yearly int dayOfWeek = getDayOfWeekFromMask(rrule.getDayOfWeekMask()); if (dayOfWeek > 0) { // one day TimeZone fixed = TimeZone.getTimeZone("UTC"); fixed.setRawOffset(previousOffset); Calendar finder = new GregorianCalendar(fixed); finder.setTimeInMillis(startTime); // Sets hour and minutes int hh = finder.get(Calendar.HOUR_OF_DAY); int mm = finder.get(Calendar.MINUTE); int m = rrule.getMonthOfYear() - 1; // Yes, it works int yearStart = year(startTime); int yearFrom = (startTime > from) ? yearStart : year(from); int yearTo = year(to); if (rrule.isNoEndDate()) { int count = rrule.getOccurrences(); int yearRecurrenceEnd; if (count != -1) { yearRecurrenceEnd = yearStart + count - 1; if (yearRecurrenceEnd < yearTo) { yearTo = yearRecurrenceEnd; } } } else { try { int yearRecurrenceEnd = year(rrule.getEndDatePattern()); if (yearRecurrenceEnd < yearTo) { yearTo = yearRecurrenceEnd; } } catch (ParseException e) { // Ignores the UNTIL part } } for (int y = yearFrom; y <= yearTo; y++) { finder.clear(); finder.set(Calendar.YEAR, y); finder.set(Calendar.MONTH, m); finder.set(Calendar.DAY_OF_WEEK, dayOfWeek); finder.set(Calendar.DAY_OF_WEEK_IN_MONTH, rrule.getInstance()); finder.set(Calendar.HOUR_OF_DAY, hh); finder.set(Calendar.MINUTE, mm); long transitionTime = finder.getTimeInMillis() - (previousOffset - getBasicOffset()); transitions.add(new TimeZoneTransition(offset, transitionTime, transitionName)); } } } } }