当前位置: 首页 > 知识库问答 >
问题:

SimpleDateFormat(不是timezone)支持哪些时区缩写来进行解析?

鲍健柏
2023-03-14

正如我在最初的问题中提到的,一个简单的测试显示,这两个类不支持相同的时区缩写。例如:

  • 时区支持“CTT”,但SimpleDateFormat不支持
  • SimpleDateFormat支持“Cest”,但时区不支持

在哪里(或如何)找到SimpleDateFormat在解析字符串中使用“z”时能够解析的缩写的完整列表,以及每个缩写的含义?

        String time = "12:00:00.000 CST Tue Dec 17 2019";
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS zzz EEE MMM dd yyyy");
        Date utcTime = sdf.parse(time);
        System.out.println(utcTime.toGMTString());
        17 Dec 2019 18:00:00 GMT

时区的Javadocs页面表示:

为了与JDK 1.1.x兼容,还支持其他一些三个字母的时区ID(如“PST”、“CTT”、“AST”)。

但没有说明是哪一个。
它也只提到了三个字母的ID,而上面的代码也可以很好地用于例如CEST(中欧夏令时)。

在哪里可以找到SimpleDateFormat能够解析的缩写列表?

共有1个答案

田骁
2023-03-14

这听起来是一个简单的问题,但答案很复杂。Java支持的时区缩写(无论是现代的DateTimeFormatter还是麻烦过时的SimpleDateFormat)不是由Java本身定义的,而是由Java使用的区域设置数据定义的。并发症包括

  • Java可以配置为从不同的源获取区域设置数据。这意味着在运行程序时设置系统属性java.locale.providers将更改支持的缩写集。
  • 默认的区域设置提供程序从Java8更改为Java9。因此,在不同的Java版本上运行程序将为您提供一组不同的受支持的时区缩写。
  • CLDR是Java9中默认的区域设置数据,有不同的版本。因此,每个新的Java版本都可能带有一组不同的受支持的缩写。
  • 时区缩写有多种语言。因此,法语区域设置的格式化程序将支持其他缩写,而不是德语区域设置的格式化程序。
  • 时区缩写含糊不清。因此,即使PST是受支持的缩写,您也不知道它是解析为皮特凯恩标准时间、太平洋标准时间还是菲律宾标准时间。

一种方法是:运行一个程序,将一年中不同时间的日期格式化为一个时区缩写。由于许多时区使用夏令时(DST)并在夏令时使用不同的缩写,因此您将希望尝试在这些时区的夏令时中设置日期,并在一年中的标准时间中设置日期。

    System.out.println("java.locale.providers: " + System.getProperty("java.locale.providers"));
    DateTimeFormatter zoneAbbreviationFormatter = DateTimeFormatter.ofPattern("zzz", Locale.FRENCH);
    Instant northernSummer = Instant.parse("2019-07-01T00:00:00Z");
    Instant southernSummer = Instant.parse("2020-01-01T00:00:00Z");

    Set<String> supportedAbbreviations = new TreeSet<>();
    for (String zid : ZoneId.getAvailableZoneIds()) {
        ZoneId zone = ZoneId.of(zid);
        supportedAbbreviations.add(northernSummer.atZone(zone).format(zoneAbbreviationFormatter));
        supportedAbbreviations.add(southernSummer.atZone(zone).format(zoneAbbreviationFormatter));
    }

    System.out.println("" + supportedAbbreviations.size() + " abbreviations");
    System.out.println(supportedAbbreviations);
java.locale.providers: null
205 abbreviations
[ACDT, ACST, ACT, ACWST, ADT, AEDT, AEST, AFT, AKDT, AKST, ALMT, AMST, AMT, AQTT, ART, AST, AWST, AZOST, AZOT, AZT, America/Punta_Arenas, Asia/Atyrau, Asia/Barnaul, Asia/Famagusta, Asia/Tomsk, BDT, BNT, BOT, BRST, BRT, BST, BTT, CAT, CCT, CDT, CEST, CET, CHADT, CHAST, CHOT, CHUT, CKT, CLST, CLT, COT, CST, CVT, CXT, ChST, DAVT, DDUT, EASST, EAST, EAT, ECT, EDT, EEST, EET, EGST, EGT, EST, Etc/GMT+1, Etc/GMT+10, Etc/GMT+11, Etc/GMT+12, Etc/GMT+2, Etc/GMT+3, Etc/GMT+4, Etc/GMT+5, Etc/GMT+6, Etc/GMT+7, Etc/GMT+8, Etc/GMT+9, Etc/GMT-1, Etc/GMT-10, Etc/GMT-11, Etc/GMT-12, Etc/GMT-13, Etc/GMT-14, Etc/GMT-2, Etc/GMT-3, Etc/GMT-4, Etc/GMT-5, Etc/GMT-6, Etc/GMT-7, Etc/GMT-8, Etc/GMT-9, Europe/Astrakhan, Europe/Kirov, Europe/Saratov, Europe/Ulyanovsk, FJST, FJT, FKT, FNT, GALT, GAMT, GET, GFT, GILT, GMT, GST, GYT, HADT, HAST, HDT, HKT, HOVT, HST, ICT, IDT, IOT, IRDT, IRKT, IRST, IST, JST, KGT, KOST, KRAT, KST, LHDT, LHST, LINT, MAGT, MART, MAWT, MDT, MEST, MET, MHT, MIST, MMT, MSK, MST, MUT, MVT, MYT, NCT, NDT, NFT, NOVT, NPT, NRT, NST, NUT, NZDT, NZST, OMST, PDT, PET, PETT, PGT, PHOT, PHT, PKT, PMDT, PMST, PONT, PST, PWT, PYST, PYT, RET, ROTT, SAKT, SAMT, SAST, SBT, SCT, SGT, SRET, SRT, SST, SYOT, TAHT, TFT, TJT, TKT, TLT, TMT, TOT, TVT, ULAT, UTC, UYT, UZT, VET, VLAT, VOST, VUT, WAKT, WEST, WET, WFT, WGST, WGT, WIB, WIT, WITA, WSDT, WSST, XJT, YAKT, YEKT]
    Set<String> zids = ZoneId.getAvailableZoneIds();
    Map <String, List<String>> supportedAbbreviations = new TreeMap<>();
    supportedAbbreviations.putAll(zids.stream()
            .collect(Collectors.groupingBy(zid -> northernSummer.atZone(ZoneId.of(zid))
                    .format(zoneAbbreviationFormatter))));
    supportedAbbreviations.putAll(zids.stream()
            .collect(Collectors.groupingBy(zid -> southernSummer.atZone(ZoneId.of(zid))
                    .format(zoneAbbreviationFormatter))));

    System.out.println("" + supportedAbbreviations.size() + " abbreviations");
    supportedAbbreviations.forEach((a, zs) -> System.out.format("%-5s %s%n", a, zs));
