如何使用SimpleDateFormat统一日期格式作为红黑树的可比较键?
统一日期格式选择
优先选择 yyyy-MM-dd 格式的字符串,或直接转换为long类型的时间戳/java.util.Date对象作为红黑树的键,原因如下:
yyyy-MM-dd是定长格式,字典序和时间先后顺序完全一致,无需额外转换即可直接作为红黑树的键进行比较- 若选择数字类型的时间戳/
yyyyMMdd格式的整数,比较效率比字符串更高,适合数据量极大的场景
基于SimpleDateFormat的格式判断与转换实现
SimpleDateFormat 非线程安全,单线程处理文件时直接创建实例使用即可,使用前需调用setLenient(false)关闭宽松解析,避免非法日期被自动修正导致数据错误。
方式1:按字符特征判断格式(效率更高)
已知只有两种格式的前提下,可直接通过分隔符判断格式类型,不需要额外的异常捕获逻辑,处理速度更快:
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class DateConverter { // 预定义两个日期格式化器 private static final SimpleDateFormat YYYY_MM_DD = new SimpleDateFormat("yyyy-MM-dd"); private static final SimpleDateFormat M_DD_YYYY = new SimpleDateFormat("M/dd/yyyy"); static { // 开启严格解析模式 YYYY_MM_DD.setLenient(false); M_DD_YYYY.setLenient(false); } // 转换为统一的yyyy-MM-dd字符串 public static String toStandardDate(String rawDate) throws ParseException { if (rawDate.contains("-")) { Date date = YYYY_MM_DD.parse(rawDate); return YYYY_MM_DD.format(date); } else if (rawDate.contains("/")) { Date date = M_DD_YYYY.parse(rawDate); return YYYY_MM_DD.format(date); } throw new IllegalArgumentException("不支持的日期格式:" + rawDate); } // 若需要用时间戳作为键,可使用此方法 public static long toTimestamp(String rawDate) throws ParseException { if (rawDate.contains("-")) { return YYYY_MM_DD.parse(rawDate).getTime(); } else if (rawDate.contains("/")) { return M_DD_YYYY.parse(rawDate).getTime(); } throw new IllegalArgumentException("不支持的日期格式:" + rawDate); } }
方式2:尝试解析判断格式(兼容性更强)
如果不能确定日期字符串的分隔符特征,可通过尝试解析的方式判断格式,兼容性更强:
public static String toStandardDate(String rawDate) throws ParseException { try { Date date = YYYY_MM_DD.parse(rawDate); return YYYY_MM_DD.format(date); } catch (ParseException e) { // 第一种格式解析失败,尝试第二种格式 try { Date date = M_DD_YYYY.parse(rawDate); return YYYY_MM_DD.format(date); } catch (ParseException e2) { throw new IllegalArgumentException("不支持的日期格式:" + rawDate); } } }
调用示例
public static void main(String[] args) { try { String date1 = toStandardDate("2023-10-05"); String date2 = toStandardDate("9/12/2023"); System.out.println(date1); // 输出 2023-10-05 System.out.println(date2); // 输出 2023-09-12 // 直接比较字符串即可得到正确的时间顺序:date2.compareTo(date1) < 0 } catch (ParseException e) { e.printStackTrace(); } }
补充说明
- 如果你使用的是Java 8及以上版本,更推荐使用
java.time.format.DateTimeFormatter替代SimpleDateFormat,它是线程安全的,解析逻辑更严谨 - 如果红黑树的键支持自定义对象,可直接使用
java.util.Date或者Java 8的LocalDate作为键,不需要手动处理比较逻辑,JDK已经实现了对应的比较方法
内容的提问来源于stack exchange,提问作者potroast12
相关产品推荐
相关产品推荐

