解析Java中的任何日期

时间:2010-08-02 15:44:54

标签: java date

我知道这个问题有很多问题,显然你无法解析任何日期。但是,我发现python-dateutil库能够解析我抛出的每个日期,同时在确定日期格式字符串时完全没有必要。 Joda时间总是作为一个伟大的Java日期解析器出售,但它仍然需要您在选择Format(或创建自己的)之前决定日期的格式。你不能只调用DateFormatter.parse(mydate)并神奇地获得一个Date对象。

例如,使用python-dateutil正确解析日期“Wed Mar 04 05:09:06 GMT-06:00 2009”:

import dateutil.parser
print dateutil.parser.parse('Wed Mar 04 05:09:06 GMT-06:00 2009')

但是下面的Joda时间调用不起作用:

    String date = "Wed Mar 04 05:09:06 GMT-06:00 2009";
    DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
    DateTime dt = fmt.parseDateTime(date);
    System.out.println(date);

创建自己的DateTimeFormatter会失败,因为这似乎与使用具有正确格式字符串的SimpleDateFormatter相同。

是否有类似的方法来解析Java中的日期,比如python-dateutil?我不关心错误,我只是想让它完美无缺。

6 个答案:

答案 0 :(得分:95)

你最好的选择是向正则表达式提供帮助以匹配日期格式模式和/或进行暴力破解。

几年前,我写了一篇愚蠢的DateUtil class来完成这项工作。以下是相关摘录:

private static final Map<String, String> DATE_FORMAT_REGEXPS = new HashMap<String, String>() {{
    put("^\\d{8}$", "yyyyMMdd");
    put("^\\d{1,2}-\\d{1,2}-\\d{4}$", "dd-MM-yyyy");
    put("^\\d{4}-\\d{1,2}-\\d{1,2}$", "yyyy-MM-dd");
    put("^\\d{1,2}/\\d{1,2}/\\d{4}$", "MM/dd/yyyy");
    put("^\\d{4}/\\d{1,2}/\\d{1,2}$", "yyyy/MM/dd");
    put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}$", "dd MMM yyyy");
    put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}$", "dd MMMM yyyy");
    put("^\\d{12}$", "yyyyMMddHHmm");
    put("^\\d{8}\\s\\d{4}$", "yyyyMMdd HHmm");
    put("^\\d{1,2}-\\d{1,2}-\\d{4}\\s\\d{1,2}:\\d{2}$", "dd-MM-yyyy HH:mm");
    put("^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{1,2}:\\d{2}$", "yyyy-MM-dd HH:mm");
    put("^\\d{1,2}/\\d{1,2}/\\d{4}\\s\\d{1,2}:\\d{2}$", "MM/dd/yyyy HH:mm");
    put("^\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}:\\d{2}$", "yyyy/MM/dd HH:mm");
    put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}\\s\\d{1,2}:\\d{2}$", "dd MMM yyyy HH:mm");
    put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}\\s\\d{1,2}:\\d{2}$", "dd MMMM yyyy HH:mm");
    put("^\\d{14}$", "yyyyMMddHHmmss");
    put("^\\d{8}\\s\\d{6}$", "yyyyMMdd HHmmss");
    put("^\\d{1,2}-\\d{1,2}-\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd-MM-yyyy HH:mm:ss");
    put("^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{1,2}:\\d{2}:\\d{2}$", "yyyy-MM-dd HH:mm:ss");
    put("^\\d{1,2}/\\d{1,2}/\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "MM/dd/yyyy HH:mm:ss");
    put("^\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}:\\d{2}:\\d{2}$", "yyyy/MM/dd HH:mm:ss");
    put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd MMM yyyy HH:mm:ss");
    put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd MMMM yyyy HH:mm:ss");
}};

/**
 * Determine SimpleDateFormat pattern matching with the given date string. Returns null if
 * format is unknown. You can simply extend DateUtil with more formats if needed.
 * @param dateString The date string to determine the SimpleDateFormat pattern for.
 * @return The matching SimpleDateFormat pattern, or null if format is unknown.
 * @see SimpleDateFormat
 */
public static String determineDateFormat(String dateString) {
    for (String regexp : DATE_FORMAT_REGEXPS.keySet()) {
        if (dateString.toLowerCase().matches(regexp)) {
            return DATE_FORMAT_REGEXPS.get(regexp);
        }
    }
    return null; // Unknown format.
}

(咳嗽,双支撑初始化,咳嗽,只是为了让它全部适合100 char最大长度;)

您可以使用新的正则表达式和日期格式模式轻松扩展它。

答案 1 :(得分:48)

我认为有一个名为Natty的好库,符合您的目的:

  

Natty是一个用Java编写的自然语言日期解析器。给定一个约会   表达,natty将应用标准语言识别和翻译   使用可选解析和生成相应日期列表的技术   语法信息。

你也可以try it online

答案 2 :(得分:7)

我所看到的是一个Date util类,它包含几种典型的日期格式。因此,当调用DateUtil.parse(date)时,它会尝试在内部使用每种日期格式解析日期,并且只有在没有内部格式可以解析它时才会抛出异常。

这对你的问题基本上是一种蛮力的方法。

答案 3 :(得分:3)

您可以尝试dateparser

它可以自动识别任何字符串,并将其解析为日期日历 LocalDateTime OffsetDateTime 正确,快速(1us~1.5us)。

它不基于任何natural language analyzerSimpleDateFormatregex.Pattern

有了它,您不必准备任何适当的模式,例如yyyy-MM-dd'T'HH:mm:ss.SSSZyyyy-MM-dd'T'HH:mm:ss.SSSZZ

Date date = DateParserUtils.parseDate("2015-04-29T10:15:00.500+0000");
Calendar calendar = DateParserUtils.parseCalendar("2015-04-29T10:15:00.500Z");
LocalDateTime dateTime = DateParserUtils.parseDateTime("2015-04-29 10:15:00.500 +00:00");

一切正常,请尽情享受。

答案 4 :(得分:0)

我不知道如何在python中进行解析。在Java中,我们可以这样做

SimpleDateFormat sdf1 = new SimpleDateFormat("dd-MM-yyyy");
  java.util.Date normalDate = null;
  java.sql.Date sqlDate = null;
  normalDate = sdf1.parse(date);
  sqlDate = new java.sql.Date(normalDate.getTime());
  System.out.println(sqlDate);

我认为像Java一样,一些预定义的函数也会出现在python中。您可以按照此方法。 此方法将String日期解析为Sql Date(dd-MM-yyyy);

import java.text.SimpleDateFormat;
import java.text.ParseException;
public class HelloWorld{
     public static void main(String []args){
        String date ="26-12-2019";
         SimpleDateFormat sdf1 = new SimpleDateFormat("dd-MM-yyyy");
        java.util.Date normalDate = null;
        java.sql.Date sqlDate = null;
        if( !date.isEmpty()) {
            try {
                normalDate = sdf1.parse(date);
                sqlDate = new java.sql.Date(normalDate.getTime());
                System.out.println(sqlDate);
            } catch (ParseException e) {
            }
        }
     }
} 

执行此操作!

答案 5 :(得分:0)

//download library:   org.ocpsoft.prettytime.nlp.PrettyTimeParser
String str = "2020.03.03";
Date date = new PrettyTimeParser().parseSyntax(str).get(0).getDates().get(0);
System.out.println(date)