程序中的日期使用问题-格式转化:SimpleDateFormat、org.apache.commons.lang3.time.DateUtils

  • Post author:
  • Post category:其他




前言

日期使用问题主要是格式转换的问题

场景:通过excel导入数据,其中一个字段为出生日期,需要对字段值进行合法性校验

博客地址:

芒果橙的个人博客

【http://mangocheng.com】



一、个人浅谈日期


时间日期作为一个基础的标识和维度,基本上所有的业务都会涉及到,因此凡是涉及到业务的数据表,都可能会加上类似创建时间、操作时间的字段。在程序开发中,前端、后端、数据库在进行数据的传递过程中,对于时间的格式就存在要求,这部分也正是问题的触发点,即格式的转换。




二、日期格式转换遇到的问题



1. 场景:通过excel导入数据,其中一个字段为出生日期,需要对字段值进行合法性校验



2. 使用过程



1)使用SimpleDateFormat进行日期转化,如果抛出异常则说明填入的出生日期有误


1. 日期的分隔符不同

try {
            String birthDate = "2000-12-31";
            SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
            format.parse(birthDate);
            System.out.println("日期正常");
        } catch (ParseException e) {
            System.out.println("日期格式有误");
        }
  • 输出:日期格式有误

  • 原因:格式不对,输入的分割符为



    ,转化的格式为

    /


2. 非法日期

// 出生日期为12月32日
try {
            String birthDate = "2000-12-32".replaceAll("-","/");
            SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
            format.parse(birthDate);
            System.out.println("日期正常");
        } catch (ParseException e) {
            System.out.println("日期格式有误");
            e.printStackTrace();
        }
  • 输出:日期正常
  • 原因:后面说明

  • 重点:虽然是12月32日,但并不会抛出异常,当时是很奇怪的,怎么会是正常的,但我没有多想,觉得是不是SimpleDateFormat本身的转化存在缺陷,于是我想着换另一个工具类



2)使用apache的org.apache.commons.lang3.time.DateUtils

  1. 非法日期
try {
            String birthDate = "2000-12-32".replaceAll("-", "");
            SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
            org.apache.commons.lang3.time.DateUtils.parseDate(birthDate,"yyyyMMdd");
            System.out.println("日期正常");
        } catch (ParseException e) {
            System.out.println("日期格式有误");
        }
  • 输出:日期正常
  • 原因:与1相同

  • 我再次认为是本身工具类的问题,于是我选择了用公司封装的工具类



3)使用公司的日期工具类

  1. 非法日期
try {
            String birthDate = "2000-12-32";
            birthDate = DateUtils.formatDate(format.parse(birthDate));
          	System.out.println("日期正常");
        } catch (ParseException e) {
            System.out.println("日期格式有误");
        }
  • 输出:日期格式有误
  • 原因:非法日期,没有12月32日

  • 用公司的工具类就正常,其他第三方的工具类反而有错,于是我搜索了下,终于明白了,原来日期转换有一个属性是lenient



3. 结论:lenient属性是关键

  1. lenient属性(默认为true):

    日期转换有一个属性是lenient——是否宽松转换(不严格解析),即如果输入的日期不合法,但能转换为日期,在不严格解析(lenient=true)时,不会抛出异常,而是会自动计算出一个新的日期(2000-12-32转换为2001-1-1)

  2. DateFormat源码:DateFormat.parse()

在这里插入图片描述

  1. 测试
  • 设置严格解析:lenient=false

    try {
                String birthDate = "2000-12-32".replaceAll("-","/");
                SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        		// 严格解析
                format.setLenient(false);
                Date newDate = format.parse(birthDate);
                System.out.println("日期正常");
                System.out.println("转化后的日期:" + newDate);
            } catch (ParseException e) {
                System.out.println("日期格式有误");
            }
    
    • 输出:日期格式有误
  • SimpleDateFormat和org.apache.commons.lang3.time.DateUtils默认设置为不严格解析,而刚好公司的工具类使用的日期格式器是spring框架的DateFormatter,为严格解析

    • org.apache.commons.lang3.time.DateUtils

      在这里插入图片描述

    • spring框架的日期格式器类

      在这里插入图片描述



版权声明:本文为qq_35893033原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。