如何处理带短/长名称的时区格式?Joda时区转换问题
搞定Joda时区识别问题:从自定义字符串提取可用时区
遇到这种自定义格式的时区字符串确实头疼,不过好在里面已经包含了Joda能识别的关键信息,给你几个干净的解决方案,按优先级排序:
1. 优先提取标准时区ID(最靠谱)
你的字符串里明确包含了America/Los Angeles——这是IANA标准时区ID,Joda的DateTimeZone完全支持(甚至空格和下划线的写法都兼容)。用正则直接把这部分抠出来就行:
String rawTimeZone = "[PST -08:00] America/Los Angeles (Pacific Standard Time)"; // 匹配"America/XXX"格式的标准时区ID Pattern tzIdPattern = Pattern.compile("America/\\w+(?:\\s\\w+)?"); Matcher matcher = tzIdPattern.matcher(rawTimeZone); if (matcher.find()) { String validTzId = matcher.group().trim(); DateTimeZone usableZone = DateTimeZone.forID(validTzId); // 拿到这个zone就可以正常处理你的2018/4/22 03:00 pm时间了 }
这个方法的优势是自动处理夏令时,洛杉矶时区有PST(冬令时)和PDT(夏令时),用标准ID的话Joda会自动根据日期切换偏移,比硬编码偏移量准确得多。
2. 提取UTC偏移量作为 fallback
如果标准ID提取失败(比如字符串格式有变动),可以退而求其次提取里面的-08:00偏移量,创建固定偏移的时区:
String rawTimeZone = "[PST -08:00] America/Los Angeles (Pacific Standard Time)"; Pattern offsetPattern = Pattern.compile("([+-]\\d{2}:\\d{2})"); Matcher offsetMatcher = offsetPattern.matcher(rawTimeZone); if (offsetMatcher.find()) { String offsetStr = offsetMatcher.group(); // 把偏移字符串转成毫秒数 int hours = Integer.parseInt(offsetStr.substring(1, 3)); int mins = Integer.parseInt(offsetStr.substring(4)); int offsetMillis = (hours * 60 + mins) * 60 * 1000; if (offsetStr.startsWith("-")) { offsetMillis = -offsetMillis; } DateTimeZone fixedOffsetZone = DateTimeZone.forOffsetMillis(offsetMillis); }
⚠️ 注意:这个方法是固定偏移,不会自动切换夏令时,如果你的时间刚好跨夏令时切换日,结果可能会有误差,所以只当备选方案用。
3. 通用正则适配更多时区格式
如果你的系统里可能出现其他地区的时区字符串(比如[CET +01:00] Europe/Paris (Central European Time)),可以用更通用的正则匹配Region/City格式的标准ID:
Pattern generalTzPattern = Pattern.compile("([A-Za-z]+/[A-Za-z\\s]+)"); Matcher generalMatcher = generalTzPattern.matcher(rawTimeZone); if (generalMatcher.find()) { String validId = generalMatcher.group().trim(); DateTimeZone zone = DateTimeZone.forID(validId); }
这个正则能匹配大多数IANA标准时区ID的写法,trim是为了去掉可能的前后空格。
为什么原字符串无法直接识别?
Joda的DateTimeZone.forID()只接受两种格式:
- IANA标准时区ID(比如
America/Los_Angeles或America/Los Angeles) - UTC偏移格式(比如
UTC-08:00)
你的原字符串是自定义的组合格式,自然不符合要求,所以必须提取出里面的有效部分才行。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

