使用正则表达式对日期字符串、时间戳字符串的检查及格式归一化

详见代码注释。

    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd hh:mm:ss";
    public static final String YYYY_MM_DD_HH_MM_SS_SSS = "yyyy-MM-dd HH:mm:ss.SSS";
 /**
     * 归一化日期字符串。可自动判断处理到毫秒。功能:
     * <ul>
     *     <li>可处理10、13位的时间戳</li>
     *     <li>可处理阿拉伯数字顺序表示的年、月、日、小时、分钟、秒、毫秒</li>
     *     <li>不能处理时区表示法,以及含英文月、星期字符格式。可含非字母分隔符号,如:: / - 空格 制表等</li>
     *     <li>各部分数值必须满足其自身要求,如月:1-12等,年月日不满足时返回null,
     *     小时不满足时返回年月日,分钟、秒、毫秒不满足时,该值部分及后续部分自动设为0</li>
     * </ul>
     * 要求:
     * <ul>
     *   <li>日期或时间各部分之间可以使用任意非字母分隔符(数量不限)</li>
     *   <li>日期或时间各部分之间无分隔时必须满足各部分的位数要求:年为四位,其他为两位,不足时要前缀0</li>
     *   <li>输入字符串中必须含年月日,否则返回null!</li>
     *   </ul>
     * 特殊示例:
     * <ul>
     *   <li>"2020/- 1 //4 20 30 15 120"处理为"2020-01-04 20:30:15.120"</li>
     *   <li>"2020/- 1 //4 20 "处理为"2020-01-04 20:00:00"</li>
     *   <li>"2020/- 1 //4  "处理为"2020-01-04"</li>
     *   <li>"20200104  "处理为"2020-01-04"</li>
     *   <li>"20200104 12:24:36 350 "处理为"2020-01-04 12:24:36.320"</li>
     *   <li>"2020/ 1" 返回null;</li>
     * </ul>
     *
     * @param dateString 日期字符串
     * @return 返回null、yyyy-MM-dd、yyyy-MM-dd HH:mm:ss、yyyy-MM-dd HH:mm:ss.SSS
     * @date 2023/12/20 14:09
     * @author MuYi
     */
    public static String normalizedDateStr(final String dateString) {
        if (StringUtils.isBlank(dateString)) {
            return null;
        }

        if (dateString.matches(".*[a-zA-Z].*")) return null;
        String dateStr = dateString.trim();
        int len = dateStr.length();
        //时间戳
        if (len == 10 || len == 13) {
            try {
                long time;
                if (dateStr.matches("^[1-9][1-12][1-31]$")) {
                    time = Long.parseLong(dateStr) * 1000L;
                    return new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS).format(new Date(time));
                } else if (dateStr.matches("^[1-9][0-9]{12}$")) {
                    time = Long.parseLong(dateStr);
                    return new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS_SSS).format(new Date(time));
                }
            } catch (Exception e) {
                return null;
            }
        }
        String ymd = "", hmss = "";
        //年月日部分
        //匹配:yyyyMMdd
        String regex = "([1-3]{1}[0-9]{3})(\\d{2})(\\d{2})";
        ymd = getYMD(regex, dateStr);
        if (ymd == null) {
            //匹配:yyyy分隔符M分隔符d
            regex = "([1-3]{1}[0-9]{3})(?:\\D+)(\\d{1,2})(?:\\D+)(\\d{1,2})";
            ymd = getYMD(regex, dateStr);
            if (ymd == null) return null;
        }
        //移除年月日部分
        String hmsStr = dateStr.replaceAll(regex, "");
        //匹配:h分隔符m分隔符s分隔符S
        regex = "(?:\\D+)(\\d{1,2})(?:\\D+)?(\\d{1,2})?(?:\\D+)?(\\d{1,2})?(?:\\D+)?(\\d{1,3})?";
        hmss = getHMSS(regex, hmsStr);
        if (hmss == null) {
            //匹配:hhmmss分隔符S
            regex = "(?:\\D+)(\\d{2})(\\d{2})?(\\d{2})?(?:\\D+)?(\\d{1,3})?";
            hmss = getHMSS(regex, hmsStr);
        }
        return hmss == null ? ymd : ymd + " " + hmss;

    }

    private static String getYMD(String regex, String dateString) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(dateString);
        if (matcher.find()) {
            String year = matcher.group(1);
            String month = matcher.group(2);
            String day = matcher.group(3);
            if (year != null && month != null && day != null) {
                int m = Integer.parseInt(month);
                int d = Integer.parseInt(day);
                if (m > 0 && m < 13 && d > 0 && d < 32)
                    return year + "-"
                            + (m < 10 ? "0" + m : month)
                            + "-"
                            + (d < 10 ? "0" + d: day);
            }
        }
        return null;
    }

    private static String getHMSS(String regex, String dateString) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(dateString);
        String hms = null;
        if (matcher.find()) {
            String hour = matcher.group(1);
            String minute = matcher.group(2);
            String second = matcher.group(3);
            String microsecond = matcher.group(4);
            int h = Integer.parseInt(hour);
            if (h < 0 || h > 24) return null;
            int m = minute != null ? Integer.parseInt(minute) : -1;
            if (m < 0 || m > 60) return String.format("%02d:00:00", h);
            int s = second != null ? Integer.parseInt(second) : -1;
            if (s < 0 || s > 60) return String.format("%02d:%02d:00", h, m);
            int ss = microsecond != null ? Integer.parseInt(microsecond) : -1;
            if (ss < 0 || ss > 999) return String.format("%02d:%02d:%02d", h, m, s);
            else return String.format("%02d:%02d:%02d.%03d", h, m, s, ss);
        } else return null;
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

muyi517

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值