在 Java 中,要处理 未知的输入格式(可能是日期字符串或时间戳字符串),统一返回日期对象。

在 Java 中,要处理 未知的输入格式(可能是日期字符串或时间戳字符串),可以通过以下步骤实现:

  1. 判断输入是日期字符串还是时间戳字符串

    • 如果是全数字组成的字符串,可以尝试将其解析为时间戳。
    • 否则,按照支持的日期格式解析。
  2. 支持多种日期格式

    • 定义常见日期格式的数组,逐一尝试解析日期字符串。
  3. 统一返回日期对象

    • 根据解析结果,返回 java.util.Date 或现代 java.time 类的实例。

示例代码

以下是完整的实现:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Date;
import java.util.regex.Pattern;

public class FlexibleDateConverter {

    // 支持的日期格式
    private static final String[] DATE_FORMATS = {
            "yyyy-MM-dd HH:mm:ss",
            "yyyy-MM-dd",
            "MM/dd/yyyy HH:mm:ss",
            "MM/dd/yyyy",
            "dd-MM-yyyy HH:mm:ss",
            "dd-MM-yyyy",
            "dd/MM/yyyy HH:mm:ss",
            "dd/MM/yyyy"
    };

    /**
     * 将未知格式的字符串解析为 Date 对象
     */
    public static Date parse(String input) {
        // 判断是否是纯数字字符串(可能是时间戳)
        if (input.matches("\\d+")) {
            return parseTimestamp(input);
        }

        // 否则尝试按日期字符串解析
        return parseDateString(input);
    }

    /**
     * 将日期字符串解析为 Date 对象
     */
    private static Date parseDateString(String dateString) {
        for (String format : DATE_FORMATS) {
            try {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
                // 检查字符串是否包含时间部分
                if (!hasTime(dateString)) {
                    LocalDate localDate = LocalDate.parse(dateString, formatter);
                    return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
                }
                LocalDateTime localDateTime = LocalDateTime.parse(dateString, formatter);
                return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
            } catch (DateTimeParseException e) {
                // 忽略当前格式,尝试下一个
                continue;
            }
        }
        throw new IllegalArgumentException("无法解析日期字符串: " + dateString);
    }

    /**
     * 将时间戳字符串解析为 Date 对象
     */
    private static Date parseTimestamp(String timestampString) {
        try {
            long timestamp = Long.parseLong(timestampString);
            return new Date(timestamp);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("无效的时间戳字符串: " + timestampString, e);
        }
    }


    /**
     * 判断字符串是否包含时分秒
     * @param dateTimeStr
     * @return
     */
    public static boolean hasTime(String dateTimeStr) {
        // 正则表达式匹配 HH:mm:ss 的格式
        String timePattern = ".*\\d{2}:\\d{2}:\\d{2}.*";
        return Pattern.matches(timePattern, dateTimeStr);
    }

    public static void main(String[] args) {
        // 示例:日期字符串
        String dateString1 = "2024-12-09 14:30:00";
        String dateString2 = "12/09/2024";

        // 示例:时间戳字符串
        String timestampString = "1702117800000";

        System.out.println("解析日期字符串1: " + parse(dateString1));
        System.out.println("解析日期字符串2: " + parse(dateString2));
        System.out.println("解析时间戳字符串: " + parse(timestampString));
    }
}

输出示例

假设当前时区为 CST:

解析日期字符串1: Mon Dec 09 14:30:00 CST 2024
解析日期字符串2: Mon Dec 09 00:00:00 CST 2024
解析时间戳字符串: Mon Dec 09 14:30:00 CST 2024

代码解析

  1. 判断字符串类型

    • 使用正则表达式 \\d+ 判断输入是否是纯数字:
      • 如果是纯数字,尝试将其转换为 long 类型的时间戳。
      • 如果不是,则尝试按照日期格式解析。
  2. 支持多种日期格式

    • 定义 DATE_FORMATS 数组,存放常见的日期格式。
    • 使用 DateTimeFormatter 逐一尝试解析,直到成功解析。
  3. 解析时间戳字符串

    • 使用 Long.parseLong() 将字符串转换为时间戳。
    • java.util.Date 或现代 java.time.Instant 创建日期对象。
  4. 错误处理

    • 如果所有日期格式都无法匹配,或者时间戳转换失败,抛出 IllegalArgumentException 提示格式不合法。

优化点

  1. 支持更多的时间戳格式

    • 时间戳可以是秒级(10 位)或毫秒级(13 位)。可以通过以下代码自动适配:
      long timestamp = Long.parseLong(input);
      if (String.valueOf(timestamp).length() == 10) {
          timestamp *= 1000; // 秒转换为毫秒
      }
      return new Date(timestamp);
      
  2. 返回现代日期类型

    • 如果需要支持 java.time 类型(如 LocalDateTimeZonedDateTime),可以在解析时直接返回对应的类型:
      public static LocalDateTime parseToLocalDateTime(String input) {
          // 与上述逻辑类似,但最终返回 LocalDateTime
      }
      

总结

  • 多种日期格式:通过定义 DATE_FORMATS 数组支持多种日期字符串解析。
  • 自动识别时间戳:通过正则表达式判断输入是否为时间戳,并支持秒/毫秒的自动适配。
  • 统一返回:返回 Date 对象,便于兼容性。如果需要现代日期类,可以扩展返回 LocalDateTime 或其他类型。

这种实现方式适用于大多数场景,灵活且易于扩展。

posted on 2024-12-11 09:27  九七年的菠萝啤  阅读(158)  评论(0)    收藏  举报