如何从带时区缩写的日期字符串中获取对应的ZoneId
Java解析带时区缩写的时间戳方案
首先给出结论:不需要自行硬编码GMT、BST的映射关系,Java内置的时间解析API已经支持直接识别这两类时区缩写,可以按以下方式处理:
- 首先纠正你当前用法的隐患:你现在使用的
SimpleDateFormat格式串没有匹配时区部分,解析时会默认使用JVM的本地时区,得到的Date对象时区是错误的。同时SimpleDateFormat是线程不安全的类,多线程环境下共用实例会出现解析异常,更推荐使用Java8+提供的java.time系列API实现解析。 - 如果你坚持使用
SimpleDateFormat,可以直接在格式串中增加z占位符匹配时区缩写,注意必须指定英文Locale,否则英文月份、时区缩写会解析失败:SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy HH:mm:ss z", Locale.ENGLISH); Date gmtDate = sdf.parse("21-Mar-21 05:01:26 GMT"); Date bstDate = sdf.parse("19-Jul-21 1:08:22 BST");注意:如果你的时间是24小时制,需要把格式串里的
hh改为HH,避免12小时制的上下午识别错误。 - 更推荐的Java8+
java.time实现方式,不存在线程安全问题,解析逻辑更严谨:// 构建解析器,指定英文Locale适配英文月份、时区缩写 DateTimeFormatter formatter = new DateTimeFormatterBuilder() .appendPattern("dd-MMM-yy HH:mm:ss z") .toFormatter(Locale.ENGLISH); // 直接解析得到带有时区信息的ZonedDateTime对象 ZonedDateTime gmtTime = ZonedDateTime.parse("21-Mar-21 05:01:26 GMT", formatter); ZonedDateTime bstTime = ZonedDateTime.parse("19-Jul-21 1:08:22 BST", formatter); // 转为标准时间戳 long gmtTimestamp = gmtTime.toInstant().toEpochMilli(); long bstTimestamp = bstTime.toInstant().toEpochMilli(); - 只有当你遇到以下两种情况时,才需要自行硬编码时区映射:
- 出现内置API无法识别的生僻时区缩写
- 出现存在歧义的时区缩写(比如CST可指代中国标准时间、美国中部时间等多种时区)
此时可以在构建DateTimeFormatter时传入自定义的时区映射表即可。
内容的提问来源于stack exchange,提问作者P.Ellis
相关产品推荐
相关产品推荐

