Recognise an arbitrary date string

Viewed 11938

I need to be able to recognise date strings. It doesn't matter if I can not distinguish between month and date (e.g. 12/12/10), I just need to classify the string as being a date, rather than converting it to a Date object. So, this is really a classification rather than parsing problem.

I will have pieces of text such as:

"bla bla bla bla 12 Jan 09 bla bla bla 01/04/10 bla bla bla"

and I need to be able to recognise the start and end boundary for each date string within.

I was wondering if anyone knew of any java libraries that can do this. My google-fu hasn't come up with anything so far.

UPDATE: I need to be able to recognise the widest possible set of ways of representing a dates. Of course the naive solution might be to write an if statement for every conceivable format, but a pattern recognition approach, with a trained model, is ideally what I'm after.

15 Answers

Here is a simple natty example :

import com.joestelmach.natty.*;

List<Date> dates =new Parser().parse("Start date 11/30/2013 , end date Friday, Sept. 7, 2013").get(0).getDates();
        System.out.println(dates.get(0));
        System.out.println(dates.get(1));

//output:
        //Sat Nov 30 11:14:30 BDT 2013
        //Sat Sep 07 11:14:30 BDT 2013

java.time

You can specify as many custom patterns as you wish using DateTimeFormatter. All you need to do is to specify patterns as optional by enclosing them within square brackets. DateTimeFormatterBuilder provides you with many more things e.g. case-insensitive parsing, defaulting to a missing unit (e.g. HOUR_OF_DAY) etc.

Demo:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.util.Locale;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        // DateTimeFormatter parser = DateTimeFormatter.ofPattern("[M/d/uu[ H:m]][d MMM u][M.d.u][E MMM d, u]", Locale.ENGLISH);
        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]")
                    .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 {
                        LocalDate.parse(s, parser);
                        System.out.println(true);
                    } catch(DateTimeParseException e) {
                        System.out.println(false);
                    }
                });     
    }   
}

Output:

true
true
true
true
true
false

Learn more about the modern date-time API from Trail: Date Time.

Check this one https://github.com/zoho/hawking. Devolped by ZOHO ZIA Team.

Hawking Parser is a Java-based NLP parser for parsing date and time information. The most popular parsers out there like Heidel Time, SuTime, and Natty Date time parser are distinctly rule-based. As such, they often tend to struggle with parsing date/time information where more complex factors like context, tense, multiple values, and more need to be considered.

With this in mind, Hawking Parser is designed to address a lot of these challenges and has many distinct advantages over other available date/time parsers.

It's a 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

Related