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

com.google.gwt.i18n.client.TimeZone Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
/*
 * 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 {
  // 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() {
  }

  /**
   * Returns the daylight savings time adjustment, in minutes, for the given
   * date. If daylight savings time is in effect on the given date, the number
   * will be positive, otherwise 0.
   *
   * @param date the date to check
   * @return offset amount
   */
  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];
  }

  /**
   * Returns the GMT representation of this time zone object.
   *
   * @param date The date from which the time information should be extracted
   * @return A GMT representation of the time given by the date
   */
  public String getGMTString(Date date) {
    return composeGMTString(getOffset(date));
  }

  /**
   * Returns time zone id for this time zone. For time zone objects that have
   * been instantiated from a time zone offset, the POSIX time zone id will be
   * returned.
   *
   * @return time zone id
   */
  public String getID() {
    return timezoneID;
  }

  /**
   * To get ISO-style (+00:00) representation of the time zone for given date.
   *
   * @param date The date for which time to retrieve RFC time zone string
   * @return ISO-style time zone string
   */
  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);
  }

  /**
   * Returns the long version of the time zone name for the given date; the
   * result of this method will be different if daylight savings time is in
   * effect.
   *
   * @param date The date for which the long time zone name is returned
   * @return long time zone name
   */
  public String getLongName(Date date) {
    return tzNames[isDaylightTime(date) ? DLT_LONG_NAME : STD_LONG_NAME];
  }

  /**
   * Returns the RFC representation of the time zone name for the given date.
   * To be consistent with JDK/Javascript API, west of Greenwich will be
   * positive.
   *
   *  @param date The date for which time to retrieve time zone offset
   *  @return time zone offset in minutes
   */
  public int getOffset(Date date) {
    return standardOffset - getDaylightAdjustment(date);
  }

  /**
   * To get RFC representation of certain time zone name for given date.
   * @param date The date for which time to retrieve RFC time zone string
   * @return RFC time zone string
   */
  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);
  }

  /**
   * Returns the short time zone name for a given date.
   *
   * @param date The date for which time to retrieve short time zone
   * @return short time zone name
   */
  public String getShortName(Date date) {
    return tzNames[isDaylightTime(date) ? DLT_SHORT_NAME : STD_SHORT_NAME];
  }

  /**
   * Returns the standard time zone offset, in minutes.
   */
  public int getStandardOffset() {
    return standardOffset;
  }

  /**
   * Check whether the given date and time falls within a daylight savings time
   * period.
   *
   * @param date and time to check
   * @return true if daylight savings time is in effect
   */
  public boolean isDaylightTime(Date date) {
    return getDaylightAdjustment(date) > 0;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy