aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnna Koskinen <Ansku@users.noreply.github.com>2020-07-14 12:46:27 +0300
committerGitHub <noreply@github.com>2020-07-14 12:46:27 +0300
commit70fa99868a11671ed7bc8875ee24e971f78ba77f (patch)
treea9c997f5e1a094ed3a1cc1056ac33068fc7047a1
parentb0d157b73b03579cfbde7976aaf6242d9c285c8e (diff)
downloadvaadin-framework-70fa99868a11671ed7bc8875ee24e971f78ba77f.tar.gz
vaadin-framework-70fa99868a11671ed7bc8875ee24e971f78ba77f.zip
Add support for "ww" in date format (#12037) (#12052)
Calculate number of the week in the year based on Date. Note, support for "ww" is missing from GWT DateTimeFormat and java.util.Calendar is not supported in GWT, hence DIY method is needed. Fixes: #10603 Authored-by: Tatu Lund <tatu@vaadin.com>
-rw-r--r--client/src/main/java/com/vaadin/client/DateTimeService.java49
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractLocalDateField.java28
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateFieldTest.java1
3 files changed, 77 insertions, 1 deletions
diff --git a/client/src/main/java/com/vaadin/client/DateTimeService.java b/client/src/main/java/com/vaadin/client/DateTimeService.java
index 00606a25c1..72d51edcae 100644
--- a/client/src/main/java/com/vaadin/client/DateTimeService.java
+++ b/client/src/main/java/com/vaadin/client/DateTimeService.java
@@ -39,6 +39,10 @@ public class DateTimeService {
private static int[] maxDaysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30,
31, 30, 31 };
+ private int[] yearDays = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273,
+ 304, 334 };
+ private int[] leapYearDays = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274,
+ 305, 335};
private static final long MILLISECONDS_PER_DAY = 24 * 3600 * 1000;
@@ -373,6 +377,10 @@ public class DateTimeService {
*/
public String formatDate(Date date, String formatStr, TimeZone timeZone) {
/*
+ * Format week numbers
+ */
+ formatStr = formatWeekNumbers(date, formatStr);
+ /*
* Format month and day names separately when locale for the
* DateTimeService is not the same as the browser locale
*/
@@ -388,6 +396,47 @@ public class DateTimeService {
return result;
}
+ /*
+ * Calculate number of the week in the year based on Date
+ * Note, support for "ww" is missing GWT DateTimeFormat
+ * and java.util.Calendar is not supported in GWT
+ * Hence DIY method needed
+ */
+ private String getWeek(Date date) {
+ int year = date.getYear()+1900;
+ int month = date.getMonth();
+ int day = date.getDate()+1;
+ int weekDay = date.getDay();
+ if (weekDay == 6) {
+ weekDay = 0;
+ } else {
+ weekDay = weekDay - 1;
+ }
+ boolean leap = false;
+ if (((year % 4) == 0) && (((year % 100) != 0) || ((year % 400) == 0))) {
+ leap = true;
+ }
+ int week;
+ if (leap) {
+ week = countWeek(leapYearDays, month, day, weekDay);
+ } else {
+ week = countWeek(yearDays, month, day, weekDay);
+ }
+ return ""+week;
+ }
+
+ private int countWeek(int[] days, int month, int day, int weekDay) {
+ return ((days[month] + day) - (weekDay + 7) % 7 + 7) / 7;
+ }
+
+ private String formatWeekNumbers(Date date, String formatStr) {
+ if (formatStr.contains("ww")) {
+ String weekNumber = getWeek(date);
+ formatStr = formatStr.replaceAll("ww", weekNumber);
+ }
+ return formatStr;
+ }
+
private String formatDayNames(Date date, String formatStr) {
if (formatStr.contains("EEEE")) {
String dayName = getDay(date.getDay());
diff --git a/server/src/main/java/com/vaadin/ui/AbstractLocalDateField.java b/server/src/main/java/com/vaadin/ui/AbstractLocalDateField.java
index 7bd245382f..9314f5d9b9 100644
--- a/server/src/main/java/com/vaadin/ui/AbstractLocalDateField.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractLocalDateField.java
@@ -15,9 +15,11 @@
*/
package com.vaadin.ui;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
-import java.time.LocalDateTime;
+import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
@@ -26,6 +28,7 @@ import java.util.Date;
import java.util.Locale;
import java.util.Map;
+import com.vaadin.data.Result;
import com.vaadin.data.validator.DateRangeValidator;
import com.vaadin.data.validator.RangeValidator;
import com.vaadin.shared.ui.datefield.AbstractTextualDateFieldState;
@@ -163,4 +166,27 @@ public abstract class AbstractLocalDateField
return temporalAccessor == null ? null
: LocalDate.from(temporalAccessor);
}
+
+ @Override
+ protected Result<LocalDate> handleUnparsableDateString(String dateString) {
+ // Handle possible week number, which cannot be parsed client side due
+ // limitations in GWT
+ if (this.getDateFormat() != null && this.getDateFormat().contains("w")) {
+ Date parsedDate;
+ SimpleDateFormat df = new SimpleDateFormat(this.getDateFormat(),this.getLocale());
+ try {
+ parsedDate = df.parse(dateString);
+ } catch (ParseException e) {
+ return super.handleUnparsableDateString(dateString);
+ }
+ ZoneId zi = this.getZoneId();
+ if (zi == null) {
+ zi = ZoneId.systemDefault();
+ }
+ LocalDate date = Instant.ofEpochMilli(parsedDate.getTime()).atZone(zi).toLocalDate();
+ return Result.ok(date);
+ } else {
+ return super.handleUnparsableDateString(dateString);
+ }
+ }
}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateFieldTest.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateFieldTest.java
index 9d7d75efb8..3a5e57273c 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateFieldTest.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateFieldTest.java
@@ -64,6 +64,7 @@ public abstract class AbstractDateFieldTest<T extends AbstractLocalDateField>
getDatePattern(new Locale("fi", "FI"), DateFormat.MEDIUM));
options.put(getDatePattern(new Locale("fi", "FI"), DateFormat.SHORT),
getDatePattern(new Locale("fi", "FI"), DateFormat.SHORT));
+ options.put("ww yyyy", "ww yyyy");
createSelectAction("Date format", category, options, "-",
dateFormatCommand);