跨环境日期解析异常求助:Mac端正常PC端报Unparsable date
问题根源与解决办法
嘿,这个问题我之前也碰到过!核心原因是系统默认区域设置(Locale)不一致导致的日期解析失败,具体来说:
- 你用的
SimpleDateFormat格式里的MMM代表月份缩写(比如Jan、Feb这类),这个解析逻辑完全依赖系统默认的Locale。你的Mac默认应该是英文Locale,所以能正常识别英文月份缩写;但学校的PC大概率默认是中文或者其他非英文Locale,解析时认不出英文的月份缩写,就抛出Unparsable date异常了。
快速修复:显式指定英文Locale
创建SimpleDateFormat的时候,手动传入英文Locale,强制用英文规则解析日期,不管系统默认设置是什么,这样在任何机器上都能正常运行。
修改后的代码如下:
public static List<BusPosition> readBusPositions() throws ParseException { String wholeText = Utils.readFile("busPositionsNew.txt"); List<String> lines = Arrays.asList(wholeText.split("\\n")); List<BusPosition> busPositions = new ArrayList<>(); // 关键:显式指定英文Locale,避免系统Locale差异影响解析 SimpleDateFormat format = new SimpleDateFormat("MMM dd yyyy hh:mm:ss:SSSa", Locale.ENGLISH); for (String line : lines) { String[] split = line.split(","); double latitude = new BigDecimal(split[3]).doubleValue(); double longitude = new BigDecimal(split[4]).doubleValue(); Date timestamp = format.parse(split[5]); busPositions.add(new BusPosition(split[0], split[1], split[2], latitude, longitude, timestamp)); } return busPositions; }
更推荐的方案:使用Java 8+的新日期API
SimpleDateFormat其实是个老古董了,线程不安全不说,API设计也有点反人类。Java 8之后推出的java.time包(比如DateTimeFormatter)更靠谱,不仅线程安全,还能更直观地处理日期,同样可以指定Locale:
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Locale; // 替换原有的SimpleDateFormat部分 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy hh:mm:ss:SSSa", Locale.ENGLISH); // 解析成LocalDateTime,要是需要Date类型可以再做转换 LocalDateTime timestamp = LocalDateTime.parse(split[5], formatter);
这样既解决了当前的Locale问题,还能避免后续可能遇到的线程安全坑,一举两得~
内容的提问来源于stack exchange,提问作者vkatsou




