Android 我想在API 23上以UTC格式显示时区的完整列表

Android 我想在API 23上以UTC格式显示时区的完整列表,android,timezone,java-7,utc,Android,Timezone,Java 7,Utc,我需要显示自定义活动,其中包含一个列表视图,按照以下格式显示所有时区: ZoneID (UTC <+/-> hh:mm) 只需获取ThreenABP并将其添加到您的Android项目中,就可以使用ZoneId和java.time中的其他功能。java.time是java 8附带的现代java日期和时间API,也被后传到java 6和java 7 链接 ,其中首先描述了java.time ,java.time的后端口到Java6和Java7(JSR-310为三十) ,Andro

我需要显示自定义活动,其中包含一个列表视图,按照以下格式显示所有时区:

ZoneID   (UTC <+/-> hh:mm)

只需获取ThreenABP并将其添加到您的Android项目中,就可以使用
ZoneId
和java.time中的其他功能。java.time是java 8附带的现代java日期和时间API,也被后传到java 6和java 7

链接
  • ,其中首先描述了
    java.time
  • ,java.time的后端口到Java6和Java7(JSR-310为三十)
  • ,Android版Three Ten Backport
  • ,解释得非常透彻

使用
java.util.TimeZone
列表,并按偏移量对其排序:

String[] ids = TimeZone.getAvailableIDs();
List<TimeZone> zones = new ArrayList<>();
for (String id : ids) {
    zones.add(TimeZone.getTimeZone(id));
}
Collections.sort(zones, new Comparator<TimeZone>() {
    // compare by the offset, reverse order
    @Override
    public int compare(TimeZone o1, TimeZone o2) {
        return o1.getRawOffset() - o2.getRawOffset();
}});
public String formatOffset(int rawOffset) {
    StringBuilder sb = new StringBuilder("UTC").append(rawOffset < 0 ? "-" : "+");
    int secs = Math.abs(rawOffset) / 1000;
    int hours = secs / 3600;
    secs -= hours * 3600;
    int mins = secs / 60;
    sb.append(hours < 10 ? "0" : "").append(hours).append(":");
    sb.append(mins < 10 ? "0" : "").append(mins);
    return sb.toString();
}

for (TimeZone tz : zones) {
    System.out.println(tz.getID() + " (" + formatOffset(tz.getRawOffset()) + ")");
}
注意,我没有包括“漂亮的标签”格式,这取决于你

我还使用了
getRawOffset
,它返回该区域的当前偏移量-检查javadoc:

该方法不考虑夏令时变化或任何其他历史数据(比如过去使用不同偏移的国家,相信我,大多数国家——如果不是全部的话——在历史上至少有一个偏移变化)。要使用这些其他偏移量,可以使用
getOffset
方法,将参考日期/时间戳作为参数传递-查看javadoc以了解详细信息

我还使用了
getAvailableIDs
,它返回所有时区,但您可以筛选此列表,使其仅包含您想要的时区


但是老实说,这个旧API(
java.util
日期
日历
简单格式
时区
等等)非常糟糕,有很多缺陷和恼人的bug,没有人值得再使用它们。特别是今天,我们有了更好的API

在没有
java.time
类(例如
ZoneId
)的API级别中,您可以使用ThreeTen Backport,正如在另一个答案中所述。然后你可以按照你找到的例子

一个主要区别是,此API始终需要一个
即时
作为获取偏移量的引用-因为它检查所有时区的历史数据,以了解在该特定时刻使用的偏移量(在下面的代码中,我使用的是当前即时):

Set availableZoneIds=ZoneId.getAvailableZoneIds();
列出时区=新建ArrayList();
for(字符串id:AvailableZoneId){
时区。添加(id的区域id);
}
//当前瞬间
final Instant now=Instant.now();
Collections.sort(时区、新比较器(){
//以相反的顺序按偏移量进行比较,使用瞬间作为参考
@凌驾
公共整数比较(分区o1、分区o2){
返回o2.getRules().getOffset(现在).compareTo(o1.getRules().getOffset(现在));
}
});
用于(区域ID区域:时区){
ZoneOffset offset=zone.getRules().getOffset(现在);
System.out.println(zone+“(UTC”+(offset.getTotalSeconds()==0?”+00:00):offset.toString())+”);
}
还要注意的是,
ZoneOffset
类有一个很好的
toString()
方法,它已经以正确的格式打印了偏移量(当偏移量为零时除外,它被打印为
Z
,但这并不难修复)。

