Java的智能日期/时间解析器[关闭]

Posted

技术标签:

【中文标题】Java的智能日期/时间解析器[关闭]【英文标题】:Intelligent date / time parser for Java [closed] 【发布时间】:2011-05-12 02:23:02 【问题描述】:

是否有一些适用于 Java 的智能日期/时间解析器库?智能我的意思是,我不需要指定日期/时间格式。 API 应该与此类似:

Calendar cal = DateTimeParser.parse("01/06/10 14:55");
cal = DateTimeParser.parse("1 Jan 2009"); // assumes 00:00 time
cal = DateTimeParser.parse("1.2.2010");
cal = DateTimeParser.parse("kygyutrtf"); // throws exception

更新

// I'm telling the parser: "If unsure, assume US date format"
cal = DateTimeParser.parse("01/02/03", new Locale("en-us"));

【问题讨论】:

类似问题:***.com/questions/3850784/… Parse any date in Java的可能重复 这个github.com/zoho/hawking可以解决你的问题 【参考方案1】:

java.time

您可以使用DateTimeFormatterBuilder 构建一个解析器,它可以处理不区分大小写的解析、可选模式(在方括号内指定)、默认缺少的字段(例如HOUR_OF_DAY)等。

演示:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.util.Locale;
import java.util.stream.Stream;

public class Main 
    public static void main(String[] args) 
        final DateTimeFormatter parser = new DateTimeFormatterBuilder()
                    .parseCaseInsensitive() // parse in case-insensitive manner                                     
                    .appendPattern("[M/d/uu[ H:m]][d MMM u][M.d.u][E MMM d, u]")
                    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
                    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
                    .toFormatter(Locale.ENGLISH);
        
        // Test
        Stream.of(
                    "Thu Apr 1, 2021",
                    "THU Apr 1, 2021",
                    "01/06/10",
                    "1 Jan 2009",
                    "1.2.2010",
                    "asdf"
                ).forEach(s -> 
                    try 
                        System.out.println(LocalDateTime.parse(s, parser));
                     catch(DateTimeParseException e) 
                        System.out.println("\"" + s + "\"" + " could not be parsed. Error: " + e.getMessage());
                    
                );     
       

输出:

2021-04-01T00:00
2021-04-01T00:00
2010-01-06T00:00
2009-01-01T00:00
2010-01-02T00:00
"asdf" could not be parsed. Error: Text 'asdf' could not be parsed, unparsed text found at index 0

Trail: Date Time 了解有关现代日期时间 API 的更多信息。

【讨论】:

【参考方案2】:

如果您要求智能日期/时间解析器,请检查这个 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:我是这个项目的开发者之一

【讨论】:

【参考方案3】:

您可以使用org.pojava。这个库足够聪明,可以检测时间格式

import org.pojava.datetime.DateTime;
import java.util.Date;

public class Main
    public static void main(String[] args)
        String input1 = "6-Jan-69";
        String input2 = "10 Apr 85 12:34:15";
        String input3 = "7/Mar/77";

        Date date1 = DateTime.parse(input1).toDate();
        Date date2 = DateTime.parse(input2).toDate();
        Date date3 = DateTime.parse(input3).toDate();

        System.out.println(date1);
        System.out.println(date2);
        System.out.println(date3);
    

输出

Mon Jan 06 00:00:00 ICT 1969
Wed Apr 10 12:34:15 ICT 1985
Mon Mar 07 00:00:00 ICT 1977

【讨论】:

【参考方案4】:

JodaTime 非常适合处理日期对象(例如 date.plusDays(10))

...但是 JChronic 是您想要的自然语言日期解析,例如

Chronic.parse("now")
Chronic.parse("tomorrow 15:00")
Chronic.parse("14/2/2001")
Chronic.parse("yesterday")
Chronic.parse("20 Jan 2010")

您的问题与this 类似。

【讨论】:

"自然语言日期解析" != "格式猜测日期解析" 否 - 但它在问题的上下文中仍然有用。【参考方案5】:

好奇你想称它为智能,请考虑以下几点:

你的1.2.2010和我的一样吗? 如果代码在具有不同语言环境的不同时区运行会怎样? 它应该遵循一些well established 标准还是完全自己发明?

您的问题的答案是

【讨论】:

【参考方案6】:

这不太可能,或者至少不够可靠。

比如10/10/10这个字符串代表什么日期?

【讨论】:

我不需要 100% 的可靠性。对于这样的情况,parse 函数可能将语言环境或语言作为可选参数。【参考方案7】:

不,没有。它应该在“01/02/03”返回什么? 2003 年 1 月 1 日、2001 年 2 月 3 日还是 2001 年 3 月 2 日?

【讨论】:

@fhucho 10/10/10 是 2010 年 10 月 10 日,如果将其视为日/月/年的任何组合,则不考虑区域设置。解析器应该为08/09 做什么? en-us 是今年 9 月 8 日,还是 2008 年 9 月或 2009 年 8 月,否则会导致解析错误? @khachik 哦,你是对的,我会将问题编辑到 01/02/03。至于 08/09 - 它应该返回 3 个选项之一,并以某种方式表明它不确定结果。理想情况下,它的行为应该与人类相似...... @fhucho 好的,让我们继续前进。它应该如何表明它不确定结果,以及在这种情况下调用它的代码应该做什么? @khachik 一个选项是Parser p = new Parser(); p.parse("08/09"); p.getCertainity();。或者parse(...) 可以返回一些包含确定性的对象。 @khachik 在我的情况下,调用代码会显示类似“获取上次更新时间时出错”之类的内容,或者干脆什么都不做,因为这种情况的概率几乎为零(在我的情况下)。

以上是关于Java的智能日期/时间解析器[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

java的自然语言日期和时间解析器[关闭]

Java 是不是有一个好的 *strict* 日期解析器?

用于 Java 的 HTML/XML 解析器 [关闭]

Java的Javascript解析器[关闭]

java中的xml dom解析器? [关闭]

EDIFACT 语法、解析器和库(Java)[关闭]