205 abbreviations
ACDT  [Australia/Yancowinna, Australia/Adelaide, Australia/Broken_Hill, Australia/South]
ACST  [Australia/North, Australia/Darwin]
ACT   [America/Eirunepe, America/Porto_Acre, Brazil/Acre, America/Rio_Branco]
ACWST [Australia/Eucla]
ADT   [Canada/Atlantic, America/Grand_Turk, America/Moncton, Atlantic/Bermuda, America/Halifax, America/Glace_Bay, America/Thule, America/Goose_Bay, SystemV/AST4ADT]
AEDT  [Australia/Hobart, Australia/Tasmania, Australia/ACT, Australia/Victoria, Australia/Canberra, Australia/Currie, Australia/NSW, Australia/Sydney, Australia/Melbourne]
AEST  [Australia/Queensland, Australia/Brisbane, Australia/Lindeman]
…
WSDT  [Pacific/Apia]
WSST  [Pacific/Apia]
XJT   [Asia/Kashgar, Asia/Urumqi]
YAKT  [Asia/Chita, Asia/Yakutsk, Asia/Khandyga]
YEKT  [Asia/Yekaterinburg]
 类似资料:
  • 我使用下面的下拉列表按UTC偏移量存储应用程序的时区: 使用PHP时,我并没有最简单的方法将这些转换为时区缩写,我唯一的编程方法就是对大约400个时区缩写列表进行排序。有人知道这个下拉列表中的每个时区是什么吗,以及夏令时是什么吗?(我假设我需要手动定义这两个列表) 编辑:将这个列表解析为每个时区的一个缩写,但它们不是“流行”的。

  • 本文向大家介绍详解Java时区处理之Date,Calendar,TimeZone,SimpleDateFormat,包括了详解Java时区处理之Date,Calendar,TimeZone,SimpleDateFormat的使用技巧和注意事项,需要的朋友参考一下 一、概述 1、问题描述 使用Java处理时间时,我们可能会经常发现时间不对,比如相差8个小时等等,其真实原因便是TimeZone。只有正

  • 问题内容: 是的,我知道FAQ会假装回答此问题,但实际上并非如此。相反,它指示您从源代码构建项目(并且构建说明非常复杂)。那种打败了整个观点:) 让我们省去世界上每个人的麻烦,即不必再构建另一个开源项目,以了解它是否真正解决了他们的问题。Xuggler支持哪些编解码器? 问题答案: FAQ不能回答这个问题的原因是,随着我们发布新版本,它会不断变化,并且要使文档中的列表保持最新状态会花费很长时间。但

  • 问题内容: 我正在尝试从java.util.Date格式化日期。我需要这种格式: 。 如何从标准日期格式正确转换 ? 不幸的是,这段代码没有返回值。 问题答案: 只需将z转到upperCase 结果:2016-06-10T13:53:22 +0200

  • 本文向大家介绍有哪些标签是不支持伪元素的?相关面试题,主要包含被问及有哪些标签是不支持伪元素的?时的应答技巧和注意事项,需要的朋友参考一下 首先我们要知道伪元素有哪些: ::after ::before ::first-letter ::fist-line (单双冒号皆可) ::selection ::backdrop (仅双冒号) 伪元素虽然强大,但是还是有一些特定的标签是不支持伪元素 befo

  • 问题内容: 我正在为Android SDK 2.3.3编写一个Android应用程序,但随后我被要求在运行Android 2.2.1的设备上对其进行测试。因此,我将目标设置为8而不是10。但是java.util.concurrent.TimeUnit仅具有Java 1.5功能集,而不是java.util.concurrent.TimeUnit的Java 1.6 / 1.7功能集。因此,我将Time