Android TimeZone.getAvailableIDs()产生奇怪的字符串

问题描述 投票:1回答:1

我有一个使用TimeZone.getAvailableIDs()提取所有可用时区ID字符串的Android应用程序。这些ID按照以下内容保存到ArrayList

ArrayList<String> clocks = new ArrayList<>();
String[] ids = TimeZone.getAvailableIDs();
Collections.addAll(clocks, ids);

此ArrayList稍后用于使用我的自定义BaseAdapter填充ListView。有些条目不是特别有用,我也不希望它们出现在列表中,例如:

Etc/GMT+10
PST8PDT
NZ-CHAT

我添加了一个for循环来遍历所有条目,并删除所有不需要的条目,目前我出于测试目的进行了以下检查:

String string = clocks.get(i);
String[] split = string.split("/");

if(string.equals("MST7MDT")) {
    clocks.remove(i);
}

if(string.contains("Etc/")) {
    clocks.remove(i);
}

if(split.length <= 1) {
    clocks.remove(i);
}

if(!string.contains("/")) {
    clocks.remove(i);
}

现在,这应该删除与“ MST7MDT”相同的一个(它不删除),任何包含“ Etc /”的(仅删除Etc/example元素的一半)以及不包含“ / ”拆分一号应执行相同操作(并非全部删除)。我已经用trim()尝试过,但没有帮助。 remove(int)似乎不是问题,我也尝试传递对象,但仍然没有。

[任何帮助将不胜感激,TimeZone.getAvailableIDs()的结果是否有其他人遇到问题?我在这里想念一些愚蠢的东西吗?

java android arraylist timezone baseadapter
1个回答
1
投票

保留区域,而不是丢弃区域

正如我们在list of time zone names on Wikipedia中所看到的,这些年来,这些区域已经发生了变化和演变。许多条目仅仅是其他区域的别名。许多人构思不当,现已弃用。

我建议您不要关注要删除的区域,而是要关注要保留的区域。该答案的其余部分显示了如何。

TimeZone.getAvailableIDs()

TimeZone类在几年前被java.time.ZoneId类所取代。切勿使用可怕的旧时区,例如TimeZoneDateCalendar

各大洲列表

作为获取清理清单的第一步,我建议过滤以这些大洲之一开头的名称:

  • 欧洲
  • 非洲
  • 南极洲
  • 大西洋
  • 美国
  • 太平洋
  • 印度
  • 澳大利亚

并且在用户根本不需要时区时添加Etc/UTC条目。

在Java代码中,按字母顺序排序。

List < String > zoneGroupNames = List.of(
        "Africa" ,
        "Antarctica" ,
        "Atlantic" ,
        "America" ,
        "Australia" ,
        "Europe" ,
        "Indian" ,
        "Pacific" ,
        "UTC"
);

我建议您为用户提供一个两步过程,他们首先建议一个大陆,然后一个区域。

区域组名称与区域名称的多重映射

为每个区域组名称构建Map以收集区域ID名称。我们需要一个组名(例如Map)到区域名称列表(例如EuropeEurope/BerlinEurope/London)的映射。

Europe/Malta

将键映射到值的集合称为“多图”。现在,我们具有内置的多图功能,并且Java捆绑了Map < String, List < String > > mapGroupNameToZoneNames = new TreeMap <>(); 实现。呼叫Map(请参阅Map::computeIfAbsent)。

Map::computeIfAbsent

this Answer添加一个条目。

Set < String > zoneIdStrings = ZoneId.getAvailableZoneIds();
for ( String zoneIdString : zoneIdStrings )
{
    String groupName = zoneIdString.split( "/" )[ 0 ];
    if ( zoneGroupNames.contains( groupName ) )
    {
        mapGroupNameToZoneNames.computeIfAbsent( groupName , ( x -> new ArrayList <>() ) ).add( zoneIdString );
    } // Else skip it.
}

System.out.println( "mapGroupNameToZoneNames = " + mapGroupNameToZoneNames );

呈现给用户

向用户显示该组列表。假设用户选择了项目#6(索引5),当前为Etc/UTC

mapGroupNameToZoneNames.computeIfAbsent( "Etc" , ( x -> new ArrayList <>() ) ).add( "UTC" );

呈现该组的区域名称列表。假设用户选择了项目#12(索引11),当前为Europe

String groupNameChosenByUser = zoneGroupNames.get( 5 ); // Europe
List < String > zoneNamesOfGroup = mapGroupNameToZoneNames.get( groupNameChosenByUser );

从该区域名称的字符串中创建Europe/Malta对象。

String zoneNameChosenByUser = zoneNamesOfGroup.get( 11 );  // Malta

zoneIdChosenByUser.toString()=欧洲/马耳他


关于java.time

ZoneId框架内置于Java 8及更高版本中。这些类取代了麻烦的旧ZoneId zoneIdChosenByUser = ZoneId.of( zoneNameChosenByUser ); 日期时间类,例如java.timelegacyjava.util.Date

要了解更多信息,请参见java.util.Date。并在Stack Overflow中搜索许多示例和说明。规格为Calendar

Calendar项目现在位于SimpleDateFormat中,建议迁移到SimpleDateFormat类。

您可以直接与数据库交换java.time对象。使用兼容Oracle Tutorial或更高版本的JSR 310。不需要字符串,不需要Joda-Time类。

从哪里获取java.time类?

© www.soinside.com 2019 - 2024. All rights reserved.