You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java日期时间格式校验与转换:多格式适配统一为指定格式

Solution for Normalizing Date Formats to MM/dd/yyyy hh:mm:ss a

Got it, let's break down how to handle these date format variations and get everything parsed into your target MM/dd/yyyy hh:mm:ss a format. The core idea is to check for each format in order of priority, fix any missing spacing or seconds, then parse with your primary format.

Step-by-Step Approach

  • First, try parsing the input directly with your primary format (sdf1). If it works, you're done.
  • If not, check for the other formats and normalize the input string to match sdf1 before parsing:
    1. For MM/dd/yyyy hh:mm:ssa (sdf2): The only issue is missing space before am/pm. Insert a space right before the trailing am or pm.
    2. For MM/dd/yyyy hh:mm a (sdf3 variant 1): Missing seconds. Append :00 right after the minutes part, keeping the space before am/pm.
    3. For MM/dd/yyyy hh:mma (sdf3 variant 2): Both missing seconds and space before am/pm. First add a space before am/pm, then append :00 after the minutes.

Java Code Implementation (Using SimpleDateFormat)

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class DateNormalizer {
    private static final SimpleDateFormat SDF1 = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a", Locale.US);
    
    public static Date parseNormalizedDate(String input) throws ParseException {
        // First try direct parse with sdf1
        try {
            return SDF1.parse(input);
        } catch (ParseException e) {
            // Handle other formats
            String normalizedInput = input.trim();
            
            // Check for sdf2: MM/dd/yyyy hh:mm:ssa (no space before am/pm)
            if (normalizedInput.matches("\\d{2}/\\d{2}/\\d{4} \\d{2}:\\d{2}:\\d{2}(am|pm)")) {
                normalizedInput = normalizedInput.replaceAll("(am|pm)$", " $1");
                return SDF1.parse(normalizedInput);
            }
            
            // Check for sdf3 variants: no seconds
            else if (normalizedInput.matches("\\d{2}/\\d{2}/\\d{4} \\d{2}:\\d{2}(am|pm)")) {
                // Case 1: has space before am/pm (MM/dd/yyyy hh:mm a)
                if (normalizedInput.contains(" am") || normalizedInput.contains(" pm")) {
                    normalizedInput = normalizedInput.replace(" ", ":00 ");
                }
                // Case 2: no space before am/pm (MM/dd/yyyy hh:mma)
                else {
                    normalizedInput = normalizedInput.replaceAll("(am|pm)$", ":00 $1");
                }
                return SDF1.parse(normalizedInput);
            }
            
            // If none match, rethrow the original exception
            throw e;
        }
    }
    
    public static void main(String[] args) {
        try {
            // Test cases
            System.out.println(parseNormalizedDate("05/20/2024 03:45:30 pm")); // sdf1
            System.out.println(parseNormalizedDate("05/20/2024 03:45:30pm")); // sdf2
            System.out.println(parseNormalizedDate("05/20/2024 03:45 pm")); // sdf3 variant 1
            System.out.println(parseNormalizedDate("05/20/2024 03:45pm")); // sdf3 variant 2
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

SimpleDateFormat is not thread-safe, so for modern Java projects, use DateTimeFormatter and the java.time API instead. Here's a quick adaptation:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;

public class ModernDateNormalizer {
    private static final DateTimeFormatter TARGET_FORMAT = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a", Locale.US);
    private static final DateTimeFormatter SDF2_FORMAT = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ssa", Locale.US);
    private static final DateTimeFormatter SDF3_FORMAT1 = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a", Locale.US);
    private static final DateTimeFormatter SDF3_FORMAT2 = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mma", Locale.US);
    
    public static LocalDateTime parseNormalizedDate(String input) throws DateTimeParseException {
        // Try target format first
        try {
            return LocalDateTime.parse(input, TARGET_FORMAT);
        } catch (DateTimeParseException e) {
            // Try sdf2
            try {
                return LocalDateTime.parse(input, SDF2_FORMAT);
            } catch (DateTimeParseException e2) {
                // Try sdf3 variants
                try {
                    return LocalDateTime.parse(input, SDF3_FORMAT1).withSecond(0);
                } catch (DateTimeParseException e3) {
                    return LocalDateTime.parse(input, SDF3_FORMAT2).withSecond(0);
                }
            }
        }
    }
}

This approach is safer, more readable, and avoids thread-safety issues with the old date API.

内容的提问来源于stack exchange,提问作者Pat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:12:50