Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Unified Diff: lib/src/intl/date_format_field.dart

Issue 932093004: Add loose parsing option for dates, accepting mixed case and missing delimiters (Closed) Base URL: https://github.com/dart-lang/intl.git@master
Patch Set: Fix test that wasn't checking for exception Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/src/intl/date_format.dart ('k') | pubspec.yaml » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/intl/date_format_field.dart
diff --git a/lib/src/intl/date_format_field.dart b/lib/src/intl/date_format_field.dart
index 47a9d7bcc4d85e4328c0c3dca254d941cff9120f..4b8b12e927d289e36f4de9dc8dbb06550b806fc1 100644
--- a/lib/src/intl/date_format_field.dart
+++ b/lib/src/intl/date_format_field.dart
@@ -39,6 +39,13 @@ abstract class _DateFormatField {
/** Abstract method for subclasses to implementing parsing for their format.*/
void parse(_Stream input, _DateBuilder dateFields);
+ /**
+ * Abstract method for subclasses to implementing 'loose' parsing for
+ * their format, accepting input case-insensitively, and allowing some
+ * delimiters to be skipped.
+ */
+ void parseLoose(_Stream input, _DateBuilder dateFields);
+
/** Parse a literal field. We just look for the exact input. */
void parseLiteral(_Stream input) {
var found = input.read(width);
@@ -47,6 +54,20 @@ abstract class _DateFormatField {
}
}
+ /**
+ * Parse a literal field. We accept either an exact match, or an arbitrary
+ * amount of whitespace.
+ */
+ void parseLiteralLoose(_Stream input) {
+ var found = input.peek(width);
+ if (found == pattern) {
+ input.read(width);
+ }
+ while (!input.atEnd() && input.peek().trim().isEmpty) {
+ input.read();
+ }
+ }
+
/** Throw a format exception with an error message indicating the position.*/
void throwFormatException(_Stream stream) {
throw new FormatException("Trying to read $this from ${stream.contents} "
@@ -64,8 +85,11 @@ class _DateFormatLiteralField extends _DateFormatField {
_DateFormatLiteralField(pattern, parent): super(pattern, parent);
parse(_Stream input, _DateBuilder dateFields) {
- return parseLiteral(input);
+ parseLiteral(input);
}
+
+ parseLoose(_Stream input, _DateBuilder dateFields) =>
+ parseLiteralLoose(input);
}
/**
@@ -84,9 +108,12 @@ class _DateFormatQuotedField extends _DateFormatField {
}
parse(_Stream input, _DateBuilder dateFields) {
- return parseLiteral(input);
+ parseLiteral(input);
}
+ parseLoose(_Stream input, _DateBuilder dateFields) =>
+ parseLiteralLoose(input);
+
void patchQuotes() {
if (pattern == "''") {
pattern = "'";
@@ -98,6 +125,110 @@ class _DateFormatQuotedField extends _DateFormatField {
}
}
+/**
+ * A field that parses "loosely", meaning that we'll accept input that is
+ * missing delimiters, has upper/lower case mixed up, and might not strictly
+ * conform to the pattern, e.g. the pattern calls for Sep we might accept
+ * sep, september, sEPTember. Doesn't affect numeric fields.
+ */
+class _LoosePatternField extends _DateFormatPatternField {
+ _LoosePatternField(String pattern, parent) : super(pattern, parent);
+
+ /**
+ * Parse from a list of possibilities, but case-insensitively.
+ * Assumes that input is lower case.
+ */
+ int parseEnumeratedString(_Stream input, List possibilities) {
+ var lowercasePossibilities = possibilities
+ .map((x) => x.toLowerCase())
+ .toList();
+ try {
+ return super.parseEnumeratedString(input, lowercasePossibilities);
+ } on FormatException {
+ return -1;
+ }
+ }
+
+ /**
+ * Parse a month name, case-insensitively, and set it in [dateFields].
+ * Assumes that [input] is lower case.
+ */
+ void parseMonth(input, dateFields) {
+ if (width <= 2) {
+ handleNumericField(input, dateFields.setMonth);
+ return;
+ }
+ var possibilities =
+ [symbols.MONTHS, symbols.SHORTMONTHS];
+ for (var monthNames in possibilities) {
+ var month = parseEnumeratedString(input, monthNames);
+ if (month != -1) {
+ dateFields.month = month + 1;
+ return;
+ }
+ }
+ }
+
+ /**
+ * Parse a standalone day name, case-insensitively.
+ * Assumes that input is lower case. Doesn't do anything
+ */
+ void parseStandaloneDay(input) {
+ // This is ignored, but we still have to skip over it the correct amount.
+ if (width <= 2) {
+ handleNumericField(input, (x) => x);
+ return;
+ }
+ var possibilities =
+ [symbols.STANDALONEWEEKDAYS, symbols.STANDALONESHORTWEEKDAYS];
+ for (var dayNames in possibilities) {
+ var day = parseEnumeratedString(input, dayNames);
+ if (day != -1) {
+ return;
+ }
+ }
+ }
+
+ /**
+ * Parse a standalone month name, case-insensitively.
+ * Assumes that input is lower case. Doesn't do anything
+ */
+ void parseStandaloneMonth(input, dateFields) {
+ if (width <= 2) {
+ handleNumericField(input, (x) => x);
+ return;
+ }
+ var possibilities =
+ [symbols.STANDALONEMONTHS, symbols.STANDALONESHORTMONTHS];
+ for (var monthNames in possibilities) {
+ var month = parseEnumeratedString(input, monthNames);
+ if (month != -1) {
+ dateFields.month = month + 1;
+ return;
+ }
+ }
+ }
+
+ /**
+ * Parse a day of the week name, case-insensitively.
+ * Assumes that input is lower case. Doesn't do anything
+ */
+ void parseDayOfWeek(_Stream input) {
+ // This is IGNORED, but we still have to skip over it the correct amount.
+ if (width <= 2) {
+ handleNumericField(input, (x) => x);
+ return;
+ }
+ var possibilities = [symbols.WEEKDAYS, symbols.SHORTWEEKDAYS];
+ for (var dayNames in possibilities) {
+ var day = parseEnumeratedString(input, dayNames);
+ if (day != -1) {
+ return;
+ }
+ }
+ }
+}
+
/*
* Represents a field in the pattern that formats some aspect of the
* date. Consists primarily of a switch on the particular pattern characters
@@ -120,6 +251,16 @@ class _DateFormatPatternField extends _DateFormatField {
parseField(input, dateFields);
}
+
+ /**
+ * Parse the date according to our specification and put the result
+ * into the correct place in dateFields. Allow looser parsing, accepting
+ * case-insensitive input and skipped delimiters.
+ */
+ void parseLoose(_Stream input, _DateBuilder dateFields) {
+ new _LoosePatternField(pattern, parent).parse(input, dateFields);
+ }
+
/**
* Parse a field representing part of a date pattern. Note that we do not
* return a value, but rather build up the result in [builder].
« no previous file with comments | « lib/src/intl/date_format.dart ('k') | pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698