如何获取指定ISO国家代码的时区ID?

5
我有一个需求,需要将时区从UTC转换到特定的时区,反之亦然,并考虑夏令时。我正在使用java.util.TimeZone类来实现。现在的问题是,有几百个时区ID不能显示给用户。

现在我们决定首先列出国家列表,然后根据所选国家列出时区列表作为解决方法。我无法获取ISO国家代码TimeZone

这是我目前用于转换时区的代码:

Timestamp convertedTime = null;
try{
System.out.println("timezone: "+timeZone +", timestamp: "+timeStamp);
Locale locale = Locale.ENGLISH;
        TimeZone destTimeZone = TimeZone.getTimeZone(timeZone);// TimeZone.getDefault();
        System.out.println("Source timezone: "+destTimeZone);
        DateFormat formatter = DateFormat.getDateTimeInstance(
                    DateFormat.DEFAULT,
                    DateFormat.DEFAULT,
                    locale);
        formatter.setTimeZone(destTimeZone);
        Date date = new Date(timeStamp.getTime());
        System.out.println(formatter.format(date));
        convertedTime = new Timestamp(date.getTime());
        /*long sixMonths = 150L * 24 * 3600 * 1000;
        Date inSixMonths = new Date(timeStamp.getTime() + sixMonths);
        System.out.println("After 6 months: "+formatter.format(inSixMonths));

我需要找出时区ID,以便在上述代码中使用给定的国家ISO代码。


更新:尝试了很多方法,下面的代码可以让我列出148个条目的时区列表(仍然很大)。有人能帮我缩短它吗?或者,建议其他方法来获得一个国家的缩短时区列表或时区,

代码:

public class TimeZones {

private static final String TIMEZONE_ID_PREFIXES =
  "^(Africa|America|Asia|Atlantic|Australia|Europe|Indian|Pacific)/.*";

private List<TimeZone> timeZones = null;

public List<TimeZone> getTimeZones() {
  if (timeZones == null) {
     initTimeZones();
  }

  return timeZones;
}

private void initTimeZones() {
  timeZones = new ArrayList<TimeZone>();
  final String[] timeZoneIds = TimeZone.getAvailableIDs();
  for (final String id : timeZoneIds) {
     if (id.matches(TIMEZONE_ID_PREFIXES)) {
        timeZones.add(TimeZone.getTimeZone(id));
     }
  }
  Collections.sort(timeZones, new Comparator<TimeZone>() {
     public int compare(final TimeZone a, final TimeZone b) {
        return a.getID().compareTo(b.getID());
     }
  });
}
3个回答

4

我认为ICU4J包会对你有所帮助。


感谢Namal的及时回复,这是一个很好的库。但是当我使用美国作为国家代码进行测试时,它给出了大量的时区列表(约50个)。根据我的理解,美国有四个时区(如果我错了,请纠正我)。我该如何获得缩短的列表呢? - Mayank
嘿,大家好,我必须尽快完成这个任务。请求是否有人可以帮助我缩短时区ID列表。 - Mayank
@user1474720:我很久以前使用过这个库。如果我们不考虑夏威夷时间和阿拉斯加时间,美国有4个时区,即太平洋时间、山地时间、中部时间和东部时间。你能给我们提供美国的时区列表吗?然后我们可以查看到底发生了什么。 - ironwood
我使用的代码如下:static void useICU4j(){ try{ String[] timeZoneIds = com.ibm.icu.util.TimeZone.getAvailableIDs("US"); System.out.println("时区ID:"); for(int i=0;i<timeZoneIds.length;i++){ System.out.println(timeZoneIds[i]); } }catch(Exception e){e.printStackTrace();} } - Mayank
@Namal,如果你有时间看一下上面的代码/ICU4j,我会非常感激。我已经在苦苦挣扎了两天多了。尝试了很多东西,但似乎没有什么像预期那样工作。 - Mayank
显示剩余2条评论

0

你可以使用 hasSameRules() 来缩短列表... 这应该将你的选择减少到大约50个:

遍历 -> 文件相同的时区 -> 选择最具代表性的

国家列表必须有大约200个条目,其中包括很多无趣的条目,例如直布罗陀或圣马丁岛... 不喜欢这个想法。


由于java.util TimeZone提供了一个比较方法(hasSameRules),您可以将690个时间代码分组并将它们减少到大约40到50个可识别的代码。 - Franz Ebner
for(int i = 0; i < TimeZoneIds.length; i++){ TimeZone tz = TimeZone.getTimeZone(TimeZoneIds[i]); if(i==0){ timez.add(tz); }else{ Iterator<TimeZone> iter = timez.iterator(); boolean sameRule = false; while(null != iter && iter.hasNext()){ if(tz.hasSameRules(iter.next())){ sameRule = true; break; } } if(!sameRule){ timez.add(tz); finalList.add(tz.getID()); } } - Mayank
即使使用四个空格缩进代码,我仍无法添加代码。请忽略此问题。如果我有遗漏,请帮忙指出。谢谢。 - Mayank
由于我以前从未尝试过这种方法,似乎它并没有按预期工作。它显示出(只要hasSameRules被正确实现-它的java.util),有许多不同的TZs。下一步可以尝试的是(为了减少时区但会丢失信息)迭代偏移量并对其进行分组。如果您这样做,将失去所有其他信息,但保留偏移量。 - Franz Ebner
@Namal,我在初始帖子中添加了代码,成功地得到了一个更短的列表。如果你能进一步减少它,我将非常感激你的帮助。 - Mayank
显示剩余2条评论

0

已经成功让事情运作起来了。我创建了自己的数据库表格,其中包含所有出现在Windows操作系统中的时区及其对应的时区ID。转换是使用java.util.TimeZone类完成的。

感谢Namal和Frank提供的意见。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接