Java解析BST时区时间偏移异常:预期UTC+1实际得到+11
BST时区解析偏移异常原因
BST是多义时区缩写,同时对应两种时区规则:
- 你预期的英国夏令时(British Summer Time),偏移为UTC+1,仅在英国每年3-10月生效,所属时区ID为
Europe/London - 布干维尔标准时间(Bougainville Standard Time),偏移为UTC+11,是太平洋布干维尔地区的全年标准时区,所属时区ID为
Pacific/Bougainville
Java 8+的java.time包使用z格式符解析短时区名称时,会优先匹配内置映射表中排序靠前的时区,你的运行环境中BST默认匹配到了UTC+11的布干维尔标准时间,才会出现和预期不符的输出。
修复方案
方案1:修改时间串使用唯一时区ID(最稳妥)
如果可以调整输入的时间字符串格式,直接将缩写BST替换为唯一的时区IDEurope/London,彻底消除歧义:
// 调整后的时间字符串 final String lastUpdated = "Mon Sep 27 18:29:00 Europe/London 2021"; // 注意时区ID使用VV格式符匹配 final DateTimeFormatter LAST_UPDATED_FORMATTER = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss VV y") .withLocale(Locale.UK);
方案2:自定义时区缩写映射(无需修改输入)
如果不能修改输入的时间字符串,可以在构造格式化器时强制指定BST对应英国时区:
final DateTimeFormatter LAST_UPDATED_FORMATTER = new DateTimeFormatterBuilder() .appendPattern("EEE MMM dd HH:mm:ss ") // 仅匹配Europe/London时区的短名称 .appendZoneText(TextStyle.SHORT, Collections.singleton(ZoneId.of("Europe/London"))) .appendPattern(" y") .toFormatter(Locale.UK);
方案3:格式化器强制绑定目标时区
如果确定所有输入的BST都指代英国夏令时,也可以直接给格式化器绑定英国时区,强制覆盖解析得到的歧义时区:
final DateTimeFormatter LAST_UPDATED_FORMATTER = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z y") .withLocale(Locale.UK) // 强制使用英国时区 .withZone(ZoneId.of("Europe/London"));
以上任意方案修复后,解析得到的偏移量都会是预期的+01:00,对应的UTC时间为2021-09-27T17:29。
内容的提问来源于stack exchange,提问作者alibaab
相关产品推荐
相关产品推荐

