
org.jruby.util.TimeZoneConverter Maven / Gradle / Ivy
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.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.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/
package org.jruby.util;
import java.util.List;
/**
* This is utility class to convert given timezone into integer based timezone
* diff. It's ported from ext/date/date_parse.c in MRI 2.3.1 under BSDL.
*/
// @see https://github.com/ruby/ruby/blob/394fa89c67722d35bdda89f10c7de5c304a5efb1/ext/date/date_parse.c
public class TimeZoneConverter {
// Ports zones_source in ext/date/date_parse.c in MRI 2.3.1 under BSDL.
private static int getOffsetFromZonesSource(String z) {
switch (z) {
case "ut":
return 0 * 3600;
case "gmt":
return 0 * 3600;
case "est":
return -5 * 3600;
case "edt":
return -4 * 3600;
case "cst":
return -6 * 3600;
case "cdt":
return -5 * 3600;
case "mst":
return -7 * 3600;
case "mdt":
return -6 * 3600;
case "pst":
return -8 * 3600;
case "pdt":
return -7 * 3600;
case "a":
return 1 * 3600;
case "b":
return 2 * 3600;
case "c":
return 3 * 3600;
case "d":
return 4 * 3600;
case "e":
return 5 * 3600;
case "f":
return 6 * 3600;
case "g":
return 7 * 3600;
case "h":
return 8 * 3600;
case "i":
return 9 * 3600;
case "k":
return 10 * 3600;
case "l":
return 11 * 3600;
case "m":
return 12 * 3600;
case "n":
return -1 * 3600;
case "o":
return -2 * 3600;
case "p":
return -3 * 3600;
case "q":
return -4 * 3600;
case "r":
return -5 * 3600;
case "s":
return -6 * 3600;
case "t":
return -7 * 3600;
case "u":
return -8 * 3600;
case "v":
return -9 * 3600;
case "w":
return -10 * 3600;
case "x":
return -11 * 3600;
case "y":
return -12 * 3600;
case "z":
return 0 * 3600;
case "utc":
return 0 * 3600;
case "wet":
return 0 * 3600;
case "at":
return -2 * 3600;
case "brst":
return -2 * 3600;
case "ndt":
return -(2 * 3600 + 1800);
case "art":
return -3 * 3600;
case "adt":
return -3 * 3600;
case "brt":
return -3 * 3600;
case "clst":
return -3 * 3600;
case "nst":
return -(3 * 3600 + 1800);
case "ast":
return -4 * 3600;
case "clt":
return -4 * 3600;
case "akdt":
return -8 * 3600;
case "ydt":
return -8 * 3600;
case "akst":
return -9 * 3600;
case "hadt":
return -9 * 3600;
case "hdt":
return -9 * 3600;
case "yst":
return -9 * 3600;
case "ahst":
return -10 * 3600;
case "cat":
return -10 * 3600;
case "hast":
return -10 * 3600;
case "hst":
return -10 * 3600;
case "nt":
return -11 * 3600;
case "idlw":
return -12 * 3600;
case "bst":
return 1 * 3600;
case "cet":
return 1 * 3600;
case "fwt":
return 1 * 3600;
case "met":
return 1 * 3600;
case "mewt":
return 1 * 3600;
case "mez":
return 1 * 3600;
case "swt":
return 1 * 3600;
case "wat":
return 1 * 3600;
case "west":
return 1 * 3600;
case "cest":
return 2 * 3600;
case "eet":
return 2 * 3600;
case "fst":
return 2 * 3600;
case "mest":
return 2 * 3600;
case "mesz":
return 2 * 3600;
case "sast":
return 2 * 3600;
case "sst":
return 2 * 3600;
case "bt":
return 3 * 3600;
case "eat":
return 3 * 3600;
case "eest":
return 3 * 3600;
case "msk":
return 3 * 3600;
case "msd":
return 4 * 3600;
case "zp4":
return 4 * 3600;
case "zp5":
return 5 * 3600;
case "ist":
return 5 * 3600 + 1800;
case "zp6":
return 6 * 3600;
case "wast":
return 7 * 3600;
case "cct":
return 8 * 3600;
case "sgt":
return 8 * 3600;
case "wadt":
return 8 * 3600;
case "jst":
return 9 * 3600;
case "kst":
return 9 * 3600;
case "east":
return 10 * 3600;
case "gst":
return 10 * 3600;
case "eadt":
return 11 * 3600;
case "idle":
return 12 * 3600;
case "nzst":
return 12 * 3600;
case "nzt":
return 12 * 3600;
case "nzdt":
return 13 * 3600;
case "afghanistan":
return 16200;
case "alaskan":
return -32400;
case "arab":
return 10800;
case "arabian":
return 14400;
case "arabic":
return 10800;
case "atlantic":
return -14400;
case "aus central":
return 34200;
case "aus eastern":
return 36000;
case "azores":
return -3600;
case "canada central":
return -21600;
case "cape verde":
return -3600;
case "caucasus":
return 14400;
case "cen. australia":
return 34200;
case "central america":
return -21600;
case "central asia":
return 21600;
case "central europe":
return 3600;
case "central european":
return 3600;
case "central pacific":
return 39600;
case "central":
return -21600;
case "china":
return 28800;
case "dateline":
return -43200;
case "e. africa":
return 10800;
case "e. australia":
return 36000;
case "e. europe":
return 7200;
case "e. south america":
return -10800;
case "eastern":
return -18000;
case "egypt":
return 7200;
case "ekaterinburg":
return 18000;
case "fiji":
return 43200;
case "fle":
return 7200;
case "greenland":
return -10800;
case "greenwich":
return 0;
case "gtb":
return 7200;
case "hawaiian":
return -36000;
case "india":
return 19800;
case "iran":
return 12600;
case "jerusalem":
return 7200;
case "korea":
return 32400;
case "mexico":
return -21600;
case "mid-atlantic":
return -7200;
case "mountain":
return -25200;
case "myanmar":
return 23400;
case "n. central asia":
return 21600;
case "nepal":
return 20700;
case "new zealand":
return 43200;
case "newfoundland":
return -12600;
case "north asia east":
return 28800;
case "north asia":
return 25200;
case "pacific sa":
return -14400;
case "pacific":
return -28800;
case "romance":
return 3600;
case "russian":
return 10800;
case "sa eastern":
return -10800;
case "sa pacific":
return -18000;
case "sa western":
return -14400;
case "samoa":
return -39600;
case "se asia":
return 25200;
case "malay peninsula":
return 28800;
case "south africa":
return 7200;
case "sri lanka":
return 21600;
case "taipei":
return 28800;
case "tasmania":
return 36000;
case "tokyo":
return 32400;
case "tonga":
return 46800;
case "us eastern":
return -18000;
case "us mountain":
return -25200;
case "vladivostok":
return 36000;
case "w. australia":
return 28800;
case "w. central africa":
return 3600;
case "w. europe":
return 3600;
case "west asia":
return 18000;
case "west pacific":
return 36000;
case "yakutsk":
return 32400;
default:
return Integer.MIN_VALUE;
}
}
public static final int INVALID_ZONE = Integer.MIN_VALUE;
/**
* Ports date_zone_to_diff from ext/date/date_parse.c in MRI 2.3.1 under BSDL.
*/
public static int dateZoneToDiff(String zone) {
String z = zone.toLowerCase();
final boolean dst;
if (z.endsWith(" daylight time")) {
z = z.substring(0, z.length() - " daylight time".length());
dst = true;
} else if (z.endsWith(" standard time")) {
z = z.substring(0, z.length() - " standard time".length());
dst = false;
} else if (z.endsWith(" dst")) {
z = z.substring(0, z.length() - " dst".length());
dst = true;
} else {
dst = false;
}
int offsetFromZonesSource;
if ((offsetFromZonesSource = getOffsetFromZonesSource(z)) != Integer.MIN_VALUE) {
if (dst) {
offsetFromZonesSource += 3600;
}
return offsetFromZonesSource;
}
if (z.startsWith("gmt") || z.startsWith("utc")) {
z = z.substring(3, z.length()); // remove "gmt" or "utc"
}
final boolean sign;
if (z.charAt(0) == '+') {
sign = true;
} else if (z.charAt(0) == '-') {
sign = false;
} else {
// if z doesn't start with "+" or "-", invalid
return INVALID_ZONE;
}
z = z.substring(1);
int hour = 0, min = 0, sec = 0;
if (z.indexOf(':') != -1) {
final List splited = StringSupport.split(z, ':');
if (splited.size() == 2) {
hour = Integer.parseInt(splited.get(0));
min = Integer.parseInt(splited.get(1));
} else {
hour = Integer.parseInt(splited.get(0));
min = Integer.parseInt(splited.get(1));
sec = Integer.parseInt(splited.get(2));
}
} else if (z.indexOf(',') != -1 || z.indexOf('.') != -1) {
// TODO min = Rational(fr.to_i, 10**fr.size) * 60
String[] splited = z.split("[\\.,]");
hour = Integer.parseInt(splited[0]);
min = (int) (Integer.parseInt(splited[1]) * 60 / Math.pow(10, splited[1].length()));
} else {
final int len = z.length();
if (len % 2 != 0) {
if (len >= 1) {
hour = Integer.parseInt(z.substring(0, 1));
}
if (len >= 3) {
min = Integer.parseInt(z.substring(1, 3));
}
if (len >= 5) {
sec = Integer.parseInt(z.substring(3, 5));
}
} else {
if (len >= 2) {
hour = Integer.parseInt(z.substring(0, 2));
}
if (len >= 4) {
min = Integer.parseInt(z.substring(2, 4));
}
if (len >= 6) {
sec = Integer.parseInt(z.substring(4, 6));
}
}
}
final int offset = hour * 3600 + min * 60 + sec;
return sign ? offset : -offset;
}
private TimeZoneConverter() { /* no instances */ }
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy