Consolidate date parsing for calendar events. Use human readable dates in app display. Probably haven't broken anything.

git-svn-id: https://zxing.googlecode.com/svn/trunk@2336 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2012-06-29 17:40:55 +00:00
parent b3f03373c2
commit 07c8b8282e
7 changed files with 192 additions and 178 deletions

View file

@ -67,7 +67,8 @@ public final class HistoryManager {
private static final String[] ID_COL_PROJECTION = { DBHelper.ID_COL }; private static final String[] ID_COL_PROJECTION = { DBHelper.ID_COL };
private static final String[] ID_DETAIL_COL_PROJECTION = { DBHelper.ID_COL, DBHelper.DETAILS_COL }; private static final String[] ID_DETAIL_COL_PROJECTION = { DBHelper.ID_COL, DBHelper.DETAILS_COL };
private static final DateFormat EXPORT_DATE_TIME_FORMAT = DateFormat.getDateTimeInstance(); private static final DateFormat EXPORT_DATE_TIME_FORMAT =
DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
private final Activity activity; private final Activity activity;

View file

@ -27,7 +27,7 @@ import android.text.SpannableString;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.ParsePosition; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
@ -45,6 +45,12 @@ public final class AddressBookResultHandler extends ResultHandler {
new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH), new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH),
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH), new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH),
}; };
static {
for (DateFormat format : DATE_FORMATS) {
format.setLenient(false);
}
}
private static final int[] BUTTON_TEXTS = { private static final int[] BUTTON_TEXTS = {
R.string.button_add_contact, R.string.button_add_contact,
R.string.button_show_map, R.string.button_show_map,
@ -148,13 +154,11 @@ public final class AddressBookResultHandler extends ResultHandler {
} }
private static Date parseDate(String s) { private static Date parseDate(String s) {
for (DateFormat currentFomat : DATE_FORMATS) { for (DateFormat currentFormat : DATE_FORMATS) {
synchronized (currentFomat) { try {
currentFomat.setLenient(false); return currentFormat.parse(s);
Date result = currentFomat.parse(s, new ParsePosition(0)); } catch (ParseException e) {
if (result != null) { // continue
return result;
}
} }
} }
return null; return null;
@ -191,7 +195,7 @@ public final class AddressBookResultHandler extends ResultHandler {
if (birthday != null && birthday.length() > 0) { if (birthday != null && birthday.length() > 0) {
Date date = parseDate(birthday); Date date = parseDate(birthday);
if (date != null) { if (date != null) {
ParsedResult.maybeAppend(DateFormat.getDateInstance().format(date.getTime()), contents); ParsedResult.maybeAppend(DateFormat.getDateInstance(DateFormat.MEDIUM).format(date.getTime()), contents);
} }
} }
ParsedResult.maybeAppend(result.getNote(), contents); ParsedResult.maybeAppend(result.getNote(), contents);

View file

@ -23,23 +23,16 @@ import com.google.zxing.client.result.ParsedResult;
import android.app.Activity; import android.app.Activity;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
/** /**
* Handles calendar entries encoded in QR Codes. * Handles calendar entries encoded in QR Codes.
* *
* @author dswitkin@google.com (Daniel Switkin) * @author dswitkin@google.com (Daniel Switkin)
* @author Sean Owen
*/ */
public final class CalendarResultHandler extends ResultHandler { public final class CalendarResultHandler extends ResultHandler {
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
private static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH);
private static final int[] buttons = { private static final int[] buttons = {
R.string.button_add_calendar R.string.button_add_calendar
}; };
@ -64,6 +57,7 @@ public final class CalendarResultHandler extends ResultHandler {
if (index == 0) { if (index == 0) {
addCalendarEvent(calendarResult.getSummary(), addCalendarEvent(calendarResult.getSummary(),
calendarResult.getStart(), calendarResult.getStart(),
calendarResult.isStartAllDay(),
calendarResult.getEnd(), calendarResult.getEnd(),
calendarResult.getLocation(), calendarResult.getLocation(),
calendarResult.getDescription()); calendarResult.getDescription());
@ -72,16 +66,25 @@ public final class CalendarResultHandler extends ResultHandler {
@Override @Override
public CharSequence getDisplayContents() { public CharSequence getDisplayContents() {
CalendarParsedResult calResult = (CalendarParsedResult) getResult(); CalendarParsedResult calResult = (CalendarParsedResult) getResult();
StringBuilder result = new StringBuilder(100); StringBuilder result = new StringBuilder(100);
ParsedResult.maybeAppend(calResult.getSummary(), result);
String startString = calResult.getStart();
appendTime(startString, result, false, false);
String endString = calResult.getEnd(); ParsedResult.maybeAppend(calResult.getSummary(), result);
if (endString != null) {
boolean sameStartEnd = startString.equals(endString); Date start = calResult.getStart();
appendTime(endString, result, true, sameStartEnd); ParsedResult.maybeAppend(format(calResult.isStartAllDay(), start), result);
Date end = calResult.getEnd();
if (end != null) {
if (calResult.isEndAllDay() && !start.equals(end)) {
// Show only year/month/day
// if it's all-day and this is the end date, it's exclusive, so show the user
// that it ends on the day before to make more intuitive sense.
// But don't do it if the event already (incorrectly?) specifies the same start/end
end = new Date(end.getTime() - 24 * 60 * 60 * 1000);
}
ParsedResult.maybeAppend(format(calResult.isEndAllDay(), end), result);
} }
ParsedResult.maybeAppend(calResult.getLocation(), result); ParsedResult.maybeAppend(calResult.getLocation(), result);
@ -90,38 +93,14 @@ public final class CalendarResultHandler extends ResultHandler {
return result.toString(); return result.toString();
} }
private static void appendTime(String when, StringBuilder result, boolean end, boolean sameStartEnd) { private static String format(boolean allDay, Date date) {
if (when.length() == 8) { if (date == null) {
// Show only year/month/day return null;
Date date;
synchronized (DATE_FORMAT) {
date = DATE_FORMAT.parse(when, new ParsePosition(0));
}
// if it's all-day and this is the end date, it's exclusive, so show the user
// that it ends on the day before to make more intuitive sense.
// But don't do it if the event already (incorrectly?) specifies the same start/end
if (end && !sameStartEnd) {
date = new Date(date.getTime() - 24 * 60 * 60 * 1000);
}
ParsedResult.maybeAppend(DateFormat.getDateInstance().format(date.getTime()), result);
} else {
// The when string can be local time, or UTC if it ends with a Z
Date date;
synchronized (DATE_TIME_FORMAT) {
date = DATE_TIME_FORMAT.parse(when.substring(0, 15), new ParsePosition(0));
}
long milliseconds = date.getTime();
if (when.length() == 16 && when.charAt(15) == 'Z') {
Calendar calendar = new GregorianCalendar();
// Account for time zone difference
milliseconds += calendar.get(Calendar.ZONE_OFFSET);
// Might need to correct for daylight savings time, but use target time since
// now might be in DST but not then, or vice versa
calendar.setTime(new Date(milliseconds));
milliseconds += calendar.get(Calendar.DST_OFFSET);
}
ParsedResult.maybeAppend(DateFormat.getDateTimeInstance().format(milliseconds), result);
} }
DateFormat format = allDay
? DateFormat.getDateInstance(DateFormat.MEDIUM)
: DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
return format.format(date);
} }
@Override @Override

View file

@ -41,15 +41,9 @@ import android.provider.ContactsContract;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale; import java.util.Locale;
import java.util.TimeZone;
/** /**
* A base class for the Android-specific barcode handlers. These allow the app to polymorphically * A base class for the Android-specific barcode handlers. These allow the app to polymorphically
@ -60,21 +54,12 @@ import java.util.TimeZone;
* instance is needed to launch an intent. * instance is needed to launch an intent.
* *
* @author dswitkin@google.com (Daniel Switkin) * @author dswitkin@google.com (Daniel Switkin)
* @author Sean Owen
*/ */
public abstract class ResultHandler { public abstract class ResultHandler {
private static final String TAG = ResultHandler.class.getSimpleName(); private static final String TAG = ResultHandler.class.getSimpleName();
private static final DateFormat DATE_FORMAT;
static {
DATE_FORMAT = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
// For dates without a time, for purposes of interacting with Android, the resulting timestamp
// needs to be midnight of that day in GMT. See:
// http://code.google.com/p/android/issues/detail?id=8330
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
}
private static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH);
private static final String GOOGLE_SHOPPER_PACKAGE = "com.google.android.apps.shopper"; private static final String GOOGLE_SHOPPER_PACKAGE = "com.google.android.apps.shopper";
private static final String GOOGLE_SHOPPER_ACTIVITY = GOOGLE_SHOPPER_PACKAGE + private static final String GOOGLE_SHOPPER_ACTIVITY = GOOGLE_SHOPPER_PACKAGE +
".results.SearchResultsActivity"; ".results.SearchResultsActivity";
@ -223,21 +208,22 @@ public abstract class ResultHandler {
* versions of the system have a bug where the event title will not be filled out. * versions of the system have a bug where the event title will not be filled out.
* *
* @param summary A description of the event * @param summary A description of the event
* @param start The start time as yyyyMMdd or yyyyMMdd'T'HHmmss or yyyyMMdd'T'HHmmss'Z' * @param start The start time
* @param end The end time as yyyyMMdd or yyyyMMdd'T'HHmmss or yyyyMMdd'T'HHmmss'Z' * @param allDay if true, event is considered to be all day starting from start time
* @param end The end time (optional)
* @param location a text description of the event location * @param location a text description of the event location
* @param description a text description of the event itself * @param description a text description of the event itself
*/ */
final void addCalendarEvent(String summary, final void addCalendarEvent(String summary,
String start, Date start,
String end, boolean allDay,
Date end,
String location, String location,
String description) { String description) {
Intent intent = new Intent(Intent.ACTION_EDIT); Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setType("vnd.android.cursor.item/event"); intent.setType("vnd.android.cursor.item/event");
long startMilliseconds = calculateMilliseconds(start); long startMilliseconds = start.getTime();
intent.putExtra("beginTime", startMilliseconds); intent.putExtra("beginTime", startMilliseconds);
boolean allDay = start.length() == 8;
if (allDay) { if (allDay) {
intent.putExtra("allDay", true); intent.putExtra("allDay", true);
} }
@ -250,7 +236,7 @@ public abstract class ResultHandler {
endMilliseconds = startMilliseconds; endMilliseconds = startMilliseconds;
} }
} else { } else {
endMilliseconds = calculateMilliseconds(end); endMilliseconds = end.getTime();
} }
intent.putExtra("endTime", endMilliseconds); intent.putExtra("endTime", endMilliseconds);
intent.putExtra("title", summary); intent.putExtra("title", summary);
@ -259,31 +245,6 @@ public abstract class ResultHandler {
launchIntent(intent); launchIntent(intent);
} }
private static long calculateMilliseconds(String when) {
if (when.length() == 8) {
// Only contains year/month/day
Date date;
synchronized (DATE_FORMAT) {
date = DATE_FORMAT.parse(when, new ParsePosition(0));
}
// Note this will be relative to GMT, not the local time zone
return date.getTime();
} else {
// The when string can be local time, or UTC if it ends with a Z
Date date;
synchronized (DATE_TIME_FORMAT) {
date = DATE_TIME_FORMAT.parse(when.substring(0, 15), new ParsePosition(0));
}
long milliseconds = date.getTime();
if (when.length() == 16 && when.charAt(15) == 'Z') {
Calendar calendar = new GregorianCalendar();
int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
milliseconds += offset;
}
return milliseconds;
}
}
final void addPhoneOnlyContact(String[] phoneNumbers,String[] phoneTypes) { final void addPhoneOnlyContact(String[] phoneNumbers,String[] phoneTypes) {
addContact(null, null, phoneNumbers, phoneTypes, null, null, null, null, null, null, null, null, null, null); addContact(null, null, phoneNumbers, phoneTypes, null, null, null, null, null, null, null, null, null, null);
} }
@ -495,7 +456,12 @@ public abstract class ResultHandler {
} }
final void openURL(String url) { final void openURL(String url) {
launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
try {
launchIntent(intent);
} catch (ActivityNotFoundException anfe) {
Log.w(TAG, "Nothing available to handle " + intent);
}
} }
final void webSearch(String query) { final void webSearch(String query) {

View file

@ -16,14 +16,37 @@
package com.google.zxing.client.result; package com.google.zxing.client.result;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Pattern;
/** /**
* @author Sean Owen * @author Sean Owen
*/ */
public final class CalendarParsedResult extends ParsedResult { public final class CalendarParsedResult extends ParsedResult {
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);
static {
// For dates without a time, for purposes of interacting with Android, the resulting timestamp
// needs to be midnight of that day in GMT. See:
// http://code.google.com/p/android/issues/detail?id=8330
DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
}
private static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH);
private final String summary; private final String summary;
private final String start; private final Date start;
private final String end; private final boolean startAllDay;
private final Date end;
private final boolean endAllDay;
private final String location; private final String location;
private final String attendee; private final String attendee;
private final String description; private final String description;
@ -31,32 +54,23 @@ public final class CalendarParsedResult extends ParsedResult {
private final double longitude; private final double longitude;
public CalendarParsedResult(String summary, public CalendarParsedResult(String summary,
String start, String startString,
String end, String endString,
String location,
String attendee,
String description) {
this(summary, start, end, location, attendee, description, Double.NaN, Double.NaN);
}
public CalendarParsedResult(String summary,
String start,
String end,
String location, String location,
String attendee, String attendee,
String description, String description,
double latitude, double latitude,
double longitude) { double longitude) {
super(ParsedResultType.CALENDAR); super(ParsedResultType.CALENDAR);
validateDate(start);
this.summary = summary; this.summary = summary;
this.start = start; try {
if (end != null) { this.start = parseDate(startString);
validateDate(end); this.end = endString == null ? null : parseDate(endString);
this.end = end; } catch (ParseException pe) {
} else { throw new IllegalArgumentException(pe.toString());
this.end = null;
} }
this.startAllDay = startString.length() == 8;
this.endAllDay = endString != null && endString.length() == 8;
this.location = location; this.location = location;
this.attendee = attendee; this.attendee = attendee;
this.description = description; this.description = description;
@ -69,23 +83,34 @@ public final class CalendarParsedResult extends ParsedResult {
} }
/** /**
* <p>We would return the start and end date as a {@link java.util.Date} except that this code * @return start time
* needs to work under JavaME / MIDP and there is no date parsing library available there, such
* as {@code java.text.SimpleDateFormat}.</p> See validateDate() for the return format.
*
* @return start time formatted as a RFC 2445 DATE or DATE-TIME.</p>
*/ */
public String getStart() { public Date getStart() {
return start; return start;
} }
/** /**
* @see #getStart(). May return null if the event has no duration. * @return true if start time was specified as a whole day
*/ */
public String getEnd() { public boolean isStartAllDay() {
return startAllDay;
}
/**
* May return null if the event has no duration.
* @see #getStart()
*/
public Date getEnd() {
return end; return end;
} }
/**
* @return true if end time was specified as a whole day
*/
public boolean isEndAllDay() {
return endAllDay;
}
public String getLocation() { public String getLocation() {
return location; return location;
} }
@ -110,8 +135,8 @@ public final class CalendarParsedResult extends ParsedResult {
public String getDisplayResult() { public String getDisplayResult() {
StringBuilder result = new StringBuilder(100); StringBuilder result = new StringBuilder(100);
maybeAppend(summary, result); maybeAppend(summary, result);
maybeAppend(start, result); maybeAppend(format(startAllDay, start), result);
maybeAppend(end, result); maybeAppend(format(endAllDay, end), result);
maybeAppend(location, result); maybeAppend(location, result);
maybeAppend(attendee, result); maybeAppend(attendee, result);
maybeAppend(description, result); maybeAppend(description, result);
@ -119,36 +144,48 @@ public final class CalendarParsedResult extends ParsedResult {
} }
/** /**
* RFC 2445 allows the start and end fields to be of type DATE (e.g. 20081021) or DATE-TIME * Parses a string as a date. RFC 2445 allows the start and end fields to be of type DATE (e.g. 20081021)
* (e.g. 20081021T123000 for local time, or 20081021T123000Z for UTC). * or DATE-TIME (e.g. 20081021T123000 for local time, or 20081021T123000Z for UTC).
* *
* @param date The string to validate * @param when The string to parse
* @throws ParseException if not able to parse as a date
*/ */
private static void validateDate(CharSequence date) { private static Date parseDate(String when) throws ParseException {
if (date != null) { if (!DATE_TIME.matcher(when).matches()) {
int length = date.length(); throw new ParseException(when, 0);
if (length != 8 && length != 15 && length != 16) { }
throw new IllegalArgumentException(); if (when.length() == 8) {
} // Show only year/month/day
for (int i = 0; i < 8; i++) { return DATE_FORMAT.parse(when);
if (!Character.isDigit(date.charAt(i))) { } else {
throw new IllegalArgumentException(); // The when string can be local time, or UTC if it ends with a Z
} Date date;
} if (when.length() == 16 && when.charAt(15) == 'Z') {
if (length > 8) { date = DATE_TIME_FORMAT.parse(when.substring(0, 15));
if (date.charAt(8) != 'T') { Calendar calendar = new GregorianCalendar();
throw new IllegalArgumentException(); long milliseconds = date.getTime();
} // Account for time zone difference
for (int i = 9; i < 15; i++) { milliseconds += calendar.get(Calendar.ZONE_OFFSET);
if (!Character.isDigit(date.charAt(i))) { // Might need to correct for daylight savings time, but use target time since
throw new IllegalArgumentException(); // now might be in DST but not then, or vice versa
} calendar.setTime(new Date(milliseconds));
} milliseconds += calendar.get(Calendar.DST_OFFSET);
if (length == 16 && date.charAt(15) != 'Z') { date = new Date(milliseconds);
throw new IllegalArgumentException(); } else {
} date = DATE_TIME_FORMAT.parse(when);
} }
return date;
} }
} }
private static String format(boolean allDay, Date date) {
if (date == null) {
return null;
}
DateFormat format = allDay
? DateFormat.getDateInstance(DateFormat.MEDIUM)
: DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
return format.format(date);
}
} }

View file

@ -19,8 +19,14 @@ package com.google.zxing.client.result;
import com.google.zxing.BarcodeFormat; import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result; import com.google.zxing.Result;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.TimeZone;
/** /**
* Tests {@link CalendarParsedResult}. * Tests {@link CalendarParsedResult}.
* *
@ -30,6 +36,17 @@ public final class CalendarParsedResultTestCase extends Assert {
private static final double EPSILON = 0.0000000001; private static final double EPSILON = 0.0000000001;
private static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.ENGLISH);
static {
DATE_TIME_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
}
@Before
public void setUp() {
Locale.setDefault(Locale.ENGLISH);
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
}
@Test @Test
public void testStartEnd() { public void testStartEnd() {
doTest( doTest(
@ -125,8 +142,8 @@ public final class CalendarParsedResultTestCase extends Assert {
"Meeting with a friend\nlook at homepage first\n\n\n \n", "Meeting with a friend\nlook at homepage first\n\n\n \n",
"Summary line", "Summary line",
"Location, with, escaped, commas", "Location, with, escaped, commas",
"20111110T110000", "20111110T110000Z",
"20111110T120000"); "20111110T120000Z");
} }
@Test @Test
@ -135,24 +152,24 @@ public final class CalendarParsedResultTestCase extends Assert {
"DTSTART;VALUE=DATE:20111110\n" + "DTSTART;VALUE=DATE:20111110\n" +
"DTEND;VALUE=DATE:20111110\n" + "DTEND;VALUE=DATE:20111110\n" +
"END:VEVENT", "END:VEVENT",
null, null, null, "20111110", "20111110"); null, null, null, "20111110T000000Z", "20111110T000000Z");
} }
private static void doTest(String contents, private static void doTest(String contents,
String description, String description,
String summary, String summary,
String location, String location,
String start, String startString,
String end) { String endString) {
doTest(contents, description, summary, location, start, end, null, Double.NaN, Double.NaN); doTest(contents, description, summary, location, startString, endString, null, Double.NaN, Double.NaN);
} }
private static void doTest(String contents, private static void doTest(String contents,
String description, String description,
String summary, String summary,
String location, String location,
String start, String startString,
String end, String endString,
String attendee, String attendee,
double latitude, double latitude,
double longitude) { double longitude) {
@ -163,8 +180,8 @@ public final class CalendarParsedResultTestCase extends Assert {
assertEquals(description, calResult.getDescription()); assertEquals(description, calResult.getDescription());
assertEquals(summary, calResult.getSummary()); assertEquals(summary, calResult.getSummary());
assertEquals(location, calResult.getLocation()); assertEquals(location, calResult.getLocation());
assertEquals(start, calResult.getStart()); assertEquals(startString, DATE_TIME_FORMAT.format(calResult.getStart()));
assertEquals(end, calResult.getEnd()); assertEquals(endString, calResult.getEnd() == null ? null : DATE_TIME_FORMAT.format(calResult.getEnd()));
assertEquals(attendee, calResult.getAttendee()); assertEquals(attendee, calResult.getAttendee());
assertEqualOrNaN(latitude, calResult.getLatitude()); assertEqualOrNaN(latitude, calResult.getLatitude());
assertEqualOrNaN(longitude, calResult.getLongitude()); assertEqualOrNaN(longitude, calResult.getLongitude());

View file

@ -19,8 +19,12 @@ package com.google.zxing.client.result;
import com.google.zxing.BarcodeFormat; import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result; import com.google.zxing.Result;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.util.Locale;
import java.util.TimeZone;
/** /**
* Tests {@link ParsedResult}. * Tests {@link ParsedResult}.
* *
@ -29,6 +33,12 @@ import org.junit.Test;
*/ */
public final class ParsedReaderResultTestCase extends Assert { public final class ParsedReaderResultTestCase extends Assert {
@Before
public void setUp() {
Locale.setDefault(Locale.ENGLISH);
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
}
@Test @Test
public void testTextType() { public void testTextType() {
doTestResult("", "", ParsedResultType.TEXT); doTestResult("", "", ParsedResultType.TEXT);
@ -203,25 +213,25 @@ public final class ParsedReaderResultTestCase extends Assert {
// UTC times // UTC times
doTestResult("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456Z\r\n" + doTestResult("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456Z\r\n" +
"DTEND:20080505T234555Z\r\nEND:VEVENT\r\nEND:VCALENDAR", "DTEND:20080505T234555Z\r\nEND:VEVENT\r\nEND:VCALENDAR",
"foo\n20080504T123456Z\n20080505T234555Z", "foo\nMay 4, 2008 12:34:56 PM\nMay 5, 2008 11:45:55 PM",
ParsedResultType.CALENDAR); ParsedResultType.CALENDAR);
doTestResult("BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456Z\r\n" + doTestResult("BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456Z\r\n" +
"DTEND:20080505T234555Z\r\nEND:VEVENT", "foo\n20080504T123456Z\n20080505T234555Z", "DTEND:20080505T234555Z\r\nEND:VEVENT", "foo\nMay 4, 2008 12:34:56 PM\nMay 5, 2008 11:45:55 PM",
ParsedResultType.CALENDAR); ParsedResultType.CALENDAR);
// Local times // Local times
doTestResult("BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456\r\n" + doTestResult("BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456\r\n" +
"DTEND:20080505T234555\r\nEND:VEVENT", "foo\n20080504T123456\n20080505T234555", "DTEND:20080505T234555\r\nEND:VEVENT", "foo\nMay 4, 2008 12:34:56 PM\nMay 5, 2008 11:45:55 PM",
ParsedResultType.CALENDAR); ParsedResultType.CALENDAR);
// Date only (all day event) // Date only (all day event)
doTestResult("BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504\r\n" + doTestResult("BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504\r\n" +
"DTEND:20080505\r\nEND:VEVENT", "foo\n20080504\n20080505", ParsedResultType.CALENDAR); "DTEND:20080505\r\nEND:VEVENT", "foo\nMay 4, 2008\nMay 5, 2008", ParsedResultType.CALENDAR);
// Start time only // Start time only
doTestResult("BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456Z\r\nEND:VEVENT", doTestResult("BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456Z\r\nEND:VEVENT",
"foo\n20080504T123456Z", ParsedResultType.CALENDAR); "foo\nMay 4, 2008 12:34:56 PM", ParsedResultType.CALENDAR);
doTestResult("BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456\r\nEND:VEVENT", doTestResult("BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456\r\nEND:VEVENT",
"foo\n20080504T123456", ParsedResultType.CALENDAR); "foo\nMay 4, 2008 12:34:56 PM", ParsedResultType.CALENDAR);
doTestResult("BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504\r\nEND:VEVENT", doTestResult("BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504\r\nEND:VEVENT",
"foo\n20080504", ParsedResultType.CALENDAR); "foo\nMay 4, 2008", ParsedResultType.CALENDAR);
doTestResult("BEGIN:VEVENT\r\nDTEND:20080505T\r\nEND:VEVENT", doTestResult("BEGIN:VEVENT\r\nDTEND:20080505T\r\nEND:VEVENT",
"BEGIN:VEVENT\r\nDTEND:20080505T\r\nEND:VEVENT", ParsedResultType.URI); "BEGIN:VEVENT\r\nDTEND:20080505T\r\nEND:VEVENT", ParsedResultType.URI);
// Yeah, it's OK that this is thought of as maybe a URI as long as it's not CALENDAR // Yeah, it's OK that this is thought of as maybe a URI as long as it's not CALENDAR