在Java中如何将任意格式的Date/DateTime字符串转为统一指定格式日期字符串
核心实现思路
预定义你业务场景下所有可能的日期格式列表,按规则排序后遍历尝试解析输入字符串,解析成功后再统一格式化为目标输出格式,该方案完全可控,可覆盖你给出的所有示例格式,也能灵活扩展新格式。
注意:你问题中提到的目标格式
dd-mm-yyyy存在书写误区,Java日期格式规则中大写M代表月份,小写m代表分钟,实际使用时目标格式需替换为dd-MM-yyyy。
方案1:Java 8+ 原生实现(推荐)
基于线程安全的java.time包实现,无需引入第三方依赖,性能更稳定:
import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Optional; public class MultiFormatDateConverter { // 预定义格式列表:复杂格式在前,简单格式在后,避免提前匹配出错 private static final List<DateTimeFormatter> SUPPORTED_FORMATTERS = new ArrayList<>(); // 目标输出格式 private static final DateTimeFormatter TARGET_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy"); static { // 指定英文Locale,保证英文月份/月份缩写可正常解析 Locale enLocale = Locale.ENGLISH; SUPPORTED_FORMATTERS.add(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S", enLocale)); SUPPORTED_FORMATTERS.add(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", enLocale)); SUPPORTED_FORMATTERS.add(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm", enLocale)); SUPPORTED_FORMATTERS.add(DateTimeFormatter.ofPattern("dd/MM/yyyy HH.mm", enLocale)); SUPPORTED_FORMATTERS.add(DateTimeFormatter.ofPattern("dd MMMM''yy HH:mm", enLocale)); SUPPORTED_FORMATTERS.add(DateTimeFormatter.ofPattern("yyyy-MM-dd", enLocale)); SUPPORTED_FORMATTERS.add(DateTimeFormatter.ofPattern("dd-MMMM-yyyy", enLocale)); SUPPORTED_FORMATTERS.add(DateTimeFormatter.ofPattern("dd/MM/yyyy", enLocale)); SUPPORTED_FORMATTERS.add(DateTimeFormatter.ofPattern("dd-MMM-yyyy", enLocale)); } /** * 多格式日期转换方法 * @param rawDateStr 原始日期字符串 * @return 转换后的目标格式字符串,解析失败返回空Optional */ public static Optional<String> convertToStandardFormat(String rawDateStr) { if (rawDateStr == null || rawDateStr.isBlank()) { return Optional.empty(); } for (DateTimeFormatter formatter : SUPPORTED_FORMATTERS) { try { LocalDate date = LocalDate.parse(rawDateStr, formatter); return Optional.of(date.format(TARGET_FORMATTER)); } catch (DateTimeParseException ignored) { // 解析失败尝试下一个格式 } } // 所有格式都不匹配 return Optional.empty(); } // 测试用例,覆盖你给出的所有示例 public static void main(String[] args) { List<String> testSamples = List.of( "2021-11-20", "2021-11-20 05:03:31", "2021-11-20 04:19:25.4", "19-11-2021 19:11", "19/11/2021 17.39", "19 November'21 16:00", "19-November-2021", "19/11/2021", "19-Nov-2021" ); testSamples.forEach(sample -> { String result = convertToStandardFormat(sample).orElse("解析失败"); System.out.printf("原始值:%s | 转换结果:%s%n", sample, result); }); } }
运行测试用例后,你给出的所有示例都能正常转换为dd-MM-yyyy格式。
方案2:借助Apache Commons Lang3简化实现
如果项目已引入Apache Commons工具包,可直接用DateUtils内置的多格式解析能力,代码更简洁:
- 引入Maven依赖(已引入可跳过):
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.14.0</version> </dependency>
- 工具方法实现:
import org.apache.commons.lang3.time.DateUtils; import java.text.ParseException; import java.time.LocalDate; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Locale; public class MultiFormatDateConverter { private static final String[] SUPPORTED_PATTERNS = { "yyyy-MM-dd HH:mm:ss.S", "yyyy-MM-dd HH:mm:ss", "dd-MM-yyyy HH:mm", "dd/MM/yyyy HH.mm", "dd MMMM''yy HH:mm", "yyyy-MM-dd", "dd-MMMM-yyyy", "dd/MM/yyyy", "dd-MMM-yyyy" }; private static final DateTimeFormatter TARGET_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy"); public static String convertToStandardFormat(String rawDateStr) throws ParseException { return DateUtils.parseDate(rawDateStr, Locale.ENGLISH, SUPPORTED_PATTERNS) .toInstant() .atZone(ZoneId.systemDefault()) .toLocalDate() .format(TARGET_FORMATTER); } }
注意事项
- 格式排序规则:必须把更复杂、匹配范围更窄的格式放在列表前面,比如带时分秒的格式要放在纯日期格式前面,避免短格式提前匹配导致解析错误。
- 歧义处理:如果存在日月位模糊的格式(比如
01/02/2023可能对应1月2日或2月1日),可根据业务数据的实际规则调整格式顺序,或增加额外的校验逻辑规避错误。 - 前端输入校验:直接复用这套转换逻辑即可,解析成功视为合法输入,解析失败返回错误提示,和存量数据转换逻辑完全统一,无需修改现有业务规则。
内容的提问来源于stack exchange,提问作者Dhana D.
相关产品推荐
相关产品推荐

