Issue 1417 support VEVENT DURATION property

git-svn-id: https://zxing.googlecode.com/svn/trunk@2480 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2012-10-24 17:07:52 +00:00
parent e6098ea320
commit eb2d89301f
3 changed files with 62 additions and 1 deletions

View file

@ -24,6 +24,7 @@ import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.Locale; import java.util.Locale;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
@ -31,6 +32,16 @@ import java.util.regex.Pattern;
*/ */
public final class CalendarParsedResult extends ParsedResult { public final class CalendarParsedResult extends ParsedResult {
private static final Pattern RFC2445_DURATION =
Pattern.compile("P(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?");
private static final long[] RFC2445_DURATION_FIELD_UNITS = {
7 * 24 * 60 * 60 * 1000L, // 1 week
24 * 60 * 60 * 1000L, // 1 day
60 * 60 * 1000L, // 1 hour
60 * 1000L, // 1 minute
1000L, // 1 second
};
private static final Pattern DATE_TIME = Pattern.compile("[0-9]{8}(T[0-9]{6}Z?)?"); private static final Pattern DATE_TIME = Pattern.compile("[0-9]{8}(T[0-9]{6}Z?)?");
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH); private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
@ -57,6 +68,7 @@ public final class CalendarParsedResult extends ParsedResult {
public CalendarParsedResult(String summary, public CalendarParsedResult(String summary,
String startString, String startString,
String endString, String endString,
String durationString,
String location, String location,
String organizer, String organizer,
String[] attendees, String[] attendees,
@ -65,14 +77,27 @@ public final class CalendarParsedResult extends ParsedResult {
double longitude) { double longitude) {
super(ParsedResultType.CALENDAR); super(ParsedResultType.CALENDAR);
this.summary = summary; this.summary = summary;
try { try {
this.start = parseDate(startString); this.start = parseDate(startString);
this.end = endString == null ? null : parseDate(endString);
} catch (ParseException pe) { } catch (ParseException pe) {
throw new IllegalArgumentException(pe.toString()); throw new IllegalArgumentException(pe.toString());
} }
if (endString == null) {
long durationMS = parseDurationMS(durationString);
end = durationMS < 0L ? null : new Date(start.getTime() + durationMS);
} else {
try {
this.end = parseDate(endString);
} catch (ParseException pe) {
throw new IllegalArgumentException(pe.toString());
}
}
this.startAllDay = startString.length() == 8; this.startAllDay = startString.length() == 8;
this.endAllDay = endString != null && endString.length() == 8; this.endAllDay = endString != null && endString.length() == 8;
this.location = location; this.location = location;
this.organizer = organizer; this.organizer = organizer;
this.attendees = attendees; this.attendees = attendees;
@ -196,4 +221,22 @@ public final class CalendarParsedResult extends ParsedResult {
return format.format(date); return format.format(date);
} }
private static long parseDurationMS(CharSequence durationString) {
if (durationString == null) {
return -1L;
}
Matcher m = RFC2445_DURATION.matcher(durationString);
if (!m.matches()) {
return -1L;
}
long durationMS = 0L;
for (int i = 0; i < RFC2445_DURATION_FIELD_UNITS.length; i++) {
String fieldValue = m.group(i + 1);
if (fieldValue != null) {
durationMS += RFC2445_DURATION_FIELD_UNITS[i] * Integer.parseInt(fieldValue);
}
}
return durationMS;
}
} }

View file

@ -42,6 +42,7 @@ public final class VEventResultParser extends ResultParser {
return null; return null;
} }
String end = matchSingleVCardPrefixedField("DTEND", rawText, true); String end = matchSingleVCardPrefixedField("DTEND", rawText, true);
String duration = matchSingleVCardPrefixedField("DURATION", rawText, true);
String location = matchSingleVCardPrefixedField("LOCATION", rawText, true); String location = matchSingleVCardPrefixedField("LOCATION", rawText, true);
String organizer = stripMailto(matchSingleVCardPrefixedField("ORGANIZER", rawText, true)); String organizer = stripMailto(matchSingleVCardPrefixedField("ORGANIZER", rawText, true));
@ -73,6 +74,7 @@ public final class VEventResultParser extends ResultParser {
return new CalendarParsedResult(summary, return new CalendarParsedResult(summary,
start, start,
end, end,
duration,
location, location,
organizer, organizer,
attendees, attendees,

View file

@ -77,6 +77,22 @@ public final class CalendarParsedResultTestCase extends Assert {
null, null, null, "20080504T123456Z", null); null, null, null, "20080504T123456Z", null);
} }
@Test
public void testDuration() {
doTest(
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
"DTSTART:20080504T123456Z\r\n" +
"DURATION:P1D\r\n" +
"END:VEVENT\r\nEND:VCALENDAR",
null, null, null, "20080504T123456Z", "20080505T123456Z");
doTest(
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
"DTSTART:20080504T123456Z\r\n" +
"DURATION:P1DT2H3M4S\r\n" +
"END:VEVENT\r\nEND:VCALENDAR",
null, null, null, "20080504T123456Z", "20080505T143800Z");
}
@Test @Test
public void testSummary() { public void testSummary() {
doTest( doTest(