作为对的补充,您可以使用格式化程序打印区域和偏移量:

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("VV '(UTC'xxx')'");
for (ZoneId zone : timezones) {
    System.out.println(fmt.format(now.atZone(zone)));
}

它产生相同的输出:“VV”打印区域ID,“xxx”打印偏移量。

使用Joda时间的解决方案:

首先使用DateTimeZone类获取所有ID,然后使用DateTimeZone.getOffset(Instant)方法对它们进行排序。考虑不同于java.util提供的夏令时

Set<String> availableIDs = DateTimeZone.getAvailableIDs();
    List<DateTimeZone> dateTimezones = new ArrayList<>();

    for (String id : availableIDs) {
        dateTimezones.add(DateTimeZone.forID(id));
    }

    final Instant now = Instant.now();
    Collections.sort(dateTimezones, new Comparator<DateTimeZone>() {

        @Override
        public int compare(DateTimeZone o1, DateTimeZone o2) {
            return o1.getOffset(now)-o2.getOffset(now);
        }
    });
    for (DateTimeZone dateTimeZone : dateTimezones) {
        int offset = dateTimeZone.getOffset(now);
        String out = String.format("%35s %s%n", dateTimeZone, " (" + formatOffset(offset) + ")");
        System.out.printf(out);
    }
Set availableIDs=DateTimeZone.getAvailableIDs();
List dateTimezones=new ArrayList();
for(字符串id:availableIDs){
添加(DateTimeZone.forID(id));
}
final Instant now=Instant.now();
Collections.sort(dateTimezones,newcomparator(){
@凌驾
公共整数比较(日期时区o1,日期时区o2){
返回o1.getOffset(现在)-o2.getOffset(现在);
}
});
对于(DateTimeZone DateTimeZone:dateTimezones){
int offset=dateTimeZone.getOffset(现在);
String out=String.format(“%35s%s%n”,dateTimeZone,”(“+formatOffset(offset)+”);
系统输出打印F(输出);
}
formatOffset(int)从上述示例中重用

链接:


要下载Joda Time

?只需按UTC按升序排序。非常感谢+1.详细答案。但是正如你已经说过的,时区不考虑日光节约,我不能实时使用它,因为它可能会导致显示的时间错误。
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
List<ZoneId> timezones = new ArrayList<>();
for (String id : availableZoneIds) {
    timezones.add(ZoneId.of(id));
}
// current instant
final Instant now = Instant.now();
Collections.sort(timezones, new Comparator<ZoneId>() {

    // compare by offset in reverse order, use the Instant as a reference
    @Override
    public int compare(ZoneId o1, ZoneId o2) {
        return o2.getRules().getOffset(now).compareTo(o1.getRules().getOffset(now));
    }
});
for (ZoneId zone : timezones) {
    ZoneOffset offset = zone.getRules().getOffset(now);
    System.out.println(zone + " (UTC" + (offset.getTotalSeconds() == 0 ? "+00:00" : offset.toString()) + ")");
}
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("VV '(UTC'xxx')'");
for (ZoneId zone : timezones) {
    System.out.println(fmt.format(now.atZone(zone)));
}
Set<String> availableIDs = DateTimeZone.getAvailableIDs();
    List<DateTimeZone> dateTimezones = new ArrayList<>();

    for (String id : availableIDs) {
        dateTimezones.add(DateTimeZone.forID(id));
    }

    final Instant now = Instant.now();
    Collections.sort(dateTimezones, new Comparator<DateTimeZone>() {

        @Override
        public int compare(DateTimeZone o1, DateTimeZone o2) {
            return o1.getOffset(now)-o2.getOffset(now);
        }
    });
    for (DateTimeZone dateTimeZone : dateTimezones) {
        int offset = dateTimeZone.getOffset(now);
        String out = String.format("%35s %s%n", dateTimeZone, " (" + formatOffset(offset) + ")");
        System.out.printf(out);
    }