使用 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日期解析与格式化内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论