123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- /*
- * Copyright 2000-2018 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
- package com.vaadin.util;
-
- import java.io.Serializable;
- import java.time.Duration;
- import java.time.LocalDate;
- import java.time.LocalDateTime;
- import java.time.ZoneId;
- import java.time.ZonedDateTime;
- import java.time.zone.ZoneOffsetTransition;
- import java.time.zone.ZoneRules;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Locale;
- import java.util.TimeZone;
-
- import elemental.json.JsonArray;
- import elemental.json.JsonObject;
- import elemental.json.impl.JreJsonFactory;
- import elemental.json.impl.JsonUtil;
-
- /**
- * Utilities related to {@link com.google.gwt.i18n.client.TimeZone}.
- *
- * @author Vaadin Ltd
- * @since 8.2
- */
- public final class TimeZoneUtil implements Serializable {
-
- /**
- * The default start year (inclusive) from which to calculate the
- * daylight-saving time zone transition dates.
- */
- private static final int STARTING_YEAR = 1980;
-
- /**
- * The default value of the number of future years from the current date for
- * which the daylight-saving time zone transition dates are calculated.
- */
- private static final int YEARS_FROM_NOW = 20;
-
- private TimeZoneUtil() {
- // Static utils only
- }
-
- /**
- * Returns a JSON string of the specified {@code zoneId} and {@link Locale},
- * which is used in
- * {@link com.google.gwt.i18n.client.TimeZone#createTimeZone(String)}.
- *
- * This method calculates the JSON string from the year
- * {@value #STARTING_YEAR} until {@value #YEARS_FROM_NOW} years into the
- * future from the current date.
- *
- * @see #toJSON(ZoneId, Locale, int, int)
- *
- * @param zoneId
- * the {@link ZoneId} to get the daylight transitions from
- * @param locale
- * the locale used to determine the short name of the time zone
- *
- * @return the encoded string
- */
- public static String toJSON(ZoneId zoneId, Locale locale) {
- int endYear = LocalDate.now().getYear() + YEARS_FROM_NOW;
- return toJSON(zoneId, locale, STARTING_YEAR, endYear);
- }
-
- /**
- * Returns a JSON string of the specified {@code zoneId} and {@link Locale},
- * which is used in
- * {@link com.google.gwt.i18n.client.TimeZone#createTimeZone(String)}.
- *
- * This method calculates the JSON string from {@code startYear} until
- * {@code startYear}, both inclusive.
- *
- * @param zoneId
- * the {@link ZoneId} to get the daylight transitions from
- * @param locale
- * the locale used to determine the short name of the time zone
- * @param startYear
- * the start year of DST transitions
- * @param endYear
- * the end year of DST transitions
- *
- * @return the encoded string
- * @since 8.11
- */
- public static String toJSON(ZoneId zoneId, Locale locale, int startYear,
- int endYear) {
- if (zoneId == null || locale == null) {
- return null;
- }
- ZoneRules rules = zoneId.getRules();
- TimeZone timeZone = TimeZone.getTimeZone(zoneId);
- List<Long> transitionsList = new ArrayList<>();
-
- TimeZoneInfo info = new TimeZoneInfo();
-
- if (timeZone.useDaylightTime()) {
- for (int year = startYear; 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 epochHours = Duration
- .ofSeconds(t.getInstant().getEpochSecond())
- .toHours();
- long duration = Math.max(t.getDuration().toMinutes(), 0);
- transitionsList.add(epochHours);
- transitionsList.add(duration);
- }
- }
- }
- info.id = zoneId.getId();
- info.transitions = transitionsList.stream().mapToLong(l -> l).toArray();
- info.stdOffset = (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.stdOffset);
- 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 stdOffset;
- String[] names;
- long[] transitions;
- }
- }
|