当前位置: 代码网 > it编程>编程语言>Java > Java进行日期解析与格式化的实现代码

Java进行日期解析与格式化的实现代码

2025年05月14日 Java 我要评论
使用 java 搭配 apache commons lang3 和 natty 库,实现灵活高效的日期解析与格式化。一、背景将不同格式的日期统一成一个格式。日期格式可能有以下几种类型:标准格式:202

使用 java 搭配 apache commons lang3 和 natty 库,实现灵活高效的日期解析与格式化。

一、背景

将不同格式的日期统一成一个格式。日期格式可能有以下几种类型:

  • 标准格式:2024-02-28、14/05/2022、2002年5月6日
  • 非英文月份缩写:02 nis 2018、26 ago 2018(西班牙语)
  • 自然语言:next monday、two days ago

二、依赖介绍

使用的版本是 jdk8。使用以下两个日期解析库:

1. apache commons lang3

apache commons lang3 提供了丰富的工具类,能够严格地解析各种标准日期格式。

<dependency>
  <groupid>org.apache.commons</groupid>
  <artifactid>commons-lang3</artifactid>
  <version>3.12.0</version>
</dependency>

2. natty

natty 是一个专门用于解析自然语言日期的 java 库,支持英文描述的各种日期表达方式。

<dependency>
  <groupid>com.joestelmach</groupid>
  <artifactid>natty</artifactid>
  <version>0.13</version>
</dependency>

三、核心实现代码

定义一个工具类,提供统一的日期解析方法:

完整代码示例:

import org.apache.commons.lang3.time.dateutils;
import com.joestelmach.natty.parser;
import org.apache.log4j.level;

import java.text.parseexception;
import java.text.simpledateformat;
import java.util.*;


/***
 * @title
 * @author shijiangyong
 * @date 2025/5/14 14:18
 **/
public class smartdateparser {

    // 允许解析的日期格式
    private static final string[] date_patterns = {
            "yyyy-mm-dd", "yyyy/m/d", "dd/mm/yyyy", "yyyy年m月d日",
            "dd mmm yyyy", "mmm dd yyyy", "dd mm yyyy",
            "yyyymmdd", "yyyy.mm.dd", "yyyy年mm月dd日", "d mmm yyyy",
            "eee, dd mmm yyyy"
    };

    // 处理非标准月份缩写(主要针对西班牙语、法语等)
    private static final map<string, string> month_corrections = new hashmap<>();
    static {
        month_corrections.put("nis", "apr");  // 可能是 april
        month_corrections.put("abr", "apr");  // 西班牙语 april
        month_corrections.put("ago", "aug");  // 西班牙语 august
    }

    /**
     * 解析日期并转换为 yyyy-m-d 格式
     */
    public static string parsedate(string input) {
        if (input == null || input.trim().isempty()) {
            return "invalid date";
        }


        input = input.trim().replaceall("[,,]", "");

        // 修正月份缩写
        for (map.entry<string, string> entry : month_corrections.entryset()) {
            if (input.contains(entry.getkey())) {
                input = input.touppercase().replace(entry.getkey(), entry.getvalue());
            }
        }
        // 1. 明确格式优先处理
        for (string pattern : date_patterns) {
            try {
                simpledateformat sdf = new simpledateformat(pattern, locale.english);
                // 严格校验日期
                sdf.setlenient(false);
                date date = sdf.parse(input);
                return formattostandard(date);
            } catch (parseexception ignored) {}
        }
        // 1. 使用 apache commons lang3 解析
        try {
            date date = dateutils.parsedatestrictly(input, locale.english, date_patterns);
            return formattostandard(date);
        } catch (parseexception ignored) {}

        // 2. 使用 natty 解析 (适用于 `next monday`, `19 aug 2019`)
        try {
            parser parser = new parser();
            list<com.joestelmach.natty.dategroup> groups = parser.parse(input);
            if (!groups.isempty()) {
                list<date> dates = groups.get(0).getdates();
                if (!dates.isempty()) {
                    return formattostandard(dates.get(0));
                }
            }
        } catch (exception ignored) {}
        return "unrecognized: " + input;
    }

    /**
     * 统一转换日期为 yyyy-mm-dd 格式
     */
    private static string formattostandard(date date) {
        calendar cal = calendar.getinstance();
        cal.settime(date);
        int year = cal.get(calendar.year);
        int month = cal.get(calendar.month) + 1;
        int day = cal.get(calendar.day_of_month);
        return string.format("%04d-%02d-%02d", year, month, day);
    }

    public static void main(string[] args) {
        org.apache.log4j.logger.getrootlogger().setlevel(level.error);
        list<string> testdates = arrays.aslist(
                "02 nis 2018", "2028-4-219", "19 aug 2019", "2019-8-19",
                "2002年5月6日", "2005/02/03", "03 sep 1985", "14/05/2022",
                "20 feb 1991", "26 ago 2018", "08 abr 1975", "01 09 1988",
                "next monday", "yesterday", "two days ago", "2024.02.28",
                "wed, 19 aug 2019"
        );

        for (string datestr : testdates) {
            system.out.println("输入: " + datestr + " → 解析: " + parsedate(datestr));
        }
    }
}

解析结果:

输入: 02 nis 2018 → 解析: 2018-04-02
输入: 2028-4-219 → 解析: 2028-04-21
输入: 19 aug 2019 → 解析: 2019-08-19
输入: 2019-8-19 → 解析: 2019-08-19
输入: 2002年5月6日 → 解析: 2002-05-06
输入: 2005/02/03 → 解析: 2005-02-03
输入: 03 sep 1985 → 解析: 1985-09-03
输入: 14/05/2022 → 解析: 2022-05-14
输入: 20 feb 1991 → 解析: 1991-02-20
输入: 26 ago 2018 → 解析: 2018-08-26
输入: 08 abr 1975 → 解析: 1975-04-08
输入: 01 09 1988 → 解析: 1988-09-01
输入: next monday → 解析: 2025-05-19
输入: yesterday → 解析: 2025-05-13
输入: two days ago → 解析: 2025-05-12
输入: 2024.02.28 → 解析: 2024-02-28
输入: wed, 19 aug 2019 → 解析: 2019-08-19

要求的日期格式都正确解析了。

到此这篇关于java进行日期解析与格式化的实现代码的文章就介绍到这了,更多相关java日期解析与格式化内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com