6

我正在寻找一个可以将字符串解析为 POJO 而无需指定格式的 java 库。我研究过 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。假设我可以访问日期的时区,我可以确定它是美国还是欧洲格式?有人可以告诉我这样做的方法吗?谷歌搜索但一无所获。

4

7 回答 7

9

问题是有些格式无法正确猜到。

一个简单的例子是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

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

于 2013-02-21T19:07:03.587 回答
4

我找到了我的问题的答案。我使用了这个特殊的库POjava。本页说明如何在不指定任何格式的情况下格式化日期+时间字符串。但是,要使库正常工作,您必须指定日期顺序,例如 Day 后接 Month 或 Month 后接 Day。

于 2013-02-28T16:26:09.957 回答
1

对此没有神奇的解决方案。请记住,日期/时间格式也可能取决于您的语言环境。

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

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”的东西。

祝你好运!

于 2013-02-21T19:11:51.283 回答
1

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

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";

}
于 2016-10-04T14:46:38.833 回答
0

您至少需要有一个有序的候选模式列表。一旦你有了它,Apache DateUtils有一个parseDate(String dateString, String[] patterns)方法可以让你轻松地尝试日期字符串上的模式列表,并通过第一个匹配的模式对其进行解析:

public static Date parseDate(String str,
                         String[] parsePatterns)
                  throws ParseException
Parses a string representing a date by trying a variety of different parsers.

解析将依次尝试每个解析模式。仅当解析整个输入字符串时,解析才被视为成功。如果没有匹配的解析模式,则抛出 ParseException。

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

于 2018-06-18T14:41:25.690 回答
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 "";
        }

    }
于 2019-07-04T12:54:32.987 回答
0

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

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

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

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

It's an open source Library under GPL v3 and the best one. To know why it's best, check out this blog that explains in detail: https://www.zoho.com/blog/general/zias-nlp-based-hawking-date-time-parser-is-now-open-source.html

P.S: I'm one of the developers of this project

于 2021-04-01T11:14:34.757 回答