1

I have a string that represents a date. I do not know the date format of the string. But for example only, it may be any of

  • 2015-10-14T16:41:42.000Z
  • 2015-10-14T19:01:53.100+01:00
  • 2015-10-14 05:20:29

or any valid format that a website may use to describe date in a meta tag (so the format will be official, as opposed to whimsical, but the set of possibilities is not small).

Can I use joda-time to solve this issue? How about java.util.Date or anything else?

update

I think I find a Javascript equivalent of what I am looking for

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

But I need an answer for Java.

Katedral Pillon
  • 14,534
  • 25
  • 99
  • 199
  • 3
    [Using Joda Date & Time API to parse multiple formats](http://stackoverflow.com/questions/3307330/using-joda-date-time-api-to-parse-multiple-formats) – Pshemo Oct 14 '15 at 19:56
  • Both of these suggestions require me to know the format beforehand. The very title of my question specifies "unknown" format :). Do you guys know by any chances of a way to get all possible date formats for my circumstance? (Hoping it's a very small set, of course). I don't mind writing multiple parsers, but the thing is the format can be anything that is valid for an html meta tag that contains date. – Katedral Pillon Oct 14 '15 at 20:01
  • I see a lot of up votes for the Jado Date link, but it is missing the ball on my question. So I have added a link to a js equivalent. – Katedral Pillon Oct 14 '15 at 20:07
  • 1
    There's no "simple" answer and the general answer is to use a List of formats and keep trying to convert the value against the List of formats until one works – MadProgrammer Oct 14 '15 at 20:41
  • +1 to MadProgrammer — that's what I did. I have a `DateParser` class that contains several pre-defined date formats I expect, plus you can provide your own list of formats per-call. Simple call is `DateParser.parse(dateString)` through complex `public static Date parse(String dateString, boolean strict, DateFormat... mine)` choosing strict or lenient parsing with varargs of your own date formats to try first, then try the fallback built-ins. – Stephen P Oct 14 '15 at 20:51
  • "but the **set of possibilities** is not small" - self-answering questions are the best. – Gimby Oct 14 '15 at 21:07
  • 1
    @Gimby your comment is neither intelligent nor helpful nor necessary: the OP provides a link where such a function actually exists for JavaScript. So this is a valuable question. And perhaps Google or Oracle or joda-time or whoever is responsible for creating authoritative Java functions should pay attention. A function like this in Java would be invaluable to many developers. – Konsol Labapen Oct 14 '15 at 21:19
  • Even though there may be a huge number of actual formats, if there are a few conforming rules for those formats, one could write a parser that picks the relevant pieces out. A common/conforming theme in the OP examples is that, on the whole, the pieces are arranged in the order `year month day hour minute second` with optional time-zone information and/or offset. Knowing that, you could find those pieces then attempt to make sense of the yet-unparsed bit, such as the `space-or-T` separator between date and time. Parse instead of match. – Stephen P Oct 14 '15 at 21:45
  • @KonsolLabapen feel better now? If you have trouble with a comment flag it – Gimby Oct 15 '15 at 07:46
  • @StephenP what would be the format for the ones I have so far? For jodatime – Katedral Pillon Oct 15 '15 at 21:56
  • 1
    @KatedralPillon yours (assuming always a 24-hour clock) look like `4-digit-year, literal_dash, 2-digit-month, literal_dash, 2-digit-day, one-space-or-literal_T, 2-digit-hour, literal_colon, 2-digit-minute, literal_colon, 2-digit-second` (etc). A regex (w/o checking valid ranges) is _like_ `\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(\.\d{3})?(.*)?` (add proper capturing groups to extract pieces) the `(\.\d{3})?` is optional 3-digit hundredths of a second; the final `(.*)?` is the optional time-zone info, which needs more parsing to tell if its a zone (Z, EST, etc.) or an offset (+01:00) – Stephen P Oct 15 '15 at 22:12

1 Answers1

1

well this is not a real "java" solution, but if you have found a Javascript one, than you can use the Javascript solution in java using the ScriptEngine.

just a little quick and dirty... :)

here is a sample code:

public static void main(String[] args) throws ScriptException, ParseException {
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("js");
    String[] dateStrings = new String[] {
            "2015-10-14T16:41:42.000Z",
            "2015-10-14T19:01:53.100+01:00",
            "2015-10-14 05:20:29" };

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
    for (String d : dateStrings) {
        String script = "new Date('" + d + "')";
        Object eval = engine.eval(script);
        Date parsed = sdf.parse(eval.toString().replace("[Date ", "").replace("]", ""));
        System.out.println(eval + " -> " + parsed);

    }

}

that prints out:

[Date 2015-10-14T16:41:42.000Z] -> Wed Oct 14 18:41:42 CEST 2015
[Date 2015-10-14T18:01:53.100Z] -> Wed Oct 14 20:01:53 CEST 2015
[Date 2015-10-14T03:20:29.000Z] -> Wed Oct 14 05:20:29 CEST 2015

The eval.toString() part can be improved obviously. as the locale settings...

max
  • 783
  • 6
  • 22
  • I am looking at the page, but I am not really sure what I am looking at. Do you mind showing a short code of how I would call the JS `new Date(dateString)` construction in Java using the ScriptEngine? – Katedral Pillon Oct 14 '15 at 21:31
  • I don't know if your example works, but the ScriptEngine idea should, so I am testing some code (yours and my own versions) and will report back once I am successful. In the meantime +1. – Katedral Pillon Oct 14 '15 at 21:52
  • shouldn't the following work? `String script = "var date = new Date('" + dateString + "'); var timestamp = date.getTime();";` and then `long timestamp = ((Long) engine.get("timestamp")).longValue(); `? – Katedral Pillon Oct 15 '15 at 21:53
  • yes it works but you have to eval the script string `engine.eval(script);` and then get the var but casting to Double and not to Long: `long timestamp = ((Double) engine.get("timestamp")).longValue();` – max Oct 15 '15 at 22:04
  • The answer may not be native Java, but until Joda-time gives use a better answer, this is it. I use the code snippet I show you, with the `Double` correction. – Katedral Pillon Oct 15 '15 at 22:54