use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class CompleteTaskInstance method createCompletedInstanceInvite.
private Invite createCompletedInstanceInvite(Invite recur, ParsedDateTime dtStart) throws ServiceException {
Invite inst = new Invite(MailItem.Type.TASK, recur.getMethod(), (recur.getTimeZoneMap() != null) ? recur.getTimeZoneMap().clone() : null, recur.isOrganizer());
long now = System.currentTimeMillis();
// Assign a new UID.
String uid = LdapUtil.generateUUID();
inst.setUid(uid);
inst.setSeqNo(0);
// Set completed status/pct/time.
inst.setStatus(IcalXmlStrMap.STATUS_COMPLETED);
inst.setPercentComplete("100");
inst.setCompleted(now);
// Set time fields.
inst.setDtStart(dtStart);
ParsedDuration dur = recur.getEffectiveDuration();
if (dur != null) {
ParsedDateTime due = dtStart.add(dur);
inst.setDtEnd(due);
}
inst.setDtStamp(now);
// Recurrence-related fields should be unset.
inst.setRecurrence(null);
inst.setRecurId(null);
// Copy the rest of the fields.
inst.setPriority(recur.getPriority());
inst.setOrganizer(recur.getOrganizer());
List<ZAttendee> attendees = recur.getAttendees();
for (ZAttendee at : attendees) inst.addAttendee(at);
inst.setName(recur.getName());
inst.setLocation(recur.getLocation());
inst.setFlags(recur.getFlags());
inst.setDescription(recur.getDescription(), recur.getDescriptionHtml());
inst.setFragment(recur.getFragment());
return inst;
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class CalSummaryCache method reloadCalendarItemOverRange.
// mSummaryCache
//
// key = "accountId:folderId"
// value = CalendarData type
//
// CalendarData = {
// folderId, range start, range end,
// // list of CalendarItemData objects (one for each appointment in range)
// [
// CalendarItemData {
// calItemId, folderId, flags, tags, item type,
// last modified,
// actual range start, actual range end,
// uid, isRecurring, isPublic, alarm,
// default instance data (FullInstanceData type),
// // list of instances (FullInstanceData if an exception, InstanceData if not)
// [
// InstanceData/FullInstanceData, ...
// ]
// },
// CalendarItemData, ...
// ]
public static CalendarItemData reloadCalendarItemOverRange(CalendarItem calItem, long rangeStart, long rangeEnd) throws ServiceException {
CalendarItemData calItemData = null;
try {
boolean rangeValid = (rangeStart >= CalendarUtils.MICROSOFT_EPOC_START_MS_SINCE_EPOC && rangeEnd > CalendarUtils.MICROSOFT_EPOC_START_MS_SINCE_EPOC && rangeStart < rangeEnd);
if (!rangeValid) {
return null;
}
Invite defaultInvite = calItem.getDefaultInviteOrNull();
if (defaultInvite == null) {
ZimbraLog.calendar.info("Could not load defaultinfo for calendar item with id=" + calItem.getId() + "; SKIPPING");
return null;
}
String defaultFba = null;
if (calItem instanceof Appointment)
defaultFba = ((Appointment) calItem).getEffectiveFreeBusyActual(defaultInvite, null);
AlarmData alarm = null;
CalendarItem.AlarmData calItemAlarmData = calItem.getAlarmData();
long alarmTime = 0;
long alarmInst = 0;
if (calItemAlarmData != null) {
alarmTime = calItemAlarmData.getNextAt();
alarmInst = calItemAlarmData.getNextInstanceStart();
int alarmInvId = calItemAlarmData.getInvId();
int alarmCompNum = calItemAlarmData.getCompNum();
String summary = null, location = null;
Invite alarmInv = calItem.getInvite(alarmInvId, alarmCompNum);
if (alarmInv != null) {
summary = alarmInv.getName();
location = alarmInv.getLocation();
}
alarm = new AlarmData(calItemAlarmData.getNextAt(), calItemAlarmData.getNextInstanceStart(), alarmInvId, alarmCompNum, summary, location, calItemAlarmData.getAlarm());
}
Long defDtStartLong = null;
Long defDurationLong = null;
ParsedDateTime defDtStart = defaultInvite.getStartTime();
if (defDtStart != null) {
defDtStartLong = Long.valueOf(defDtStart.getUtcTime());
ParsedDateTime defDtEnd = defaultInvite.getEffectiveEndTime();
if (defDtEnd != null)
defDurationLong = Long.valueOf(defDtEnd.getUtcTime() - defDtStartLong.longValue());
}
String defaultEffectivePartStat = calItem.getEffectivePartStat(defaultInvite, null);
FullInstanceData defaultData = new FullInstanceData(defaultInvite, null, defDtStartLong, defDurationLong, defaultEffectivePartStat, defaultFba, null);
calItemData = new CalendarItemData(calItem.getType(), calItem.getFolderId(), calItem.getId(), calItem.getFlagString(), calItem.getTags(), TagUtil.getTagIdString(calItem), calItem.getModifiedSequence(), calItem.getSavedSequence(), calItem.getDate(), calItem.getChangeDate(), calItem.getSize(), defaultInvite.getUid(), defaultInvite.isRecurrence(), calItem.hasExceptions(), calItem.isPublic(), alarm, defaultData);
long actualRangeStart = 0;
long actualRangeEnd = 0;
int numInstances = 0;
Collection<CalendarItem.Instance> instances = calItem.expandInstances(rangeStart, rangeEnd, true);
for (CalendarItem.Instance inst : instances) {
try {
long instStart = inst.getStart();
long duration = inst.getEnd() - instStart;
// 0 means "no DTSTART", however, note that negative numbers are valid
Long instStartLong = instStart != 0 ? Long.valueOf(instStart) : null;
Long durationLong = duration > 0 ? Long.valueOf(duration) : null;
// For an instance whose alarm time is within the time range, we must
// include it even if its start time is after the range.
long startOrAlarm = instStart == alarmInst ? alarmTime : instStart;
boolean hasTimes = inst.hasStart() && inst.hasEnd();
if (hasTimes && (startOrAlarm >= rangeEnd || inst.getEnd() <= rangeStart)) {
continue;
}
numInstances++;
if (hasTimes) {
if (actualRangeStart == 0 || startOrAlarm < actualRangeStart)
actualRangeStart = startOrAlarm;
if (inst.getEnd() > actualRangeEnd)
actualRangeEnd = inst.getEnd();
}
InviteInfo invId = inst.getInviteInfo();
Invite inv = calItem.getInvite(invId.getMsgId(), invId.getComponentId());
Long alarmAt = instStart == alarmInst ? Long.valueOf(alarmTime) : null;
String fba = inv.getFreeBusyActual();
if (calItem instanceof Appointment)
fba = ((Appointment) calItem).getEffectiveFreeBusyActual(inv, inst);
String effectivePartStat = calItem.getEffectivePartStat(inv, inst);
InstanceData instData;
if (!inst.isException()) {
String ridZ = inst.getRecurIdZ();
Long tzOffset = instStartLong != null && inst.isAllDay() ? Long.valueOf(inst.getStartTzOffset()) : null;
instData = new InstanceData(ridZ, instStartLong, durationLong, alarmAt, tzOffset, effectivePartStat, fba, inv.getPercentComplete(), defaultData);
} else {
String ridZ = null;
if (inv.hasRecurId())
ridZ = inv.getRecurId().getDtZ();
instData = new FullInstanceData(inv, ridZ, instStartLong, durationLong, effectivePartStat, fba, alarmAt);
}
calItemData.addInstance(instData);
} catch (MailServiceException.NoSuchItemException e) {
ZimbraLog.calendar.info("Error could not get instance " + inst.getMailItemId() + "-" + inst.getComponentNum() + " for appt " + calItem.getId(), e);
}
}
if (numInstances < 1)
return null;
calItemData.setActualRange(actualRangeStart, actualRangeEnd);
} catch (MailServiceException.NoSuchItemException e) {
ZimbraLog.calendar.info("Error could not get default invite for calendar item: " + calItem.getId(), e);
} catch (RuntimeException e) {
ZimbraLog.calendar.info("Caught Exception " + e + " while getting summary info for calendar item: " + calItem.getId(), e);
}
return calItemData;
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class ZRecur method expandRecurrenceOverRange.
public List<Date> expandRecurrenceOverRange(ParsedDateTime dtStart, long rangeStart, long rangeEnd) throws ServiceException {
List<Date> toRet = new LinkedList<Date>();
Date rangeStartDate = new Date(rangeStart);
// subtract 1000ms (1sec) because the code in the method treats
// end time as inclusive while the rangeEnd input argument is
// exclusive value
Date rangeEndDate = new Date(rangeEnd - 1000);
Date dtStartDate = new Date(dtStart.getUtcTime());
Date earliestDate;
if (dtStartDate.after(rangeStartDate))
earliestDate = dtStartDate;
else
earliestDate = rangeStartDate;
if (mUntil != null) {
Date until = mUntil.getDateForRecurUntil(dtStart.getTimeZone());
if (until.before(rangeEndDate))
rangeEndDate = until;
}
// Set limit of expansion count.
int maxInstancesFromConfig = sExpansionLimits.maxInstances;
int maxInstancesExpanded;
if (maxInstancesFromConfig <= 0)
maxInstancesExpanded = mCount;
else if (mCount <= 0)
maxInstancesExpanded = maxInstancesFromConfig;
else
maxInstancesExpanded = Math.min(mCount, maxInstancesFromConfig);
// initially 1 rather than 0 because DTSTART is always included
int numInstancesExpanded = 1;
// Set hard limit of expansion time range. (bug 21989)
ParsedDateTime earliestDateTime = ParsedDateTime.fromUTCTime(earliestDate.getTime());
Date hardEndDate = getEstimatedEndTime(earliestDateTime);
if (hardEndDate.before(rangeEndDate))
rangeEndDate = hardEndDate;
if (rangeEndDate.before(earliestDate)) {
ZimbraLog.calendar.debug("Expanding recurrence over range where range end %s is before earliest date %s", DateUtil.formatDate(rangeEndDate), DateUtil.formatDate(earliestDate));
return toRet;
}
GregorianCalendar cur = dtStart.getCalendarCopy();
int baseMonthDay = cur.get(Calendar.DAY_OF_MONTH);
boolean baseIsLeapDay = ((baseMonthDay == 29) && (cur.get(Calendar.MONTH) == Calendar.FEBRUARY));
// until we hit rangeEnd, or we've SAVED count entries:
//
// gather each set {
//
//
//
// curDate forward one INTERVAL
//
// }
// check Set against BYSETPOS & ranges & count
//
int interval = mInterval;
if (interval <= 0)
interval = 1;
// the range.
if (!dtStartDate.before(earliestDate) && !dtStartDate.after(rangeEndDate))
toRet.add(dtStartDate);
int numConsecutiveIterationsWithoutMatchingInstance = 0;
boolean pastHardEndTime = false;
// track how many times we looped
long numIterations = 0;
while (!pastHardEndTime && (maxInstancesExpanded <= 0 || numInstancesExpanded < maxInstancesExpanded)) {
numIterations++;
boolean curIsAtOrAfterEarliestDate = !cur.getTime().before(earliestDate);
boolean curIsAfterEndDate = cur.getTime().after(rangeEndDate);
List<Calendar> addList = new LinkedList<Calendar>();
switch(mFreq) {
case HOURLY:
/*
* BYSECOND - for each listed second
* BYMINUTE - for each listed minute in hour
* BYHOUR - match iff in hour list
* BYDAY - for each day listed
* BYMONTHDAY - only those monthdays
* BYYEARDAY - only those yeardays
* BYMONTH - only those months
*/
if (!checkMonthList(cur))
continue;
if (!checkYearDayList(cur))
continue;
if (!checkMonthDayList(cur))
continue;
if (!checkDayList(cur))
continue;
if (!checkHourList(cur))
continue;
addList.add((Calendar) (cur.clone()));
cur.add(Calendar.HOUR_OF_DAY, interval);
addList = expandHourList(addList);
addList = expandMinuteList(addList);
addList = expandSecondList(addList);
break;
case DAILY:
if (!checkMonthList(cur))
continue;
if (!checkYearDayList(cur))
continue;
if (!checkMonthDayList(cur))
continue;
if (!checkDayList(cur))
continue;
addList.add((Calendar) (cur.clone()));
cur.add(Calendar.DAY_OF_YEAR, interval);
addList = expandHourList(addList);
addList = expandMinuteList(addList);
addList = expandSecondList(addList);
break;
case WEEKLY:
/*
* BYSECOND - for every listed second
* BYMINUTE - for every listed minute
* BYHOUR - for every listed hour
* BYDAY - for every listed day
* BYMONTHDAY - MAYBE once a month
* BYYEARDAY - MAYBE once a year
* BYMONTH - iff month matches
*
* for each (INTERVAL)WEEK{
* if (byMonth && !month matches)
* curDay = set MONTH to DtStart in next matching month
*
* if (byYearDay && !yearday matches)
* curDay = set date to next matching yearday
*
* if (byMonthDay && !monthday matches)
* curDay = skip to next matching monthday
*
* if (!byDay or FOREACH day in list)
* if (!byHour or FOREACH hour in list)
* if (!byMinute or FOREACH minute in list)
* if (!bySecond or FOREACH second in list)
* ----add to list----
*
* check against BYSETPOS
*
* curDay += 1 week
* } while (count check & until check & rangeEnd check)
*
*/
if (!checkMonthList(cur))
continue;
if (!checkYearDayList(cur))
continue;
if (!checkMonthDayList(cur))
continue;
addList.add((Calendar) (cur.clone()));
cur.add(Calendar.WEEK_OF_YEAR, interval);
addList = expandDayListForWeekly(addList);
addList = expandHourList(addList);
addList = expandMinuteList(addList);
addList = expandSecondList(addList);
break;
case MONTHLY:
if (!checkMonthList(cur))
continue;
if (!checkYearDayList(cur))
continue;
addList.add((Calendar) (cur.clone()));
cur.set(Calendar.DAY_OF_MONTH, 1);
cur.add(Calendar.MONTH, interval);
int daysInMonth = cur.getActualMaximum(Calendar.DAY_OF_MONTH);
cur.set(Calendar.DAY_OF_MONTH, Math.min(baseMonthDay, daysInMonth));
addList = expandMonthDayList(addList);
addList = expandDayListForMonthlyYearly(addList);
addList = expandHourList(addList);
addList = expandMinuteList(addList);
addList = expandSecondList(addList);
break;
case YEARLY:
/*
* BYSECOND
* BYMINUTE
* BYHOUR
* BYDAY
* BYMONTHDAY
* BYYEARDAY
* BYWEEKNO - specified week
* BYMONTH - once
*/
if (baseIsLeapDay) {
// previously adding a year to a leap day will have rounded down to the 28th.
// If this happened, we need to be sure that if we are back in a leap
// year, it is back at 29th
cur.set(Calendar.DAY_OF_MONTH, cur.getActualMaximum(Calendar.DAY_OF_MONTH));
}
if (ignoreYearForRecurrenceExpansion(cur, baseIsLeapDay)) {
cur.add(Calendar.YEAR, interval);
break;
}
addList.add((Calendar) (cur.clone()));
cur.add(Calendar.YEAR, interval);
addList = expandMonthList(addList);
addList = expandYearDayList(addList);
addList = expandMonthDayList(addList);
addList = expandDayListForMonthlyYearly(addList);
addList = expandHourList(addList);
addList = expandMinuteList(addList);
addList = expandSecondList(addList);
break;
default:
// MINUTELY and SECONDLY are intentionally not supported for performance reasons.
return toRet;
}
addList = handleSetPos(addList);
boolean noInstanceFound = true;
boolean foundInstancePastEndDate = false;
// add all the ones that match!
for (Calendar addCal : addList) {
Date toAdd = addCal.getTime();
// count it twice.
if (toAdd.compareTo(dtStartDate) == 0) {
noInstanceFound = false;
continue;
}
// current date window
if (toAdd.after(dtStartDate))
numInstancesExpanded++;
if (!toAdd.after(rangeEndDate)) {
if (!toAdd.before(earliestDate)) {
toRet.add(toAdd);
noInstanceFound = false;
}
} else {
foundInstancePastEndDate = true;
break;
}
if (maxInstancesExpanded > 0 && numInstancesExpanded >= maxInstancesExpanded)
break;
}
// So the invalid rule detection must look for at least 4 consecutive failed iterations.
if (curIsAtOrAfterEarliestDate) {
if (noInstanceFound)
numConsecutiveIterationsWithoutMatchingInstance++;
else
numConsecutiveIterationsWithoutMatchingInstance = 0;
if (numConsecutiveIterationsWithoutMatchingInstance >= 4) {
ZimbraLog.calendar.warn("Invalid recurrence rule: " + toString());
return toRet;
}
}
pastHardEndTime = foundInstancePastEndDate || (noInstanceFound && curIsAfterEndDate);
}
return toRet;
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class ZRecur method main.
public static void main(String[] args) {
ICalTimeZone tzUTC = ICalTimeZone.getUTC();
TimeZoneMap tzmap = new TimeZoneMap(tzUTC);
ParsedDateTime dtStart = null;
try {
dtStart = ParsedDateTime.parse("20050101T123456", tzmap, tzUTC, tzUTC);
} catch (ParseException e) {
System.out.println("Caught ParseException at start: " + e);
}
Date rangeStart;
Date rangeEnd;
GregorianCalendar cal = new GregorianCalendar();
cal.clear();
cal.setTimeZone(tzUTC);
cal.set(2005, 4, 15, 0, 0, 0);
rangeStart = cal.getTime();
cal.set(2006, 0, 1, 0, 0, 0);
rangeEnd = cal.getTime();
try {
ZRecur test = new ZRecur("FREQ=DAILY;BYMONTH=5,6", tzmap);
System.out.println("\n\n" + test.toString() + "\n-------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
cal.setTimeZone(tzUTC);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
try {
ZRecur test = new ZRecur("FREQ=DAILY;BYMONTH=5,6;BYDAY=TH,-1MO", tzmap);
System.out.println("\n\n" + test.toString() + "\n-------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
cal.setTimeZone(tzUTC);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
try {
ZRecur test = new ZRecur("FREQ=DAILY;BYMONTH=5,6;BYMONTHDAY=1,3,5,7,9,31", tzmap);
System.out.println("\n\n" + test.toString() + "\n-------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
try {
ZRecur test = new ZRecur("FREQ=DAILY;BYMONTH=5,6;BYMONTHDAY=1,3,5,7,9,31;BYDAY=SU,SA", tzmap);
System.out.println("\n\n" + test.toString() + "\n--------------------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
try {
ZRecur test = new ZRecur("FREQ=DAILY;BYMONTH=5,6;BYMONTHDAY=1,3,5,7,9,31;BYDAY=SU,SA;BYHOUR=21,0", tzmap);
System.out.println("\n\n" + test.toString() + "\n--------------------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
try {
ZRecur test = new ZRecur("FREQ=DAILY;BYMONTH=5,6;BYMONTHDAY=1,3,5,7,9,31;BYDAY=SU;BYHOUR=21,0;BYMINUTE=23", tzmap);
System.out.println("\n\n" + test.toString() + "\n--------------------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
try {
ZRecur test = new ZRecur("FREQ=DAILY;BYMONTH=5,6;BYMONTHDAY=1,3,5,7,9,31;BYDAY=SU;BYHOUR=1,21,0;BYSECOND=0,59", tzmap);
System.out.println("\n\n" + test.toString() + "\n--------------------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
try {
// parse error testing
ZRecur test = new ZRecur("FREQ=DAILY;BIYMONTH=5,6;BYMONTHDAY=1,3,5,7,9,31;BYDAY=SU;BYHOUR=1,21,0;BYSECOND=0,59;BYSETPOS=1,-1,3,1000,,-1000", tzmap);
System.out.println("\n\n" + test.toString() + "\n--------------------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
try {
ZRecur test = new ZRecur("FREQ=HOURLY;BIYMONTH=6;BYMONTHDAY=1,3;BYHOUR=2,14", tzmap);
System.out.println("\n\n" + test.toString() + "\n--------------------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
try {
ZRecur test = new ZRecur("FREQ=HOURLY;BIYMONTH=6;BYMONTHDAY=1;;BYMINUTE=10;BYSECOND=11,12", tzmap);
System.out.println("\n\n" + test.toString() + "\n--------------------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
cal.set(2010, 0, 1, 0, 0, 0);
rangeEnd = cal.getTime();
try {
ZRecur test = new ZRecur("FREQ=YEARLY", tzmap);
System.out.println("\n\n" + test.toString() + "\n--------------------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
try {
ZRecur test = new ZRecur("FREQ=YEARLY;BYYEARDAY=-1", tzmap);
System.out.println("\n\n" + test.toString() + "\n--------------------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
try {
ZRecur test = new ZRecur("FREQ=SECONDLY", tzmap);
System.out.println("\n\n" + test.toString() + "\n--------------------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
try {
ParsedDateTime myDtStart = ParsedDateTime.parse("16010101T020000", tzmap, tzUTC, tzUTC);
ZRecur test = new ZRecur("FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=12;BYDAY=-1SU", tzmap);
System.out.println("\n\n" + test.toString() + "\n--------------------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(myDtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
System.out.printf("%tc\n", cal);
}
} catch (ParseException e) {
System.out.println("Caught ParseException" + e);
e.printStackTrace();
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
cal.set(2010, 0, 1, 0, 0, 0);
rangeEnd = cal.getTime();
try {
ZRecur test = new ZRecur("FREQ=YEARLY;BYMONTH=12;BYDAY=1WE", tzmap);
System.out.println("\n\n" + test.toString() + "\n--------------------------------------------------------------");
List<Date> dateList = test.expandRecurrenceOverRange(dtStart, rangeStart.getTime(), rangeEnd.getTime());
for (Date d : dateList) {
cal.setTime(d);
System.out.printf("%tc\n", cal);
}
} catch (ServiceException e) {
System.out.println("Caught ServiceException" + e);
e.printStackTrace();
}
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class ZRecur method parse.
private void parse(String str, TimeZoneMap tzmap) throws ServiceException {
try {
int numByParts = 0;
for (String tok : str.split("\\s*;\\s*")) {
String[] s = tok.split("\\s*=\\s*");
if (s.length != 2) {
if (ZimbraLog.calendar.isDebugEnabled())
ZimbraLog.calendar.debug(new Formatter().format("Parse error for recur: \"%s\" at token \"%s\"", str, tok));
continue;
}
String rhs = s[1];
// MS Exchange can add invalid spaces in RRULE part values. Get rid of them. (see bug 25169)
rhs = rhs.replaceAll("\\s+", "");
try {
switch(Tokens.valueOf(s[0])) {
case FREQ:
mFreq = Frequency.valueOf(rhs);
break;
case UNTIL:
ParsedDateTime until = ParsedDateTime.parse(rhs, tzmap);
if (until != null) {
// be specified in an UTC time format."
if (until.hasTime())
until.toUTC();
mUntil = until;
}
break;
case COUNT:
mCount = Integer.parseInt(rhs);
break;
case INTERVAL:
mInterval = Integer.parseInt(rhs);
break;
case BYSECOND:
++numByParts;
parseIntList(rhs, mBySecondList, 0, 59, false);
break;
case BYMINUTE:
++numByParts;
parseIntList(rhs, mByMinuteList, 0, 59, false);
break;
case BYHOUR:
++numByParts;
parseIntList(rhs, mByHourList, 0, 23, false);
break;
case BYDAY:
++numByParts;
parseByDayList(rhs, mByDayList);
break;
case BYMONTHDAY:
++numByParts;
parseIntList(rhs, mByMonthDayList, -31, 31, true);
break;
case BYYEARDAY:
++numByParts;
parseIntList(rhs, mByYearDayList, -366, 366, true);
break;
case BYWEEKNO:
++numByParts;
parseIntList(rhs, mByWeekNoList, -53, 53, true);
break;
case BYMONTH:
++numByParts;
parseIntList(rhs, mByMonthList, 1, 12, false);
break;
case BYSETPOS:
++numByParts;
parseIntList(rhs, mBySetPosList, Integer.MIN_VALUE, Integer.MAX_VALUE, true);
break;
case WKST:
mWkSt = ZWeekDay.valueOf(rhs);
break;
}
} catch (IllegalArgumentException e) {
ZimbraLog.calendar.warn("Skipping RECUR token: \"%s\" in Recur \"%s\" due to parse error", s[0], str, e);
}
}
// 5) there is no other BYxxx part
if (numByParts == 2 && Frequency.MONTHLY.equals(mFreq) && mByDayList.size() == 1 && mByDayList.get(0).mOrdinal == 0 && mBySetPosList.size() == 1) {
mByDayList.get(0).mOrdinal = mBySetPosList.get(0);
mBySetPosList.clear();
}
} catch (ParseException e) {
throw ServiceException.FAILURE("Parse error for recur \"" + str + "\"", e);
}
}
Aggregations