com.google.gwt.i18n.client.TimeZone.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.i18n.client.TimeZone.java

Source

/*
 * Copyright 2008 Google Inc.
 *
 * 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.google.gwt.i18n.client;

import com.google.gwt.core.client.JsArrayInteger;
import com.google.gwt.core.client.JsArrayString;

import java.util.Date;

/**
 * The TimeZone class implements a time zone information source for client
 * applications. The time zone object is instantiated from a TimeZoneData object,
 * which is made from a JSON string that contains all the data needed for
 * the specified time zone. Applications can instantiate a time zone statically,
 * in which case the data could be retrieved from
 * the {@link com.google.gwt.i18n.client.constants.TimeZoneConstants TimeZoneConstants}
 * class. Applications can also choose to instantiate from a string obtained
 * from a server. The time zone string contains locale specific data. If the
 * application only uses a short representation, the English data will usually
 * satisfy the user's need. In the case that only the time zone offset is known,
 * there is a decent fallback that only uses the time zone offset to create a
 * TimeZone object.
 */
public class TimeZone implements com.google.gwt.i18n.shared.TimeZone {
    // constants to reference time zone names in the time zone names array
    private static final int STD_SHORT_NAME = 0;
    private static final int STD_LONG_NAME = 1;
    private static final int DLT_SHORT_NAME = 2;
    private static final int DLT_LONG_NAME = 3;

    /**
     * This factory method provides a decent fallback to create a time zone object
     * just based on a given time zone offset.
     *
     * @param timeZoneOffsetInMinutes time zone offset in minutes
     * @return a new time zone object
     */
    public static TimeZone createTimeZone(int timeZoneOffsetInMinutes) {
        TimeZone tz = new TimeZone();
        tz.standardOffset = timeZoneOffsetInMinutes;
        tz.timezoneID = composePOSIXTimeZoneID(timeZoneOffsetInMinutes);
        tz.tzNames = new String[2];
        tz.tzNames[0] = composeUTCString(timeZoneOffsetInMinutes);
        tz.tzNames[1] = composeUTCString(timeZoneOffsetInMinutes);
        tz.transitionPoints = null;
        tz.adjustments = null;
        return tz;
    }

    /**
     * This factory method creates a time zone instance from a JSON string that
     * contains the time zone information for desired time zone. Applications can
     * get such a string from the TimeZoneConstants class, or it can request the
     * string from the server. Either way, the application obtains the original
     * string from the data provided in the TimeZoneConstant.properties file,
     * which was carefully prepared from CLDR and Olson time zone database.
     *
     * @param tzJSON JSON string that contains time zone data
     * @return a new time zone object
     */
    public static TimeZone createTimeZone(String tzJSON) {
        TimeZoneInfo tzData = TimeZoneInfo.buildTimeZoneData(tzJSON);

        return createTimeZone(tzData);
    }

    public static TimeZone createTimeZone(TimeZoneInfo timezoneData) {
        TimeZone tz = new TimeZone();

        tz.timezoneID = timezoneData.getID();
        tz.standardOffset = -timezoneData.getStandardOffset();

        JsArrayString jsTimezoneNames = timezoneData.getNames();

        tz.tzNames = new String[jsTimezoneNames.length()];

        for (int i = 0; i < jsTimezoneNames.length(); i++) {
            tz.tzNames[i] = jsTimezoneNames.get(i);
        }

        JsArrayInteger transitions = timezoneData.getTransitions();

        if (transitions == null || transitions.length() == 0) {
            tz.transitionPoints = null;
            tz.adjustments = null;
        } else {
            int transitionNum = transitions.length() / 2;
            tz.transitionPoints = new int[transitionNum];
            tz.adjustments = new int[transitionNum];

            for (int i = 0; i < transitionNum; ++i) {
                tz.transitionPoints[i] = transitions.get(i * 2);
                tz.adjustments[i] = transitions.get(i * 2 + 1);
            }
        }
        return tz;
    }

    /**
     * In GMT representation, +/- has reverse sign of time zone offset.
     * when offset == 480, it should output GMT-08:00.
     */
    private static String composeGMTString(int offset) {
        char data[] = { 'G', 'M', 'T', '-', '0', '0', ':', '0', '0' };
        if (offset <= 0) {
            data[3] = '+';
            offset = -offset; // suppress the '-' sign for text display.
        }
        data[4] += (offset / 60) / 10;
        data[5] += (offset / 60) % 10;
        data[7] += (offset % 60) / 10;
        data[8] += offset % 10;
        return new String(data);
    }

