Java 中的时区 IDjava.time.ZoneId关于 java.time

2022-09-01 22:37:29

我在Java时区遇到了奇怪的问题。

调用 TimeZone.getDefault() 会给出我的本地时区,其 ID 为“GMT+02:00”。有趣的是,这个ID没有出现在TimeZone.getAvailableIDs()提供的列表中。显然,我的区域似乎是“Etc / GMT + 2”。

我正在尝试用时区填充组合,但无法进行选择,因为GMT + 02:00不在列表中。有人看到这个问题吗?有什么想法吗?


更新:

底线是 - 不能依赖ID字符串,必须与偏移量一起使用,因为显示ID可能因系统而异。


答案 1

GMT + 02:00是一个自定义ID,它不会出现在(这是巨大的)的输出中。您可以做的是要求用户首先指定其偏移量,然后获取给定偏移量的可用 ID。例如,对于 GMT+02:00,以下代码段:TimeZone.getAvailableIDs()

for (String string : TimeZone.getAvailableIDs(TimeZone.getTimeZone(
        "GMT+02:00").getRawOffset())) {
    System.out.println(string);
}

给出以下输出:

ART
Africa/Blantyre
Africa/Bujumbura
Africa/Cairo
Africa/Gaborone
Africa/Harare
Africa/Johannesburg
Africa/Kigali
Africa/Lubumbashi
Africa/Lusaka
Africa/Maputo
Africa/Maseru
Africa/Mbabane
Africa/Tripoli
Asia/Amman
Asia/Beirut
Asia/Damascus
Asia/Gaza
Asia/Istanbul
Asia/Jerusalem
Asia/Nicosia
Asia/Tel_Aviv
CAT
EET
Egypt
Etc/GMT-2
Europe/Athens
Europe/Bucharest
Europe/Chisinau
Europe/Helsinki
Europe/Istanbul
Europe/Kaliningrad
Europe/Kiev
Europe/Mariehamn
Europe/Minsk
Europe/Nicosia
Europe/Riga
Europe/Simferopol
Europe/Sofia
Europe/Tallinn
Europe/Tiraspol
Europe/Uzhgorod
Europe/Vilnius
Europe/Zaporozhye
Israel
Libya
Turkey

它仍然很大,但这次是人类可浏览的。


答案 2

java.time.ZoneId

TimeZone是麻烦的旧日期时间类的一部分,这些类现在是遗留的,被java.time类所取代。

在您的情况下,请查看 ZoneId 和 .与 UTC 的偏移量是小时数和分钟数。时区是某个区域在不同时间段内使用的过去、现在和未来偏移量的历史记录。ZoneOffset

通过 ZoneId.getAvailableZoneIds 获取所有已知区域的集合。确保您的 JVM 最近已更新,其中包含有关您感兴趣的所有时区的信息。政客们有一种令人惊讶的倾向,即经常改变区域定义,通常几乎没有预先警告。

Set < String > ids = ZoneId.getAvailableZoneIds() ;

截至 Java 8 Update 144。

