自动日期/时间解析器,不指定格式

时间:2013-02-21 19:00:51

标签: java datetime date-parsing

我正在搜索一个java库,它可以将字符串解析为POJO而不指定格式。我研究过POjava。还有其他类似的东西吗?

DateTime dateTime = DateTimeParser.parse("21/02/13");

//If unclear use the cultural information passed
DateTime dateTime = DateTimeParser.parse("01/02/13", new Locale("en-us"));

//Should also work with time zones
DateTime dateTime = DateTimeParser.parse("2011/12/13T14:15:16+01:00");

我发现以下链接存在同一问题Intelligent date / time parser for Java,但不是非常有用的答案。 Joda或JChronic都没有做我想要的。如果我错了,请纠正我。

更新

我说Joda没有解决我的目的的原因是,Joda希望以ISO8601格式或您指定的任何格式(如“yyyyMMdd”)解析字符串。我将无法对此格式进行硬编码,因为我需要处理多种格式。

我有解决方案,以消除美国或欧洲日期格式的模糊性,即mm / dd / yy或dd / mm / yy。假设我可以访问日期的时区,我可以确定它是美国还是欧洲格式?有人能告诉我这样做吗?谷歌搜索但没有发现任何东西。

7 个答案:

答案 0 :(得分:8)

问题是有些格式不能被猜对了。

一个简单的例子是01/02/2013。这是2月1日还是1月2日?或者甚至更糟:01/02/09

存在两种格式。 (谢谢你,英国和美国!)

因此,任何格式的猜测者都必须依靠这些格式的运气,或故意为这些格式失败。

python模块dateutil.parser可以作为尽力而为解析器的示例。对不起,我不知道java等价物。但您可能需要查看Joda Time

http://labix.org/python-dateutil#head-b95ce2094d189a89f80f5ae52a05b4ab7b41af47

它实际上有参数dayfirstyearfirst

然后有一个perl模块:

https://metacpan.org/pod/Time::ParseDate

您可以使用该模块中的优先级列表。盲目尝试一些模式并不是很快(优化的词法分析器会更快),但它可能对你来说已经足够好了,除非你猜测数百万条记录的格式。

答案 1 :(得分:4)

我找到了问题的答案。我使用了这个特定的库POjava。这个page解释了如何格式化日期+时间字符串而不指定任何格式。但是,要使库正常工作,您必须指定日期顺序,如Day,然后是Month或Month,然后是Day。

答案 2 :(得分:0)

这没有神奇的解决方案。请记住日期/时间格式也取决于您的区域设置。

实际上,你可以做的最好的事情就是定义一个格式列表,然后逐个“尝试”它们,直到找到一个(或没有)适合它们。

private static final FORMAT_1 = "MM/dd/yyyy'T'HH:mm:ss.SSS"
private static final FORMAT_2 = "MM/dd/yyyy'T'HH:mm:ss"
private static final FORMAT_3 = "MM/dd/yyyy"

在java中使用日期/时间对象时,请记住考虑线程安全性。我有一个类做这种名为“ThreadSafeDateTimeFormatter”的东西。

祝你好运!

答案 3 :(得分:0)

由于我没有为我的情况找到方便的解决方案,我写了一个简单的静态实用程序方法,帮助了我。如果添加更多格式,在集合中包装格式并对其进行迭代可以使事情变得更容易。

public static Date returnDateFromDateString(String propValue) throws Exception {

    SimpleDateFormat sdfFormat1 = new SimpleDateFormat(IDateFConstants.DATE_STRING_FORMAT_1);
    SimpleDateFormat sdfFormat2 = new SimpleDateFormat(IDateFConstants.DATE_STRING_FORMAT_2);
    SimpleDateFormat sdfISO8601 = new SimpleDateFormat(IDateFConstants.DATE_STRING_ISO_8601);

    try {
        return sdfFormat1.parse(propValue);
    } catch (ParseException e) { }

    try {
        return sdfFormat2.parse(propValue);
    } catch (ParseException e) { }

    try {
        return sdfISO8601.parse(propValue);
    } catch (ParseException e) { }

    throw new Exception(IDateFConstants.DATE_FORMAT_ERROR);
}

IDateFConstants看起来像

