从GMT值计算时区 - Android

时间:2013-05-11 07:37:21

标签: java android timezone timezone-offset


在Android表单中,我接受来自用户的GMT值(偏移),如+5:30,+ 3:00。
从这个值,我想计算“印度/德里”的时区。

关于如何做的任何想法...... Plzz

3 个答案:

答案 0 :(得分:4)

如果您已经具有该偏移量有效的特定时刻,您可以执行以下操作:

import java.util.*;

public class Test {

    public static void main(String [] args) throws Exception {
        // Five and a half hours
        int offsetMilliseconds = (5 * 60 + 30) * 60 * 1000;
        for (String id : findTimeZones(System.currentTimeMillis(),
                                       offsetMilliseconds)) {
            System.out.println(id);
        }
    }

    public static List<String> findTimeZones(long instant,
                                             int offsetMilliseconds) {
        List<String> ret = new ArrayList<String>();
        for (String id : TimeZone.getAvailableIDs()) {
            TimeZone zone = TimeZone.getTimeZone(id);
            if (zone.getOffset(instant) == offsetMilliseconds) {
                ret.add(id);
            }
        }
        return ret;
    }
}

在我打印的方框上打印:

Asia/Calcutta
Asia/Colombo
Asia/Kolkata
IST

(据我所知,印度/德里不是有效的zoneinfo ID。)

如果您不知道偏移量有效的瞬间,真正正确地执行此操作会变得更加困难。这是一个版本:

public static List<String> findTimeZones(int offsetMilliseconds) {
    List<String> ret = new ArrayList<String>();
    for (String id : TimeZone.getAvailableIDs()) {
        TimeZone zone = TimeZone.getTimeZone(id);
        if (zone.getRawOffset() == offsetMilliseconds ||
            zone.getRawOffset() + zone.getDSTSavings() == offsetMilliseconds) {
            ret.add(id);
        }
    }
    return ret;
}

...但是假设每个时区只有两个偏移,实际上时区可以在历史上发生很大变化。当然,它还为您提供了更广泛的ID。例如,一小时的偏移将包括欧洲/伦敦和欧洲/巴黎,因为在夏季伦敦时间为UTC + 1,而冬季巴黎时间为UTC + 1.

答案 1 :(得分:1)

许多时区 ID 可以具有相同的时区偏移

通常,时区 ID 和时区偏移之间的关系是多对一的,即许多时区 ID 可以具有相同的时区偏移。事实上,由于 DST,一个时区 ID 可以有两个时区偏移,例如时区 ID“欧洲/伦敦”的时区偏移量分别为“+00:00”和“+01:00”in the summer and in the winter

除此之外,还有一些例子是,国家的时区偏移被其统治者/政治家多次更改,Ole V.V. 也提到过。在以下评论中:

<块引用>

时区 ID 和时区偏移量之间的关系是多对一的…… 如果您正在考虑某个时间点,则为真。如果回顾历史, 真的是多对多。

所以,考虑到 DST 和这些历史事件,我们可以说时区 ID 和时区偏移之间的关系是多对多的。

使用 ZoneId.getAvailableZoneIds()(现代日期时间 API)的解决方案:

您可以遍历ZoneId来过滤和收集ZoneOffset,其ZoneOffset等于使用输入偏移字符串创建的import java.time.Instant; import java.time.ZoneId; import java.time.ZoneOffset; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { // Test System.out.println(getTimeZoneId("+5:30")); System.out.println(getTimeZoneId("-5:00")); } static List<String> getTimeZoneId(String input) { List<String> list = new ArrayList<>(); // Convert +5:30 to +05:30; similarly, -5:00 to -05:00 String[] arr = input.split(":"); if (arr.length == 2) { input = arr[0].substring(0, 1) + String.format("%02d", Integer.parseInt(arr[0].replaceAll("\\D", ""))) + ":" + arr[1]; ZoneOffset offset = ZoneOffset.of(input); Instant now = Instant.now(); list = ZoneId.getAvailableZoneIds() .stream() .filter(tzId -> ZoneId.of(tzId).getRules().getOffset(now).equals(offset)) .collect(Collectors.toList()); } return list; } }

演示:

[Asia/Kolkata, Asia/Colombo, Asia/Calcutta]
[America/Panama, America/Chicago, America/Eirunepe, Etc/GMT+5, Mexico/General, America/Porto_Acre, America/Guayaquil, America/Rankin_Inlet, US/Central, America/Rainy_River, America/Indiana/Knox, America/North_Dakota/Beulah, America/Monterrey, America/Jamaica, America/Atikokan, America/Coral_Harbour, America/North_Dakota/Center, America/Cayman, America/Indiana/Tell_City, America/Mexico_City, America/Matamoros, CST6CDT, America/Knox_IN, America/Bogota, America/Menominee, America/Resolute, SystemV/EST5, Canada/Central, Brazil/Acre, America/Cancun, America/Lima, America/Bahia_Banderas, US/Indiana-Starke, America/Rio_Branco, SystemV/CST6CDT, Jamaica, America/Merida, America/North_Dakota/New_Salem, America/Winnipeg]

输出:

\D

ONLINE DEMO

注意:正则表达式模式 {{1}} 指定一个非数字字符。

Trail: Date Time 了解有关现代 Date-Time API 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

答案 2 :(得分:-1)

如果我已正确解释您的问题,请尝试此操作,

final SimpleDateFormat date=
        new SimpleDateFormat("EEE, MMM d, yyyy hh:mm:ss a z");
date.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("GMT time: " + date.format(currentTime));

在此您可以添加偏移量。看看这对你有帮助。