10

Is there some intelligent date / time parser library for Java? By intelligent I mean, that I don't need to specify the date / time format. The API should be similar to this:

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

UPDATE:

// I'm telling the parser: "If unsure, assume US date format"
cal = DateTimeParser.parse("01/02/03", new Locale("en-us"));
Luke Girvin
  • 13,221
  • 9
  • 64
  • 84
fhucho
  • 34,062
  • 40
  • 136
  • 186

7 Answers7

12

JodaTime is excellent for manipulating date objects (e.g. date.plusDays(10))

...but JChronic is what you want for natural language date parsing, e.g.

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

Your question is similar to this one.

Community
  • 1
  • 1
Joel
  • 29,538
  • 35
  • 110
  • 138
3

No, there is not. What it should return on "01/02/03"? 1 Jan 2003, 3 Feb 2001, or 2 Mar 2001?

khachik
  • 28,112
  • 9
  • 59
  • 94
  • @fhucho `10/10/10` is 2010 Oct 10 without considering the locale if it treated as day/month/year in any combination. What the parser should do for `08/09`? It is 8/Sep/current year for en-us, or Sep/2008 or Aug/2009 or it causes parsing error? – khachik Nov 18 '10 at 15:39
  • @khachik oh, you're right, I'll edit the question to 01/02/03. As for 08/09 - it should return one of the 3 options and somehow indicate that it is unsure about the result. Ideally it should behave similarly to a human... – fhucho Nov 18 '10 at 15:47
  • @fhucho Ok, let's move forward. How it should indicate that it is unsure about the result, and what the code calling it should do in that case? – khachik Nov 18 '10 at 16:05
  • @khachik One option is `Parser p = new Parser(); p.parse("08/09"); p.getCertainity();`. Or `parse(...)` could return some object containing certainity. – fhucho Nov 18 '10 at 17:36
  • @khachik In my case, the calling code would display something like "Error obtaining last update time", or simply do nothing, because probability of this is almost zero (in my case). – fhucho Nov 18 '10 at 17:39
  • @fhucho What does the caller code do, when it got a `Certainity` object which represents one or more problems found? Your are trying to prove that is possible to make such a parser. Yes, it is possible. Such a parser can be useful for particular cases, but not in general. So if `JChronic` or anything else fits your requirements, you can use it. I have made one on Python, but it was very specific, fit my requirements, and I have met the same question a long time ago. – khachik Nov 18 '10 at 17:52
2

Curious that you want to call that intelligent, just consider these:

  • Is your 1.2.2010 the same as mine?
  • What happens if the code is run on different time zones with varying locales?
  • Should it follow some well established standard or invent its own entirely?

The answer to your question is no.

Esko
  • 29,022
  • 11
  • 55
  • 82
1

This isn't really going to be possible, or at least reliable enough.

For example, what date does the string 10/10/10 represent?

matt b
  • 138,234
  • 66
  • 282
  • 345
  • 1
    I don't need 100% reliability. For cases like this, the parse function may have locale or language as an optional argument. – fhucho Nov 18 '10 at 15:18
1

If you are asking for an intelligent date/time Parser then, 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

Heisenberg
  • 41
  • 5
1

java.time

You can build a parser using DateTimeFormatterBuilder that can take care of case-insensitive parsing, optional patterns (specified inside square brackets), defaulting the missing fields (e.g. HOUR_OF_DAY) etc.

Demo:

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());
                    }
                });     
    }   
}

Output:

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

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

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
0

You can use org.pojava. This library smart enough to detect time format

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);
    }
}

Output

Mon Jan 06 00:00:00 ICT 1969
Wed Apr 10 12:34:15 ICT 1985
Mon Mar 07 00:00:00 ICT 1977
NM Naufaldo
  • 1,032
  • 1
  • 12
  • 30