diff options
author | Artur Signell <artur.signell@itmill.com> | 2010-08-24 11:37:36 +0000 |
---|---|---|
committer | Artur Signell <artur.signell@itmill.com> | 2010-08-24 11:37:36 +0000 |
commit | 7a192a8d5f643e51837ad2ce4cba91a29c343e9d (patch) | |
tree | 095e106e66db3e46133d4f8f9ca940c8438e47af | |
parent | 3b1c8515a708760cce1bf0ce24a1a0e7262eeca6 (diff) | |
download | vaadin-framework-7a192a8d5f643e51837ad2ce4cba91a29c343e9d.tar.gz vaadin-framework-7a192a8d5f643e51837ad2ce4cba91a29c343e9d.zip |
Fix for #5474 - DateField fails to parse month names when using custom date format
svn changeset:14577/svn branch:6.4
-rw-r--r-- | src/com/vaadin/terminal/gwt/client/DateTimeService.java | 141 | ||||
-rw-r--r-- | src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java | 78 |
2 files changed, 157 insertions, 62 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/DateTimeService.java b/src/com/vaadin/terminal/gwt/client/DateTimeService.java index f572411a83..b307eaf737 100644 --- a/src/com/vaadin/terminal/gwt/client/DateTimeService.java +++ b/src/com/vaadin/terminal/gwt/client/DateTimeService.java @@ -6,6 +6,8 @@ package com.vaadin.terminal.gwt.client; import java.util.Date;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.i18n.client.LocaleInfo;
import com.vaadin.terminal.gwt.client.ui.VDateField;
/**
@@ -272,4 +274,143 @@ public class DateTimeService { return weekNumber;
}
+ /**
+ * Check if format contains the month name. If it does we manually convert
+ * it to the month name since DateTimeFormat.format always uses the current
+ * locale and will replace the month name wrong if current locale is
+ * different from the locale set for the DateField.
+ *
+ * MMMM is converted into long month name, MMM is converted into short month
+ * name. '' are added around the name to avoid that DateTimeFormat parses
+ * the month name as a pattern.
+ *
+ * @param date
+ * The date to convert
+ * @param formatStr
+ * The format string that might contain MMM or MMMM
+ * @param dateTimeService
+ * Reference to the Vaadin DateTimeService
+ * @return
+ */
+ public String formatDate(Date date, String formatStr) {
+ /*
+ * Format month names separately when locale for the DateTimeService is
+ * not the same as the browser locale
+ */
+ formatStr = formatMonthNames(date, formatStr);
+
+ // Format uses the browser locale
+ DateTimeFormat format = DateTimeFormat.getFormat(formatStr);
+
+ String result = format.format(date);
+
+ return result;
+ }
+
+ private String formatMonthNames(Date date, String formatStr) {
+ if (formatStr.contains("MMMM")) {
+ @SuppressWarnings("deprecation")
+ String monthName = getMonth(date.getMonth());
+
+ if (monthName != null) {
+ formatStr = formatStr.replaceAll("[M]{4,}", "'" + monthName
+ + "'");
+ }
+ }
+
+ if (formatStr.contains("MMM")) {
+
+ @SuppressWarnings("deprecation")
+ String monthName = getShortMonth(date.getMonth());
+
+ if (monthName != null) {
+ formatStr = formatStr.replaceAll("[M]{3,}", "'" + monthName
+ + "'");
+ }
+ }
+
+ return formatStr;
+ }
+
+ /**
+ * Replaces month names in the entered date Parses the month name from the
+ * entered dat
+ *
+ * @param enteredDate
+ * @param formatString
+ * @return
+ */
+ private String parseMonthName(String enteredDate, String formatString) {
+ LocaleInfo browserLocale = LocaleInfo.getCurrentLocale();
+ if (browserLocale.getLocaleName().equals(getLocale())) {
+ // No conversion needs to be done when locales match
+ return enteredDate;
+ }
+ String[] browserMonthNames = browserLocale.getDateTimeConstants()
+ .months();
+ String[] browserShortMonthNames = browserLocale.getDateTimeConstants()
+ .shortMonths();
+
+ if (formatString.contains("MMMM")) {
+ // Full month name
+ for (int i = 0; i < 12; i++) {
+ enteredDate = enteredDate.replaceAll(getMonth(i),
+ browserMonthNames[i]);
+ }
+ }
+ if (formatString.contains("MMM")) {
+ // Short month name
+ for (int i = 0; i < 12; i++) {
+ enteredDate = enteredDate.replaceAll(getShortMonth(i),
+ browserShortMonthNames[i]);
+ }
+ }
+
+ return enteredDate;
+ }
+
+ /**
+ * Parses the given date string using the given format string and the locale
+ * set in this DateTimeService instance.
+ *
+ * @param dateString
+ * Date string e.g. "1 February 2010"
+ * @param formatString
+ * Format string e.g. "d MMMM yyyy"
+ * @param lenient
+ * true to use lenient parsing, false to use strict parsing
+ * @return A Date object representing the dateString. Never returns null.
+ * @throws IllegalArgumentException
+ * if the parsing fails
+ *
+ */
+ public Date parseDate(String dateString, String formatString,
+ boolean lenient) throws IllegalArgumentException {
+ /* DateTimeFormat uses the browser's locale */
+ DateTimeFormat format = DateTimeFormat.getFormat(formatString);
+
+ /*
+ * Parse month names separately when locale for the DateTimeService is
+ * not the same as the browser locale
+ */
+ dateString = parseMonthName(dateString, formatString);
+
+ Date date;
+
+ if (lenient) {
+ date = format.parse(dateString);
+ } else {
+ date = format.parseStrict(dateString);
+ }
+
+ // Some version of Firefox sets the timestamp to 0 if parsing fails.
+ if (date != null && date.getTime() == 0) {
+ throw new IllegalArgumentException("Parsing of '" + dateString
+ + "' failed");
+ }
+
+ return date;
+
+ }
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java b/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java index fd32cf7ad3..da5292571b 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java @@ -12,7 +12,6 @@ import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.FocusEvent; import com.google.gwt.event.dom.client.FocusHandler; -import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.ui.TextBox; import com.vaadin.terminal.gwt.client.ApplicationConnection; @@ -177,44 +176,8 @@ public class VTextualDate extends VDateField implements Paintable, Field, String dateText; Date currentDate = getDate(); if (currentDate != null) { - String formatStr = getFormatString(); - - /* - * Check if format contains the month name. If it does we need to - * manually convert it to the month name since DateTimeFormat.format - * always uses the current locale and will replace the month name - * wrong if current locale is different from the locale set for the - * DateField. - * - * MMMM is converted into long month name, MMM is converted into - * short month name. '' are added around the name to avoid that - * DateTimeFormat parses the month name as a pattern. - */ - if (formatStr.contains("MMMM")) { - @SuppressWarnings("deprecation") - String monthName = getDateTimeService().getMonth( - currentDate.getMonth()); - - if (monthName != null) { - formatStr = formatStr.replaceAll("[M]{4,}", "'" + monthName - + "'"); - } - } - - if (formatStr.contains("MMM")) { - - @SuppressWarnings("deprecation") - String monthName = getDateTimeService().getShortMonth( - currentDate.getMonth()); - - if (monthName != null) { - formatStr = formatStr.replaceAll("[M]{3,}", "'" + monthName - + "'"); - } - } - - DateTimeFormat format = DateTimeFormat.getFormat(formatStr); - dateText = format.format(currentDate); + dateText = getDateTimeService().formatDate(currentDate, + getFormatString()); } else { dateText = ""; } @@ -243,32 +206,23 @@ public class VTextualDate extends VDateField implements Paintable, Field, public void onChange(ChangeEvent event) { if (!text.getText().equals("")) { try { - DateTimeFormat format = DateTimeFormat - .getFormat(getFormatString()); - Date newDate; + String enteredDate = text.getText(); + + setDate(getDateTimeService().parseDate(enteredDate, + getFormatString(), lenient)); + if (lenient) { - newDate = format.parse(text.getText()); - if (newDate != null) { - // if date value was leniently parsed, normalize text - // presentation - text.setValue( - DateTimeFormat.getFormat(getFormatString()) - .format(newDate), false); - } - } else { - newDate = format.parseStrict(text.getText()); + // If date value was leniently parsed, normalize text + // presentation. + // FIXME: Add a description/example here of when this is + // needed + text.setValue( + getDateTimeService().formatDate(getDate(), + getFormatString()), false); } - long stamp = newDate.getTime(); - if (stamp == 0) { - // If date parsing fails in firefox the stamp will be 0 - setDate(null); - addStyleName(PARSE_ERROR_CLASSNAME); - } else { - setDate(newDate); - // remove possibly added invalid value indication - removeStyleName(PARSE_ERROR_CLASSNAME); - } + // remove possibly added invalid value indication + removeStyleName(PARSE_ERROR_CLASSNAME); } catch (final Exception e) { ClientExceptionHandler.displayError(e.getMessage()); |