[亚洲/亚丁,美洲/库亚巴等/GMT+9等/GMT+8,非洲/内罗毕,美洲/马里戈特,亚洲/阿克套,太平洋/夸贾林,美洲/El_Salvador,亚洲/坤甸,非洲/开罗,太平洋/Pago_Pago,非洲/姆巴巴纳,亚洲/古晋,太平洋/檀香山,太平洋/拉罗汤加,美洲/危地马拉,澳大利亚/霍巴特,欧洲/伦敦,美洲/伯利兹,美洲/巴拿马,亚洲/重庆,美洲/马那瓜,美国/印第安纳州/彼得堡,亚洲/埃里温,欧洲/布鲁塞尔, GMT, 欧洲/华沙, 美国/芝加哥, 亚洲/喀什, 智利/大陆, 太平洋/雅浦, CET, etc/GMT-1, etc/GMT-0, 欧洲/泽西, 美国/特古西加尔巴, etc/GMT-5, 欧洲/伊斯坦布尔, 美国/Eirunepe, etc/GMT-4, America/Miquelon, etc/GMT-3, Europe/Luxembourg, etc/GMT-2, etc/GMT-9, america/argentina/Catamarca, etc/GMT-8, etc/GMT-7, etc/GMT-7, etc/GMT-6, Europe/Zaporozhye, Canada/Yukon, Canada/Atlantic, Atlantic/St_Helena, 澳大利亚/塔斯马尼亚、利比亚、欧洲/根西岛、美洲/Grand_Turk、美国/太平洋-新、亚洲/撒马尔罕、美洲/阿根廷/科尔多瓦、亚洲/Phnom_Penh、非洲/基加利、亚洲/阿拉木图、美国/阿拉斯加、亚洲/迪拜、欧洲/Isle_of_Man、美洲/阿拉瓜纳、古巴、亚洲/新西伯利亚、美洲/阿根廷/萨尔塔等/GMT+3、非洲/突尼斯等/GMT+2、等/GMT+1、太平洋/法考福、非洲/的黎波里等/GMT+0, 以色列,非洲/班珠尔等/GMT+7,印度/科摩罗等/GMT+6,等/GMT+5,等/GMT+4,太平洋/Port_Moresby,美国/亚利桑那州,南极洲/肖瓦,印度/留尼汪岛,太平洋/帕劳,欧洲/加里宁格勒,美洲/蒙得维的亚,非洲/温得和克,亚洲/卡拉奇,非洲/摩加迪沙,澳大利亚/珀斯,巴西/东部,等/GMT,亚洲/赤塔,太平洋/复活节,南极洲/戴维斯,南极洲/麦克默多,亚洲/澳门,美国/马瑙斯, 非洲/弗里敦、欧洲/布加勒斯特、亚洲/托木斯克、美洲/阿根廷/门多萨、亚洲/澳门、欧洲/马耳他、墨西哥/巴哈苏尔、太平洋/塔希提岛、非洲/阿斯美拉、欧洲/布辛根、美洲/阿根廷/Rio_Gallegos、非洲/马拉博、欧洲/斯科普里、美洲/卡塔马卡、美洲/戈德萨布、欧洲/萨拉热窝、澳大利亚/澳大利亚首都领地、英国-爱尔兰、非洲/拉各斯、美洲/科尔多瓦、欧洲/罗马、亚洲/达卡、印度/毛里求斯、太平洋/萨摩亚、美国/里贾纳、美洲/Fort_Wayne、美洲/Dawson_Creek、 非洲/阿尔及尔,欧洲/玛丽港,美洲/St_Johns,美洲/St_Thomas,欧洲/苏黎世,美洲/安圭拉,亚洲/帝力,美洲/丹佛,非洲/巴马科,欧洲/萨拉托夫,英国,墨西哥/一般,太平洋/瓦利斯,欧洲/直布罗陀,非洲/科纳克里,非洲/卢本巴希,亚洲/伊斯坦布尔,美洲/哈瓦那,新西兰-CHAT,亚洲/乔巴山,美洲/Porto_Acre,亚洲/鄂木斯克,欧洲/瓦杜兹,美国/密歇根州,亚洲/达卡,美洲/巴巴多斯,欧洲/蒂拉斯波尔,大西洋/Cape_Verde, 亚洲/叶卡捷琳堡,美洲/路易斯维尔,太平洋/约翰斯顿,太平洋/查塔姆,欧洲/卢布尔雅那,美洲/Sao_Paulo,亚洲/查亚普拉,美洲/库拉索,亚洲/杜尚别,美洲/圭亚那,美洲/瓜亚基尔,美洲/马提尼克岛,葡萄牙,欧洲/柏林,欧洲/莫斯科,欧洲/基希讷乌,美洲/Puerto_Rico,美洲/Rankin_Inlet,太平洋/波纳佩,欧洲/斯德哥尔摩,欧洲/布达佩斯,美国/阿根廷/胡胡伊,澳大利亚/尤克拉,亚洲/上海,环球,欧洲/萨格勒布,美洲/Port_of_Spain, 欧洲/赫尔辛基、亚洲/贝鲁特、亚洲/Tel_Aviv、太平洋/布干维尔、美国/中部、非洲/Sao_Tome、印度/查戈斯、美洲/卡宴、亚洲/雅库茨克、太平洋/加拉帕戈斯、澳大利亚/北部、欧洲/巴黎、非洲/恩贾梅纳、太平洋/斐济、美洲/Rainy_River、印度/马尔代夫、澳大利亚/扬科温纳、SystemV/AST4、亚洲/口头、美洲/耶洛奈夫、太平洋/恩德伯里、美国/朱诺、澳大利亚/维多利亚、美国/印第安纳/韦韦、亚洲/塔什干、亚洲/雅加达、 非洲/休达, 亚洲/巴尔瑙尔, 美洲/累西腓, 美洲/Buenos_Aires, 美洲/诺罗尼亚, 美洲/Swift_Current, 澳大利亚/阿德尔助手, 美洲/梅特拉卡特拉, 非洲/吉布提, 美洲/帕拉马里博, 欧洲/辛菲罗波尔, 欧洲/索非亚, 非洲/努瓦克肖特, 欧洲/布拉格, 美国/印第安纳/文森, 南极洲/莫森, 美国/克拉伦代克, 南极洲/巨魔, 欧洲/萨马拉, 印度/圣诞节, 美国/安提瓜, 太平洋/甘比尔, 美国/印第安纳波利斯, 美国/伊努维克, 美国/伊卡卢伊特, 太平洋/富纳富提, UTC, 南极洲/麦格理, 加拿大/太平洋, 美国/蒙克顿, 非洲/哈博罗内, 太平洋/楚克, 亚洲/平壤, 美国/St_文森特,亚洲/加沙等/通用,PST8PDT,大西洋/法罗,亚洲/Qyzylorda,加拿大/纽芬兰,美国/肯塔基州/路易斯维尔,美国/雅库塔特,亚洲/Ho_Chi_Minh,南极洲/凯西,欧洲/哥本哈根,非洲/阿斯马拉,大西洋/亚速尔群岛,欧洲/维也纳,韩国,太平洋/皮特凯恩,美国/马萨特兰,澳大利亚/昆士兰,太平洋/瑙鲁,欧洲/地拉,亚洲/加尔各答,SystemV / MST7,澳大利亚/堪培拉,MET,澳大利亚/Broken_Hill,欧洲/里加,美国/多米尼克, 非洲/阿比让,美洲/门多萨,美洲/圣塔伦,夸贾林,美洲/亚松森,亚洲/Ulan_Bator,新西兰,美国/博伊西,澳大利亚/柯里,EST5EDT,太平洋/关岛,太平洋/威克,大西洋/百慕大,美洲/Costa_Rica,美国/道森,亚洲/重庆,爱尔兰,欧洲/阿姆斯特丹,美国/印第安纳/诺克斯,美国/North_Dakota/比尤拉,非洲/阿克拉,大西洋/法罗,墨西哥/巴哈诺特,美国/马塞约等/UCT,太平洋/阿皮亚,GMT0,美国/阿特卡, 太平洋/纽埃、加拿大/东萨斯喀彻温省、澳大利亚/Lord_Howe、欧洲/都柏林、太平洋/特鲁克、MST7MDT、美洲/蒙特雷、美洲/拿骚、美洲/牙买加、亚洲/比什凯克、美洲/阿蒂科坎、大西洋/斯坦利、澳大利亚/新南威尔士州、美国/夏威夷、SystemV/CST6、印度/马埃岛、亚洲/阿克托比、美洲/锡特卡、亚洲/符拉迪沃斯托克、非洲/利伯维尔、非洲/马普托、祖鲁、美国/肯塔基/蒙蒂塞洛、非洲/El_Aaiun、非洲/瓦加杜古、美洲/Coral_Harbour、太平洋/马克萨斯、 巴西/西部,美洲/阿鲁巴,美洲/North_Dakota/中心,美洲/开曼,亚洲/乌兰巴托,亚洲/巴格达,欧洲/San_Marino,美洲/印第安纳/Tell_City,美洲/蒂华纳,太平洋/塞班岛,SystemV /YST9,非洲/杜阿拉,美洲/奇瓦瓦州,美洲/奥吉纳加,亚洲/霍夫,美洲/安克雷奇,智利/复活节岛,美国/哈利法克斯,南极洲/罗特拉,美国/印第安纳州/印第安纳波利斯,美国/山地,亚洲/大马士革,美洲/阿根廷/San_Luis,美国/圣地亚哥, 亚洲/巴库、美洲/阿根廷/乌斯怀亚、大西洋/雷克雅未克、非洲/布拉柴维尔、非洲/波多诺伏、美洲/La_Paz、南极洲/杜蒙德维尔、亚洲/台北、南极洲/South_Pole、亚洲/马尼拉、亚洲/曼谷、非洲/Dar_es_Salaam、波兰、大西洋/马德拉、南极洲/帕尔默、美洲/Thunder_Bay、非洲/Addis_Ababa、亚洲/仰光、欧洲/乌日哥罗德、巴西/德诺罗尼亚、亚洲/阿什哈巴德等/祖鲁、美洲/印第安纳/马伦戈、美洲/克雷斯顿、美洲/Punta_Arenas、 美洲/Mexico_City、南极洲/东方、亚洲/耶路撒冷、欧洲/安道尔、美国/萨摩亚、中国、亚洲/万象、太平洋/基里蒂马蒂、美洲/马塔莫罗斯、美洲/布兰克-萨布隆、亚洲/利雅得、冰岛、太平洋/波纳佩、亚洲/Ujung_Pandang、大西洋/South_Georgia、欧洲/里斯本、亚洲/哈尔滨、欧洲/奥斯陆、亚洲/新库兹涅茨克、CST6CDT、大西洋/加那利、美洲/Knox_IN、亚洲/科威特、SystemV/HST10、太平洋/埃法特、非洲/洛美、美洲/波哥大、美洲/梅诺米尼、 美洲/阿达克,太平洋/诺福克,欧洲/基洛夫,美国/Resolute,太平洋/塔拉瓦,非洲/坎帕拉,亚洲/克拉斯诺亚尔斯克,格林威治,SystemV/EST5,美国/埃德蒙顿,欧洲/波德戈里察,澳大利亚/南部,加拿大/中部,非洲/布琼布拉,美洲/Santo_Domingo,美国/东方,欧洲/明斯克,太平洋/奥克兰,非洲/卡萨布兰卡,美国/Glace_Bay,加拿大/东方,亚洲/卡塔尔,欧洲/基辅,新加坡, 亚洲/马加丹, SystemV/PST8, 美洲/太子港, 欧洲/贝尔法斯特, 美洲/St_Barthelemy, 亚洲/阿什哈巴德, 非洲/罗安达, 美洲/尼皮贡, 大西洋/Jan_Mayen, 巴西/英亩, 亚洲/马斯喀特, 亚洲/巴林, 欧洲/维尔纽斯, 美洲/福塔雷萨等/GMT0, 美国/东印第安纳州, 美国/埃莫西约, 美洲/坎昆, 非洲/马塞卢, 太平洋/科斯雷, 非洲/金沙萨, 亚洲/加德满都, 亚洲/首尔, 澳大利亚/悉尼, 美国/利马, 澳大利亚/LHI, 美洲/St_Lucia, 欧洲/马德里、美洲/Bahia_Banderas、美洲/蒙特塞拉特、亚洲/文莱、美洲/Santa_Isabel、加拿大/山区、美洲/Cambridge_Bay、亚洲/科伦坡、澳大利亚/西部、印度/塔那那利佛、澳大利亚/布里斯班、印度/马约特岛、美国/印第安纳-斯塔克、亚洲/乌鲁木齐、美国/阿留申群岛、欧洲/伏尔加格勒、美洲/Lower_Princes、美洲/温哥华、非洲/布兰太尔、美洲/Rio_Branco、美洲/丹麦港、美洲/底特律、美洲/图勒、非洲/卢萨卡、亚洲/Hong_Kong、 伊朗,美国/阿根廷/La_Rioja,非洲/达喀尔,SystemV / CST6CDT,美国/托尔托拉,美国/Porto_Velho,亚洲/萨哈林等/GMT + 10,美洲/Scoresbysund,亚洲/堪察加半岛,亚洲/廷布,非洲/哈拉雷等/GMT + 12,等/ GMT + 11,纳瓦霍,美国/诺姆,欧洲/塔林,土耳其,非洲/喀土穆,非洲/约翰内斯堡,非洲/班吉,欧洲/贝尔格莱德,牙买加,非洲/几内亚比绍,亚洲/德黑兰,WET,欧洲/阿斯特拉罕,非洲/朱巴, 美洲/Campo_Grande,美洲/贝伦等/格林威治,亚洲/西贡,美洲/恩塞纳达,太平洋/中途岛,美洲/胡胡伊,非洲/廷巴克图,美洲/巴伊亚州,美洲/Goose_Bay,美国/维珍,美国/潘尼尔东,亚洲/加德满都,美洲/凤凰城,非洲/尼亚美,美洲/怀特霍斯,太平洋/努美,亚洲/第比利斯,美洲/蒙特利尔,亚洲/望加锡,美洲/阿根廷/San_Juan,香港,UCT,亚洲/尼科西亚,美洲/印第安纳州/Winamac,SystemV / MST7MDT,美国/阿根廷/ComodRivadavia, 美洲/Boa_Vista,美洲/格林纳达,亚洲/阿特劳,澳大利亚/达尔文,亚洲/坎迪加,亚洲/Kuala_Lumpur,亚洲/法马古斯塔,亚洲/廷布,亚洲/仰光,欧洲/布拉迪斯拉发,亚洲/加尔各答,美洲/阿根廷/图库曼,亚洲/喀布尔,印度/科科斯,日本,太平洋/汤加塔布,美国/New_York等/GMT-12,等/GMT-11等/GMT-10,SystemV/YST9YDT,欧洲/乌里扬诺夫斯克等/GMT-14,等/GMT-13,W-SU,美国/梅里达,EET,美国/罗萨里奥, 加拿大/萨斯喀彻温省,美洲/St_Kitts,北极/朗伊尔城,美洲/Fort_Nelson,美洲/加拉加斯,美洲/瓜德罗普岛,亚洲/希伯伦,印度/开格朗,SystemV / PST8PDT,非洲/蒙罗维亚,亚洲/东内拉,埃及,亚洲/Srednekolymsk,美洲/North_Dakota/New_Salem,亚洲/阿纳德尔,澳大利亚/墨尔本,亚洲/伊尔库茨克,美洲/Shiprock,美国/温尼伯,欧洲/梵蒂冈,亚洲/安曼,等/UTC,SystemV / AST4ADT,亚洲/东京,美洲/多伦多,亚洲/新加坡, 澳大利亚/林德曼、美国/Los_Angeles、SystemV/EST5EDT、太平洋/马朱罗、美国/阿根廷/Buenos_Aires、欧洲/尼科西亚、太平洋/瓜达尔卡纳尔岛、欧洲/雅典、美国/太平洋、欧洲/摩纳哥]

