2

I have dates in text format of the form dd-mmm-yy or d-mmm-y, where months are abbreviations in letters (for example, 4-Nov-09 or 12-Dec-05, etc...) I would like to parse it to produce a java.util.Date object.

Could this be achieved by leveraging the java.text.DateFormat class? Or is there another easy way of doing this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
David Menard
  • 2,261
  • 3
  • 43
  • 67

7 Answers7

4

You may need to use the SimpleDateFormat for parsing custom formats. This article explains the details of formatting.

"d-MMM-yyyy" corresponds to 4-Nov-2009
Vincent Ramdhanie
  • 102,349
  • 23
  • 137
  • 192
  • this takes a date and formats it to a string, i need the oposite, any other examples? – David Menard Nov 12 '09 at 21:38
  • You want to parse a string to date, so use the `parse` method. – BalusC Nov 12 '09 at 21:39
  • It does both ways. Use parse() to go from String to Date – Vincent Ramdhanie Nov 12 '09 at 21:39
  • Note: SimpleDateFormat is not synchronized. I discovered this when I was supporting a Tomcat application that crashed due to two threads playing with the same memory area simultaneously. If you use SimpleDateFormat in a web application then ensure you instantiate a new object for each web request. – PP. Nov 12 '09 at 22:36
2

SimpleDateFormat is the class normally used for this. Note that this class is not thread-safe (somewhat counter-intuitively) and if you're using this in a threaded context, then investigating Joda and its DateTimeFormatter is worthwhile.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
1

You can do it with java.text.SimpleDateFormat. Click the link, you'll see all patterns.

For 1-2 digit days you can use the d pattern. For 3-character month abbreviations you can use the MMM pattern. For 2 digit years you can use the yy pattern.

So the following should do:

String dateString = "4-Nov-09";
SimpleDateFormat sdf = new SimpleDateFormat("d-MMM-yy");
Date date = sdf.parse(dateString);
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
1

Whatever you do, please use a Locale. That way, you'll still get reasonable results when the input comes in with a month name in French.

shoover
  • 3,071
  • 1
  • 29
  • 40
1

java.time

This is the modern answer. The DateFormat class mentioned in the question and its SimpleDateFormat subclass used in most of the old answers are notoriously troublesome and long outdated. Don’t use any of those. Don’t use Date either, it’s poorly designed and long outdated too.

Since you have got a two-digit year (09 and 05 in your examples), you need to decide on a century. In the first round I am assuming that the year is in the range 2000 through 2099.

First we need a formatter:

static DateTimeFormatter dateFormatter
        = DateTimeFormatter.ofPattern("d-MMM-uu", Locale.ENGLISH);

DateTimeFormatter is thread safe, so we’re happy with one instance for all to use. @shoover is correct that we should provide a locale. Use the formatter like this:

    String text = "4-Nov-09";
    LocalDate date = LocalDate.parse(text, dateFormatter);
    System.out.println("Date: " + date);

Output is:

Date: 2009-11-04

Validate

For validation, in particular of the correct interpretation of the two-digit year, I recommend that you add a range check. For example, to validate that the parsed date is not more than 10 years into the past or future:

    LocalDate today = LocalDate.now(ZoneId.systemDefault());
    if (date.isBefore(today.minusYears(10))
            || date.isAfter(today.plusYears(10))) {
        System.err.println("This date can’t be right");
    }

For many purposes you will know in advance that the date is either in the past or in the future and can narrow down the valid interval even further than in my example.

Other centuries

If the years can go outside the 20xx range, we control the interpretation of the year through a DateTimeFormatterBuilder and its appendValueReduced method. Refer to one of the related answers in the list of links below.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

Check out SimpleDateFormat

examples

Omnipresent
  • 29,434
  • 47
  • 142
  • 186
0

You could try this library dateparser.

It can recognize any String automatically, and parse it into Date, Calendar, LocalDateTime, OffsetDateTime correctly.

With it, you don't have to prepare any appropriate patterns:

Date date = DateParserUtils.parseDate("12-Dec-05");

The date will be Mon Dec 12 00:00:00 CST 2005

Is it cool?

sulin
  • 358
  • 5
  • 7
  • What we’d really like to have from `12-Dec-05` would be a `LocalDate` (it’s a date without time of day). Is that unsupported? Some might also expect December 5, 2012 from your string, I’m uncomfortable with not specifying which we want. – Ole V.V. Sep 17 '19 at 15:21
  • 1
    In my opinion, `12-Dec-05` is similar to `Dec, 12, 05`, I don't know which is more widely used. But `dateparser` could be customized, you can change it easily. About `LocalDate`, you could use `LocalDateTime#toLocalDate` to get. – sulin Sep 18 '19 at 03:08