public interface IDateFConstants {

public static final String DATE_STRING_ISO_8601 = "yyyy-MM-dd'T'HH:mm:ss";
public static final String DATE_STRING_FORMAT_1 = "dd.MM.yyyy";
public static final String DATE_STRING_FORMAT_2 = "dd.MM.yyyy HH:mm:ss";

public static final String DATE_FORMAT_ERROR = "Date string wasn't" + 
                                            + "formatted in known formats";

}

答案 4 :(得分:0)

您至少需要一个有序的模式候选列表。完成后,Apache DateUtils有一个$(".printPdf").click(function () { var pdfdoc = new jsPDF("portrait"); var getPageTitle = $("#page-title"); var pageTitle = (getPageTitle != "")? getPageTitle : "Document"; var contentClass = ".page-content"; var $pageContent = $(contentClass); var margins = { top: 10, bottom: 20, left: 15, width: 180 }; pdfdoc.setDisplayMode('original'); pdfdoc.fromHTML($pageContent.get(0), margins.left, margins.top, { "width": margins.width, "text-align": "unset" }, function () { pdfdoc.save(pdfdoc.pageTitle + ".pdf") }, margins); }); 方法,可让您轻松尝试日期字符串上的模式列表,并通过匹配的第一个模式对其进行解析:

parseDate(String dateString, String[] patterns)
  

解析将依次尝试每个解析模式。只能视为解析   如果它解析整个输入字符串,则成功。如果没有解析   模式匹配,抛出ParseException。

     

解析器将对解析的日期宽容。

答案 5 :(得分:0)

        public static String detectDateFormat(String inputDate, String requiredFormat) {
        String tempDate = inputDate.replace("/", "").replace("-", "").replace(" ", "");
        String dateFormat;

        if (tempDate.matches("([0-12]{2})([0-31]{2})([0-9]{4})")) {
            dateFormat = "MMddyyyy";
        } else if (tempDate.matches("([0-31]{2})([0-12]{2})([0-9]{4})")) {
            dateFormat = "ddMMyyyy";
        } else if (tempDate.matches("([0-9]{4})([0-12]{2})([0-31]{2})")) {
            dateFormat = "yyyyMMdd";
        } else if (tempDate.matches("([0-9]{4})([0-31]{2})([0-12]{2})")) {
            dateFormat = "yyyyddMM";
        } else if (tempDate.matches("([0-31]{2})([a-z]{3})([0-9]{4})")) {
            dateFormat = "ddMMMyyyy";
        } else if (tempDate.matches("([a-z]{3})([0-31]{2})([0-9]{4})")) {
            dateFormat = "MMMddyyyy";
        } else if (tempDate.matches("([0-9]{4})([a-z]{3})([0-31]{2})")) {
            dateFormat = "yyyyMMMdd";
        } else if (tempDate.matches("([0-9]{4})([0-31]{2})([a-z]{3})")) {
            dateFormat = "yyyyddMMM";
        } else {
//add your required regex
            return "";
        }
        try {
            String formattedDate = new SimpleDateFormat(requiredFormat, Locale.ENGLISH).format(new SimpleDateFormat(dateFormat).parse(tempDate));

            return formattedDate;
        } catch (Exception e) {

            return "";
        }

    }

答案 6 :(得分:0)

这个日期/时间解析器支持 20 多种日期格式,用户可以设置日期格式作为输入的配置。查看完整的 Doc,它比其他日期时间库做得更多。

Github 链接:https://github.com/zoho/hawking。 由 ZOHO ZIA 团队开发。

Hawking Parser 是一个基于 Java 的 NLP 解析器,用于解析日期和时间信息。最流行的解析器,如 Heidel Time、SuTime 和 Natty Date 时间解析器,显然是基于规则的。因此,他们往往难以解析日期/时间信息,因为需要考虑更复杂的因素,如上下文、时态、多个值等。

考虑到这一点,Hawking Parser 旨在解决许多这些挑战,并且与其他可用的日期/时间解析器相比具有许多明显的优势。

它是 GPL v3 下的一个开源库,也是最好的库。要了解为什么它是最好的,请查看这篇详细解释的博客:https://www.zoho.com/blog/general/zias-nlp-based-hawking-date-time-parser-is-now-open-source.html

P.S:我是这个项目的开发者之一