获取 JVM 的当前默认时区

ZoneId z = ZoneId.systemDefault() ; 

美洲/Los_Angeles

请注意,JVM 的缺省值可以在运行时的任何时刻由 JVM 中任何应用程序的任何线程中的任何代码更改。通常,最好指定所需/预期的时区,而不是依赖于系统默认值。

以 的格式指定适当的时区名称,例如 美国/蒙特利尔非洲/卡萨布兰卡或 。切勿使用3-4个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。continent/regionPacific/AucklandESTIST

ZoneId z = ZoneId.of( "America/Montreal" ) ;

如果您想知道特定区域在特定时刻播放的偏移量,请通过对象进行询问。ZoneRules

ZoneOffset offsetInEffectNow = z.getRules().getOffset( Instant.now() );

查看上述所有代码,这些代码在 IdeOne.com 实时运行

底线是 - 不能依赖ID字符串,必须与偏移量一起使用,因为显示ID可能因系统而异。

否,时区标识符已记录在案且一致。在 IANA 跟踪的维基百科中查看此列表

我不太了解在做什么,但如果像其他遗留的日期时间类一样,它可能不是明智地设计的。也不确定您的主机操作系统和JVM是如何配置的。很难诊断,因为你没有提供足够的信息。TimeZone


关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle 教程。搜索 Stack Overflow 以获取许多示例和解释。规格是JSR 310

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过其他类扩展了 java.time。这个项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter


推荐