summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorAhmed Ashour <asashour@yahoo.com>2017-09-28 11:37:32 +0200
committerHenri Sara <henri.sara@gmail.com>2017-09-28 12:37:32 +0300
commitc520767bf156c54a9d1a9f69f0aa78bc3b835b3f (patch)
tree208c6d8679708a6cc9e8b425d86fe10f2abeedc9 /client
parent131601de3693655387313e47e887f593c32fa625 (diff)
downloadvaadin-framework-c520767bf156c54a9d1a9f69f0aa78bc3b835b3f.tar.gz
vaadin-framework-c520767bf156c54a9d1a9f69f0aa78bc3b835b3f.zip
Handle 'z' (timezone) in AbstractDateField.setDateFormat() (#8844)
Diffstat (limited to 'client')
-rw-r--r--client/src/main/java/com/vaadin/client/DateTimeService.java93
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java11
-rw-r--r--client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java17
3 files changed, 118 insertions, 3 deletions
diff --git a/client/src/main/java/com/vaadin/client/DateTimeService.java b/client/src/main/java/com/vaadin/client/DateTimeService.java
index 2e9627a5a5..577b079ce2 100644
--- a/client/src/main/java/com/vaadin/client/DateTimeService.java
+++ b/client/src/main/java/com/vaadin/client/DateTimeService.java
@@ -21,6 +21,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gwt.i18n.client.LocaleInfo;
+import com.google.gwt.i18n.client.TimeZone;
import com.google.gwt.i18n.shared.DateTimeFormat;
import com.vaadin.shared.ui.datefield.DateResolution;
@@ -50,7 +51,7 @@ public class DateTimeService {
* Creates a new date time service with a given locale.
*
* @param locale
- * e.g. fi, en etc.
+ * e.g. {@code fi}, {@code en}, etc.
* @throws LocaleNotLoadedException
*/
public DateTimeService(String locale) throws LocaleNotLoadedException {
@@ -305,10 +306,40 @@ public class DateTimeService {
* @return
*/
public String formatDate(Date date, String formatStr) {
+ return formatDate(date, formatStr, null);
+ }
+
+ /**
+ * 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.
+ *
+ * z is converted into the time zone name, using the specified
+ * {@code timeZoneJSON}
+ *
+ * @param date
+ * The date to convert
+ * @param formatStr
+ * The format string that might contain {@code MMM} or
+ * {@code MMMM}
+ * @param timeZone
+ * The {@link TimeZone} used to replace {@code z}, can be
+ * {@code null}
+ *
+ * @return the formatted date string
+ * @since 8.2
+ */
+ public String formatDate(Date date, String formatStr, TimeZone timeZone) {
/*
* Format month and day names separately when locale for the
* DateTimeService is not the same as the browser locale
*/
+ formatStr = formatTimeZone(date, formatStr, timeZone);
formatStr = formatMonthNames(date, formatStr);
formatStr = formatDayNames(date, formatStr);
@@ -406,6 +437,66 @@ public class DateTimeService {
return formatStr;
}
+ private String formatTimeZone(Date date, String formatStr,
+ TimeZone timeZone) {
+ // if 'z' is found outside quotes and timeZone is used
+ if (getIndexOf(formatStr, 'z') != -1 && timeZone != null) {
+ return replaceTimeZone(formatStr, timeZone.getShortName(date));
+ }
+ return formatStr;
+ }
+
+ /**
+ * Replaces the {@code z} characters of the specified {@code formatStr} with
+ * the given {@code timeZoneName}.
+ *
+ * @param formatStr
+ * The format string, which is the pattern describing the date
+ * and time format
+ * @param timeZoneName
+ * the time zone name
+ * @return the format string, with {@code z} replaced (if found)
+ */
+ private static String replaceTimeZone(String formatStr,
+ String timeZoneName) {
+
+ // search for 'z' outside the quotes (inside quotes is escaped)
+ int start = getIndexOf(formatStr, 'z');
+ if (start == -1) {
+ return formatStr;
+ }
+
+ // if there are multiple consecutive 'z', treat them as one
+ int end = start;
+ while (end + 1 < formatStr.length()
+ && formatStr.charAt(end + 1) == 'z') {
+ end++;
+ }
+ return formatStr.substring(0, start) + "'" + timeZoneName + "'"
+ + formatStr.substring(end + 1);
+ }
+
+ /**
+ * Returns the first index of the specified {@code ch}, which is outside the
+ * quotes.
+ */
+ private static int getIndexOf(String str, char ch) {
+ boolean inQuote = false;
+ for (int i = 0; i < str.length(); i++) {
+ char c = str.charAt(i);
+ if (c == '\'') {
+ if (i + 1 < str.length() && str.charAt(i + 1) == '\'') {
+ i++;
+ } else {
+ inQuote ^= true;
+ }
+ } else if (c == ch && !inQuote) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
/**
* Replaces month names in the entered date with the name in the current
* browser locale.
diff --git a/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java b/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java
index c9c6df01f4..206709c86d 100644
--- a/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java
+++ b/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java
@@ -27,6 +27,7 @@ import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.i18n.client.TimeZone;
import com.google.gwt.user.client.ui.TextBox;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.Focusable;
@@ -70,6 +71,9 @@ public abstract class VAbstractTextualDate<R extends Enum<R>>
/** For internal use only. May be removed or replaced in the future. */
private String formatStr;
+ /** For internal use only. May be removed or replaced in the future. */
+ private TimeZone timeZone;
+
public VAbstractTextualDate(R resoluton) {
super(resoluton);
text = new TextBox();
@@ -177,7 +181,7 @@ public abstract class VAbstractTextualDate<R extends Enum<R>>
String formatString = getFormatString();
if (currentDate != null) {
dateText = getDateTimeService().formatDate(currentDate,
- formatString);
+ formatString, timeZone);
} else {
dateText = "";
}
@@ -195,7 +199,10 @@ public abstract class VAbstractTextualDate<R extends Enum<R>>
Roles.getTextboxRole()
.removeAriaReadonlyProperty(text.getElement());
}
+ }
+ public void setTimeZone(TimeZone timeZone) {
+ this.timeZone = timeZone;
}
@Override
@@ -220,7 +227,7 @@ public abstract class VAbstractTextualDate<R extends Enum<R>>
// FIXME: Add a description/example here of when this is
// needed
text.setValue(getDateTimeService().formatDate(getDate(),
- getFormatString()), false);
+ getFormatString(), timeZone), false);
}
// remove possibly added invalid value indication
diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java
index fb3351ea4f..81eea0e71e 100644
--- a/client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java
@@ -16,8 +16,11 @@
package com.vaadin.client.ui.datefield;
+import com.google.gwt.i18n.client.TimeZone;
+import com.google.gwt.i18n.client.TimeZoneInfo;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.UIDL;
+import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.ui.VAbstractTextualDate;
import com.vaadin.shared.ui.datefield.AbstractTextualDateFieldState;
@@ -71,4 +74,18 @@ public abstract class AbstractTextualDateConnector<R extends Enum<R>>
return (AbstractTextualDateFieldState) super.getState();
}
+ @OnStateChange("timeZoneJSON")
+ private void onTimeZoneJSONChange() {
+ TimeZone timeZone;
+ String timeZoneJSON = getState().timeZoneJSON;
+ if (timeZoneJSON != null) {
+ TimeZoneInfo timeZoneInfo = TimeZoneInfo
+ .buildTimeZoneData(timeZoneJSON);
+ timeZone = TimeZone.createTimeZone(timeZoneInfo);
+ } else {
+ timeZone = null;
+ }
+ getWidget().setTimeZone(timeZone);
+ }
+
}