如何在不知道格式的情况下将字符串转换为日期?

2022-08-31 16:43:08

我有一个问题。我正在尝试将一些字符串转换为日期,但我不知道日期到达的格式。

它可能以或等方式出现。yyyy.mm.dd hh:mm:ssMM.dd.yy hh:mm:ss

如何将这些字符串转换为日期?我试过这个:

DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
Date d = (Date)formatter.parse(someDate);

但是当我打印出一些日期时,它像这样打印出来:2010-08-05 12:42:48.638 CEST这意味着,但是当我运行上面的代码时,日期对象现在变得很奇怪,至少可以说是奇怪的。yyyy.mm.dd hh:mm:ssSat Jan 31 00:42:48 CET 11

任何想法,如何正确格式化字符串到日期?


答案 1

你不能!

如果您有日期,那么它可以是2010年8月5日或2010年5月8日 - 您需要知道日期格式(或者至少优先考虑一种格式)以区分它们。2010-08-05


答案 2

我同意Kragen的观点,即在一般情况下没有正确的解决方案。但是,如果以下情况成立,您可以使用以下解决方案:

  1. 您有一组所有可能的格式

  2. 格式之间没有歧义;其中两个表达式无法成功解析任何日期表达式。

请考虑以下解决方案,该解决方案循环访问可能的格式列表。此解决方案利用 ThreadLocal,以便在多线程环境中有效地解析日期(请记住,这不是线程安全的):SimpleDateFormat

public class FlexibleDateParser {
    private List<ThreadLocal<SimpleDateFormat>> threadLocals = new  ArrayList<ThreadLocal<SimpleDateFormat>>();

    public FlexibleDateParser(List<String> formats, final TimeZone tz){
        threadLocals.clear();
        for (final String format : formats) {
            ThreadLocal<SimpleDateFormat> dateFormatTL = new ThreadLocal<SimpleDateFormat>() {
                protected SimpleDateFormat initialValue() {
                    SimpleDateFormat sdf = new SimpleDateFormat(format);
                    sdf.setTimeZone(tz); 
                    sdf.setLenient(false);
                    return sdf;
                }
            };
            threadLocals.add(dateFormatTL);
        }       
    }

    public Date parseDate(String dateStr) throws ParseException {
        for (ThreadLocal<SimpleDateFormat> tl : threadLocals) {
            SimpleDateFormat sdf = tl.get();
            try {
                return sdf.parse(dateStr);
            } catch (ParseException e) {
                // Ignore and try next date parser
            }
        }
        // All parsers failed
        return null;
    }       
}