From c520767bf156c54a9d1a9f69f0aa78bc3b835b3f Mon Sep 17 00:00:00 2001 From: Ahmed Ashour Date: Thu, 28 Sep 2017 11:37:32 +0200 Subject: Handle 'z' (timezone) in AbstractDateField.setDateFormat() (#8844) --- .../main/java/com/vaadin/ui/AbstractDateField.java | 51 +++++++ .../main/java/com/vaadin/util/TimeZoneUtil.java | 150 +++++++++++++++++++++ 2 files changed, 201 insertions(+) create mode 100644 server/src/main/java/com/vaadin/util/TimeZoneUtil.java (limited to 'server/src') diff --git a/server/src/main/java/com/vaadin/ui/AbstractDateField.java b/server/src/main/java/com/vaadin/ui/AbstractDateField.java index bc6b5f49a8..b5f11f7122 100644 --- a/server/src/main/java/com/vaadin/ui/AbstractDateField.java +++ b/server/src/main/java/com/vaadin/ui/AbstractDateField.java @@ -19,6 +19,7 @@ import java.io.Serializable; import java.lang.reflect.Type; import java.text.SimpleDateFormat; import java.time.LocalDate; +import java.time.ZoneId; import java.time.temporal.Temporal; import java.time.temporal.TemporalAdjuster; import java.util.Calendar; @@ -56,6 +57,7 @@ import com.vaadin.shared.ui.datefield.DateFieldConstants; import com.vaadin.shared.ui.datefield.DateResolution; import com.vaadin.ui.declarative.DesignAttributeHandler; import com.vaadin.ui.declarative.DesignContext; +import com.vaadin.util.TimeZoneUtil; /** * A date editor component with {@link LocalDate} as an input value. @@ -95,6 +97,8 @@ public abstract class AbstractDateField transitionsList = new ArrayList<>(); + + TimeZoneInfo info = new TimeZoneInfo(); + + int endYear = LocalDate.now().getYear() + YEARS_FROM_NOW; + if (timeZone.useDaylightTime()) { + for (int year = STARTING_YEAR; year <= endYear; year++) { + ZonedDateTime i = LocalDateTime.of(year, 1, 1, 0, 0) + .atZone(zoneId); + while (true) { + ZoneOffsetTransition t = rules + .nextTransition(i.toInstant()); + if (t == null) { + break; + } + i = t.getInstant().atZone(zoneId); + if (i.toLocalDate().getYear() != year) { + break; + } + long epocHours = Duration + .ofSeconds(t.getInstant().getEpochSecond()) + .toHours(); + long duration = Math.max(t.getDuration().toMinutes(), 0); + transitionsList.add(epocHours); + transitionsList.add(duration); + } + } + } + info.id = zoneId.getId(); + info.transitions = transitionsList.stream().mapToLong(l -> l).toArray(); + info.std_offset = (int) Duration.ofMillis(timeZone.getRawOffset()) + .toMinutes(); + info.names = new String[] { + timeZone.getDisplayName(false, TimeZone.SHORT, locale), + timeZone.getDisplayName(false, TimeZone.LONG, locale), + timeZone.getDisplayName(true, TimeZone.SHORT, locale), + timeZone.getDisplayName(true, TimeZone.LONG, locale) }; + + return stringify(info); + } + + private static String stringify(TimeZoneInfo info) { + JreJsonFactory factory = new JreJsonFactory(); + JsonObject object = factory.createObject(); + object.put("id", info.id); + object.put("std_offset", info.std_offset); + object.put("names", getArray(factory, info.names)); + object.put("transitions", getArray(factory, info.transitions)); + return JsonUtil.stringify(object); + } + + private static JsonArray getArray(JreJsonFactory factory, long[] array) { + JsonArray jsonArray = factory.createArray(); + for (int i = 0; i < array.length; i++) { + jsonArray.set(i, array[i]); + } + return jsonArray; + } + + private static JsonArray getArray(JreJsonFactory factory, String[] array) { + JsonArray jsonArray = factory.createArray(); + for (int i = 0; i < array.length; i++) { + jsonArray.set(i, array[i]); + } + return jsonArray; + } + + private static class TimeZoneInfo implements Serializable { + String id; + int std_offset; + String[] names; + long[] transitions; + } +} -- cgit v1.2.3