All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vaadin.util.TimeZoneUtil Maven / Gradle / Ivy

There is a newer version: 8.27.3
Show newest version
/*
 * Copyright (C) 2000-2024 Vaadin Ltd
 *
 * This program is available under Vaadin Commercial License and Service Terms.
 *
 * See  for the full
 * 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 {@code 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
     * {@code 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
     * {@code 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 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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy