Commit 914bf666 authored by Matt Tucker's avatar Matt Tucker Committed by matt

Added support for setting the time zone (JM-403).

git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@2833 b35dd754-fafc-0310-a699-88a17e54d16e
parent 3a328b09
......@@ -133,9 +133,15 @@
## Removed key: 'sidebar.client-session'
## Removed key: 'sidebar.server-session'
## Removed key: 'sidebar.component-session'
##
## 2.2.1
## Modified key: 'server2server.settings.label_disable_info'
## Modified key: 'server2server.settings.label_enable_info'
##
## 2.3.0
## Added key: 'language.choose'
## Added key: 'timezone.choose'
## Removed key: 'locale.choose'
# Messenger
......@@ -636,11 +642,11 @@ index.memory=Java Memory
# Locale Page
locale.title=Server Locale
locale.title.info=Use the form below to set the system locale. By default, the locale is the system \
default locale and the language is English.
locale.title.info=Use the form below to set the locale.
locale.system.set=Set System Locale
locale.current=Current Locale
locale.choose=Choose new locale
language.choose=Choose Language
timezone.choose=Choose Time Zone
# License details Page
......
......@@ -3,7 +3,7 @@
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
* Copyright (C) 2004-2005 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
......@@ -13,6 +13,7 @@ package org.jivesoftware.util;
import java.text.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* A set of methods for retrieving and converting locale specific strings and numbers.
......@@ -21,9 +22,8 @@ import java.util.*;
*/
public class LocaleUtils {
private static String[][] timeZoneList = null;
private static Object timeZoneLock = new Object();
private static final Map<Locale, String[][]> timeZoneLists =
new ConcurrentHashMap<Locale, String[][]>();
// The basename to use for looking up the appropriate resource bundles
// TODO - extract this out into a test that grabs the resource name from JiveGlobals
......@@ -46,15 +46,13 @@ public class LocaleUtils {
String language = null;
String country = null;
String variant = null;
if (localeCode != null) {
StringTokenizer tokenizer = new StringTokenizer(localeCode, "_");
StringTokenizer tokenizer = new StringTokenizer(localeCode, "_");
if (tokenizer.hasMoreTokens()) {
language = tokenizer.nextToken();
if (tokenizer.hasMoreTokens()) {
language = tokenizer.nextToken();
country = tokenizer.nextToken();
if (tokenizer.hasMoreTokens()) {
country = tokenizer.nextToken();
if (tokenizer.hasMoreTokens()) {
variant = tokenizer.nextToken();
}
variant = tokenizer.nextToken();
}
}
}
......@@ -65,59 +63,221 @@ public class LocaleUtils {
return locale;
}
// The list of supported timezone ids. The list tries to include all of the relevant
// time zones for the world without any extraneous zones.
private static String[] timeZoneIds = new String[]{"GMT",
"Pacific/Apia",
"HST",
"AST",
"America/Los_Angeles",
"America/Phoenix",
"America/Mazatlan",
"America/Denver",
"America/Belize",
"America/Chicago",
"America/Mexico_City",
"America/Regina",
"America/Bogota",
"America/New_York",
"America/Indianapolis",
"America/Halifax",
"America/Caracas",
"America/Santiago",
"America/St_Johns",
"America/Sao_Paulo",
"America/Buenos_Aires",
"America/Godthab",
"Atlantic/South_Georgia",
"Atlantic/Azores",
"Atlantic/Cape_Verde",
"Africa/Casablanca",
"Europe/Dublin",
"Europe/Berlin",
"Europe/Belgrade",
"Europe/Paris",
"Europe/Warsaw",
"ECT",
"Europe/Athens",
"Europe/Bucharest",
"Africa/Cairo",
"Africa/Harare",
"Europe/Helsinki",
"Asia/Jerusalem",
"Asia/Baghdad",
"Asia/Kuwait",
"Europe/Moscow",
"Africa/Nairobi",
"Asia/Tehran",
"Asia/Muscat",
"Asia/Baku",
"Asia/Kabul",
"Asia/Yekaterinburg",
"Asia/Karachi",
"Asia/Calcutta",
"Asia/Katmandu",
"Asia/Almaty",
"Asia/Dhaka",
"Asia/Colombo",
"Asia/Rangoon",
"Asia/Bangkok",
"Asia/Krasnoyarsk",
"Asia/Hong_Kong",
"Asia/Irkutsk",
"Asia/Kuala_Lumpur",
"Australia/Perth",
"Asia/Taipei",
"Asia/Tokyo",
"Asia/Seoul",
"Asia/Yakutsk",
"Australia/Adelaide",
"Australia/Darwin",
"Australia/Brisbane",
"Australia/Sydney",
"Pacific/Guam",
"Australia/Hobart",
"Asia/Vladivostok",
"Pacific/Noumea",
"Pacific/Auckland",
"Pacific/Fiji",
"Pacific/Tongatapu"
};
// A mapping from the supported timezone ids to friendly english names.
private static final Map<String, String> nameMap = new HashMap<String, String>();
static {
nameMap.put(timeZoneIds[0], "International Date Line West");
nameMap.put(timeZoneIds[1], "Midway Island, Samoa");
nameMap.put(timeZoneIds[2], "Hawaii");
nameMap.put(timeZoneIds[3], "Alaska");
nameMap.put(timeZoneIds[4], "Pacific Time (US & Canada); Tijuana");
nameMap.put(timeZoneIds[5], "Arizona");
nameMap.put(timeZoneIds[6], "Chihuahua, La Pax, Mazatlan");
nameMap.put(timeZoneIds[7], "Mountain Time (US & Canada)");
nameMap.put(timeZoneIds[8], "Central America");
nameMap.put(timeZoneIds[9], "Central Time (US & Canada)");
nameMap.put(timeZoneIds[10], "Guadalajara, Mexico City, Monterrey");
nameMap.put(timeZoneIds[11], "Saskatchewan");
nameMap.put(timeZoneIds[12], "Bogota, Lima, Quito");
nameMap.put(timeZoneIds[13], "Eastern Time (US & Canada)");
nameMap.put(timeZoneIds[14], "Indiana (East)");
nameMap.put(timeZoneIds[15], "Atlantic Time (Canada)");
nameMap.put(timeZoneIds[16], "Caracas, La Paz");
nameMap.put(timeZoneIds[17], "Santiago");
nameMap.put(timeZoneIds[18], "Newfoundland");
nameMap.put(timeZoneIds[19], "Brasilia");
nameMap.put(timeZoneIds[20], "Buenos Aires, Georgetown");
nameMap.put(timeZoneIds[21], "Greenland");
nameMap.put(timeZoneIds[22], "Mid-Atlantic");
nameMap.put(timeZoneIds[23], "Azores");
nameMap.put(timeZoneIds[24], "Cape Verde Is.");
nameMap.put(timeZoneIds[25], "Casablanca, Monrovia");
nameMap.put(timeZoneIds[26], "Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London");
nameMap.put(timeZoneIds[27], "Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna");
nameMap.put(timeZoneIds[28], "Belgrade, Bratislava, Budapest, Ljubljana, Prague");
nameMap.put(timeZoneIds[29], "Brussels, Copenhagen, Madrid, Paris");
nameMap.put(timeZoneIds[30], "Sarajevo, Skopje, Warsaw, Zagreb");
nameMap.put(timeZoneIds[31], "West Central Africa");
nameMap.put(timeZoneIds[32], "Athens, Istanbul, Minsk");
nameMap.put(timeZoneIds[33], "Bucharest");
nameMap.put(timeZoneIds[34], "Cairo");
nameMap.put(timeZoneIds[35], "Harare, Pretoria");
nameMap.put(timeZoneIds[36], "Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius");
nameMap.put(timeZoneIds[37], "Jerusalem");
nameMap.put(timeZoneIds[38], "Baghdad");
nameMap.put(timeZoneIds[39], "Kuwait, Riyadh");
nameMap.put(timeZoneIds[40], "Moscow, St. Petersburg, Volgograd");
nameMap.put(timeZoneIds[41], "Nairobi");
nameMap.put(timeZoneIds[42], "Tehran");
nameMap.put(timeZoneIds[43], "Abu Dhabi, Muscat");
nameMap.put(timeZoneIds[44], "Baku, Tbilisi, Muscat");
nameMap.put(timeZoneIds[45], "Kabul");
nameMap.put(timeZoneIds[46], "Ekaterinburg");
nameMap.put(timeZoneIds[47], "Islamabad, Karachi, Tashkent");
nameMap.put(timeZoneIds[48], "Chennai, Kolkata, Mumbai, New Dehli");
nameMap.put(timeZoneIds[49], "Kathmandu");
nameMap.put(timeZoneIds[50], "Almaty, Novosibirsk");
nameMap.put(timeZoneIds[51], "Astana, Dhaka");
nameMap.put(timeZoneIds[52], "Sri Jayawardenepura");
nameMap.put(timeZoneIds[53], "Rangoon");
nameMap.put(timeZoneIds[54], "Bangkok, Hanoi, Jakarta");
nameMap.put(timeZoneIds[55], "Krasnoyarsk");
nameMap.put(timeZoneIds[56], "Beijing, Chongqing, Hong Kong, Urumqi");
nameMap.put(timeZoneIds[57], "Irkutsk, Ulaan Bataar");
nameMap.put(timeZoneIds[58], "Kuala Lampur, Singapore");
nameMap.put(timeZoneIds[59], "Perth");
nameMap.put(timeZoneIds[60], "Taipei");
nameMap.put(timeZoneIds[61], "Osaka, Sapporo, Tokyo");
nameMap.put(timeZoneIds[62], "Seoul");
nameMap.put(timeZoneIds[63], "Yakutsk");
nameMap.put(timeZoneIds[64], "Adelaide");
nameMap.put(timeZoneIds[65], "Darwin");
nameMap.put(timeZoneIds[66], "Brisbane");
nameMap.put(timeZoneIds[67], "Canberra, Melbourne, Sydney");
nameMap.put(timeZoneIds[68], "Guam, Port Moresby");
nameMap.put(timeZoneIds[69], "Hobart");
nameMap.put(timeZoneIds[70], "Vladivostok");
nameMap.put(timeZoneIds[71], "Magadan, Solomon Is., New Caledonia");
nameMap.put(timeZoneIds[72], "Auckland, Wellington");
nameMap.put(timeZoneIds[73], "Fiji, Kamchatka, Marshall Is.");
nameMap.put(timeZoneIds[74], "Nuku'alofa");
}
/**
* Returns a list of all available time zone's as a String [][]. The first
* entry in each list item is the timeZoneID, and the second is the
* display name.<p>
* <p/>
* Normally, there are many ID's that correspond to a single display name.
* However, the list has been paired down so that a display name only
* appears once. Normally, the time zones will be returned in order:
* -12 GMT,..., +0GMT,... +12GMT..., etc.
* The list of time zones attempts to be inclusive of all of the worlds
* zones while being as concise as possible. For "en" language locales
* the name is a friendly english name. For non-"en" language locales
* the standard JDK name is used for the given Locale. The GMT+/- time
* is also included for readability.
*
* @return a list of time zones, as a tuple of the zime zone ID, and its
* display name.
*/
public static String[][] getTimeZoneList() {
if (timeZoneList == null) {
synchronized (timeZoneLock) {
if (timeZoneList == null) {
Date now = new Date();
Locale jiveLocale = JiveGlobals.getLocale();
String[] timeZoneIDs = TimeZone.getAvailableIDs();
Locale jiveLocale = JiveGlobals.getLocale();
// Now, create String[][] using the unique zones.
timeZoneList = new String[timeZoneIDs.length][2];
for (int i = 0; i < timeZoneList.length; i++) {
String zoneID = timeZoneIDs[i];
timeZoneList[i][0] = zoneID;
timeZoneList[i][1] = getTimeZoneName(zoneID, now, jiveLocale);
}
}
String[][] timeZoneList = timeZoneLists.get(jiveLocale);
if (timeZoneList == null) {
String[] timeZoneIDs = timeZoneIds;
// Now, create String[][] using the unique zones.
timeZoneList = new String[timeZoneIDs.length][2];
for (int i = 0; i < timeZoneList.length; i++) {
String zoneID = timeZoneIDs[i];
timeZoneList[i][0] = zoneID;
timeZoneList[i][1] = getTimeZoneName(zoneID, jiveLocale);
}
// Add the new list to the map of locales to lists
timeZoneLists.put(jiveLocale, timeZoneList);
}
return timeZoneList;
}
/**
* Returns the display name for a time zone. The display name is the name
* specified by the Java TimeZone class, with the addition of the GMT offset
* specified by the Java TimeZone class for non-"en" locales or a friendly english
* name for "en", with the addition of the GMT offset
* for human readability.
*
* @param zoneID the time zone to get the name for.
* @param now the current date.
* @param locale the locale to use.
* @return the display name for the time zone.
*/
private static String getTimeZoneName(String zoneID, Date now, Locale locale) {
public static String getTimeZoneName(String zoneID, Locale locale) {
TimeZone zone = TimeZone.getTimeZone(zoneID);
StringBuilder buf = new StringBuilder();
StringBuffer buf = new StringBuffer();
// Add in the GMT part to the name. First, figure out the offset.
int offset = zone.getRawOffset();
if (zone.inDaylightTime(now) && zone.useDaylightTime()) {
offset += (int)JiveConstants.HOUR;
if (zone.inDaylightTime(new Date()) && zone.useDaylightTime()) {
offset += (int) JiveConstants.HOUR;
}
buf.append("(");
if (offset < 0) {
buf.append("GMT-");
}
......@@ -125,8 +285,8 @@ public class LocaleUtils {
buf.append("GMT+");
}
offset = Math.abs(offset);
int hours = offset / (int)JiveConstants.HOUR;
int minutes = (offset % (int)JiveConstants.HOUR) / (int)JiveConstants.MINUTE;
int hours = offset / (int) JiveConstants.HOUR;
int minutes = (offset % (int) JiveConstants.HOUR) / (int) JiveConstants.MINUTE;
buf.append(hours).append(":");
if (minutes < 10) {
buf.append("0").append(minutes);
......@@ -134,8 +294,23 @@ public class LocaleUtils {
else {
buf.append(minutes);
}
buf.append(" - ").append(zoneID.replace('_', ' ').replace('/', ' ')).append(" ");
buf.append(zone.getDisplayName(true, TimeZone.SHORT, locale).replace('_', ' ').replace('/', ' '));
buf.append(") ");
// Use a friendly english timezone name if the locale is en, otherwise use the timezone id
if ("en".equals(locale.getLanguage())) {
String name = nameMap.get(zoneID);
if (name == null) {
name = zoneID;
}
buf.append(name);
}
else {
buf.append(
zone.getDisplayName(true, TimeZone.LONG, locale).replace('_', ' ').replace('/',
' '));
}
return buf.toString();
}
......@@ -201,12 +376,12 @@ public class LocaleUtils {
* the passed in Locale substituting the passed in arguments. Substitution
* is handled using the {@link java.text.MessageFormat} class.
*
* @param key the key to use for retrieving the string from the
* appropriate resource bundle.
* @param locale the locale to use for retrieving the appropriate
* locale-specific string.
* @param key the key to use for retrieving the string from the
* appropriate resource bundle.
* @param locale the locale to use for retrieving the appropriate
* locale-specific string.
* @param arguments a list of objects to use which are formatted, then
* inserted into the pattern at the appropriate places.
* inserted into the pattern at the appropriate places.
* @return the localized string.
*/
public static String getLocalizedString(String key, Locale locale, List arguments) {
......@@ -217,7 +392,7 @@ public class LocaleUtils {
locale = JiveGlobals.getLocale();
}
String value = "";
String value;
// See if the bundle has a value
try {
......
......@@ -12,13 +12,7 @@
<%@ page import="org.jivesoftware.util.*,
java.util.HashMap,
java.util.Map,
org.jivesoftware.messenger.*,
org.jivesoftware.messenger.user.*,
java.util.*,
java.text.*,
org.jivesoftware.admin.AdminPageBean,
org.jivesoftware.admin.AdminConsole,
javax.servlet.jsp.jstl.core.Config"
java.util.*"
%>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
......@@ -40,6 +34,7 @@
<% // Get parameters //
String localeCode = ParamUtils.getParameter(request,"localeCode");
String timeZoneID = ParamUtils.getParameter(request,"timeZoneID");
boolean save = request.getParameter("save") != null;
Map errors = new HashMap();
......@@ -56,9 +51,21 @@
return;
}
}
// Set the timezeone
try {
TimeZone tz = TimeZone.getTimeZone(timeZoneID);
JiveGlobals.setTimeZone(tz);
}
catch (Exception e) {}
}
Locale locale = JiveGlobals.getLocale();
// Get the time zone list.
String[][] timeZones = LocaleUtils.getTimeZoneList();
// Get the current time zone.
TimeZone timeZone = JiveGlobals.getTimeZone();
%>
<% // Title of this page and breadcrumbs
......@@ -83,7 +90,8 @@
<div style="padding-top:0.5em;">
<p>
<fmt:message key="locale.current" />: <%= locale.getDisplayName() %>
<b><fmt:message key="locale.current" />:</b> <%= locale.getDisplayName(locale) %> /
<%= LocaleUtils.getTimeZoneName(JiveGlobals.getTimeZone().getID(), locale) %>
</p>
<% boolean usingPreset = false;
......@@ -94,7 +102,7 @@
}
%>
<p><b><fmt:message key="locale.choose" />:</b></p>
<p><b><fmt:message key="language.choose" />:</b></p>
<table cellspacing="0" cellpadding="3" border="0">
<tbody>
......@@ -167,6 +175,20 @@
</tbody>
</table>
<br>
<p><b><fmt:message key="timezone.choose" />:</b></p>
<select size="1" name="timeZoneID">
<% for (int i=0; i<timeZones.length; i++) {
String selected = "";
if (timeZone.getID().equals(timeZones[i][0].trim())) {
selected = " selected";
}
%>
<option value="<%= timeZones[i][0] %>"<%= selected %>><%= timeZones[i][1] %>
<% } %>
</select>
</div>
</fieldset>
......@@ -176,14 +198,4 @@
</form>
<jsp:include page="bottom.jsp" flush="true" />
<%!
private String spacer(int length) {
StringBuffer buf = new StringBuffer();
for (int i=0; i<length; i++) {
buf.append("&nbsp;");
}
return buf.toString();
}
%>
\ No newline at end of file
<jsp:include page="bottom.jsp" flush="true" />
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment