aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtur Signell <artur.signell@itmill.com>2010-08-24 11:37:36 +0000
committerArtur Signell <artur.signell@itmill.com>2010-08-24 11:37:36 +0000
commit7a192a8d5f643e51837ad2ce4cba91a29c343e9d (patch)
tree095e106e66db3e46133d4f8f9ca940c8438e47af
parent3b1c8515a708760cce1bf0ce24a1a0e7262eeca6 (diff)
downloadvaadin-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.java141
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java78
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());