    /**
     * POSIX time zone ID as fallback.
     */
    private static String composePOSIXTimeZoneID(int offset) {
        if (offset == 0) {
            return "Etc/GMT";
        }
        String str;
        if (offset < 0) {
            offset = -offset;
            str = "Etc/GMT-";
        } else {
            str = "Etc/GMT+";
        }
        return str + offsetDisplay(offset);
    }

    private static String composeUTCString(int offset) {
        if (offset == 0) {
            return "UTC";
        }
        String str;
        if (offset < 0) {
            offset = -offset;
            str = "UTC+";
        } else {
            str = "UTC-";
        }
        return str + offsetDisplay(offset);
    }

    private static String offsetDisplay(int offset) {
        int hour = offset / 60;
        int mins = offset % 60;
        if (mins == 0) {
            return Integer.toString(hour);
        }
        return Integer.toString(hour) + ":" + Integer.toString(mins);
    }

    private String timezoneID;
    private int standardOffset;
    private String[] tzNames;
    private int[] transitionPoints;
    private int[] adjustments;

    private TimeZone() {
    }

    /* (non-Javadoc)
     * @see com.google.gwt.i18n.client.TimeZoneIntf#getDaylightAdjustment(java.util.Date)
     */
    public int getDaylightAdjustment(Date date) {
        if (transitionPoints == null) {
            return 0;
        }
        long timeInHours = date.getTime() / 1000 / 3600;
        int index = 0;
        while (index < transitionPoints.length && timeInHours >= transitionPoints[index]) {
            ++index;
        }
        return (index == 0) ? 0 : adjustments[index - 1];
    }

    /* (non-Javadoc)
     * @see com.google.gwt.i18n.client.TimeZoneIntf#getGMTString(java.util.Date)
     */
    public String getGMTString(Date date) {
        return composeGMTString(getOffset(date));
    }

    /* (non-Javadoc)
     * @see com.google.gwt.i18n.client.TimeZoneIntf#getID()
     */
    public String getID() {
        return timezoneID;
    }

    /* (non-Javadoc)
     * @see com.google.gwt.i18n.client.TimeZoneIntf#getISOTimeZoneString(java.util.Date)
     */
    public String getISOTimeZoneString(Date date) {
        int offset = -getOffset(date);
        char data[] = { '+', '0', '0', ':', '0', '0' };
        if (offset < 0) {
            data[0] = '-';
            offset = -offset; // suppress the '-' sign for text display.
        }
        data[1] += (offset / 60) / 10;
        data[2] += (offset / 60) % 10;
        data[4] += (offset % 60) / 10;
        data[5] += offset % 10;
        return new String(data);
    }

    /* (non-Javadoc)
     * @see com.google.gwt.i18n.client.TimeZoneIntf#getLongName(java.util.Date)
     */
    public String getLongName(Date date) {
        return tzNames[isDaylightTime(date) ? DLT_LONG_NAME : STD_LONG_NAME];
    }

    /* (non-Javadoc)
     * @see com.google.gwt.i18n.client.TimeZoneIntf#getOffset(java.util.Date)
     */
    public int getOffset(Date date) {
        return standardOffset - getDaylightAdjustment(date);
    }

    /* (non-Javadoc)
     * @see com.google.gwt.i18n.client.TimeZoneIntf#getRFCTimeZoneString(java.util.Date)
     */
    public String getRFCTimeZoneString(Date date) {
        int offset = -getOffset(date);
        char data[] = { '+', '0', '0', '0', '0' };
        if (offset < 0) {
            data[0] = '-';
            offset = -offset; // suppress the '-' sign for text display.
        }
        data[1] += (offset / 60) / 10;
        data[2] += (offset / 60) % 10;
        data[3] += (offset % 60) / 10;
        data[4] += offset % 10;
        return new String(data);
    }

    /* (non-Javadoc)
     * @see com.google.gwt.i18n.client.TimeZoneIntf#getShortName(java.util.Date)
     */
    public String getShortName(Date date) {
        return tzNames[isDaylightTime(date) ? DLT_SHORT_NAME : STD_SHORT_NAME];
    }

    /* (non-Javadoc)
     * @see com.google.gwt.i18n.client.TimeZoneIntf#getStandardOffset()
     */
    public int getStandardOffset() {
        return standardOffset;
    }

    /* (non-Javadoc)
     * @see com.google.gwt.i18n.client.TimeZoneIntf#isDaylightTime(java.util.Date)
     */
    public boolean isDaylightTime(Date date) {
        return getDaylightAdjustment(date) > 0;
    }
}