msf4j微服务框架 ParseException: Unparsable date: "2019-01-01 00:00:00" 异常处理

最近遇到一个问题,前端接口在往后端接口传值的时候,时间字符串(比如:2019-01-01 00:00:00)转 timestamp 出错了,导致接口调用失败,同样的代码,在windows上运行是OK的,但是到linux或者mac上就会出现异常,初步怀疑是Windows和linux/Mac的时区不一致导致的,于是在mac和Linux上输出系统语言和系统区域,结果都是中文:

说明系统语言设置是没问题的,于是接着使用debug模式一步一步找到异常的地方,终于发现了问题出现在这里:

根据msf4j的源代码所呈现时间转换逻辑:

  1. 在类 DateTypeAdapter中,声明了3个用于转换的DateFormat 实例,分别是:
  • enUsFormat 美国语言
  • localFormat 本地语言
  • iso8601Format iso8601标准
  1. 接下来调用转换方法private synchronized Date deserializeToDate(String json)string转换为Date对象,完成转换

不过很不幸的是,在linux 和 mac中,全都转换失败,只有在windows下才会转换成功,通过在debug模式下查找,发现原因在创建DateFormat实例的时候DateFormat.getDateTimeInstance(),mac模式下获取到的locale是en_CN

windows模式下获取到的locale是zh_CN:

所以问题就在en_CNzh_CN这里,其中,enzh表示的是系统语言,en表示英语(一般指美国英语),zh表示中文,CN表示国家-中国,换个方式看可能更好理解:

        Locale locale = Locale.getDefault();
        System.out.println(locale.getLanguage());//输出系统语言代码
        System.out.println(locale.getCountry());//输出系统国家代码
        System.out.println(locale.getDisplayLanguage());//输出系统语言名称
        System.out.println(locale.getDisplayCountry());//输出系统国家名称





输出结果为:

不过即使输出为中文和中国,但是也还有可能出错,因为在实例 DateFormat localFormat = DateFormat.getDateTimeInstance(2, 2) 创建的过程中,并不需要指定locale,该方法会去使用一个系统默认语言Local.Category.Format:

public final static DateFormat getDateTimeInstance(int dateStyle,
                                                       int timeStyle)
    {
        return get(timeStyle, dateStyle, 3, Locale.getDefault(Locale.Category.FORMAT));
    }


这时候如果mac系统中的语言是中文加上英文,像这样:

Locale.Category.Format获取到的language就会是en,所以就变成了en_CN(英文_中国),然后转换就是失败了

所以解决办法就是在创建DateFormat实例之前,给jvm设置Locale.setDefault(Locale.CHINA),这样就避免了jvm在查找系统语言的过程中找到除了中文语言之外的其他语言,造成转换失败的异常

当然,如果把英文删除,只保留中文,则不用设置LocaleCHINA也没问题了,所以linux 上也是如此,在系统语言中,设置了不止一个中文语言,还包括英语,虽然第一语言是中文。

转载于:https://my.oschina.net/u/4118973/blog/3097162

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值