0

I have this trash DateFormat in a log file that need to parse in order to compare it.

It’s in this format. Mon 03-Mai-21

My try:

    DateFormat format = new SimpleDateFormat("EEE FF-MMM-YY", Locale.GERMAN);
    String test = "Mon 03-Mai-21";
    Date date = null;
    try {
        date = format.parse(test);
    } catch (ParseException e) {
        e.printStackTrace();
    }

I’m getting a ParseException when trying to parse, but I have no clue what’s wrong with my pattern?

My expected result is 2021-05-03.

4
  • Don’t ever use SimpleDateFormat and Date. They are so poorly designed, so cumbersome and error-prone to work with and so long outdated. Use DateTimeFormatter and LocalDate from java.time, the modern Java date and time API. And enjoy. Commented Nov 10, 2021 at 16:17
  • What is your expected result? 2021-05-17? 2021-05-03? Or? Commented Nov 10, 2021 at 16:27
  • 1
    okay I will try that, 2021-05-03 it is Commented Nov 10, 2021 at 16:34
  • Thank you, danke schön. Two points for your future questions: (1) when asking about code that doesn’t work, always state the expected/desired behaviour. Even when, as here, it looked like it was obvious. (2) When providing more information (which is often necessary and always welcome), edit the question so we have everything in one place. Many readers don’t come around to reading the comments. Commented Nov 10, 2021 at 17:10

1 Answer 1

2

java.time

I recommend that you use java.time, the modern Java date and time API, for your date work.

Declare a formatter for your format:

private static Map<Long, String> dayOfWeekAbbreviations
        = Map.ofEntries(
                Map.entry(1L, "Mon"),
                Map.entry(2L, "Die"),
                Map.entry(3L, "Mit"),
                Map.entry(4L, "Don"),
                Map.entry(5L, "Fre"),
                Map.entry(6L, "Sam"),
                Map.entry(7L, "Son"));

private static final DateTimeFormatter DATE_FORMATTER
        = new DateTimeFormatterBuilder()
                .appendText(ChronoField.DAY_OF_WEEK, dayOfWeekAbbreviations)
                .appendPattern(" dd-MMM-uu")
                .toFormatter(Locale.GERMAN);    

Parse like this:

    String test = "Mon 03-Mai-21";
    LocalDate date = LocalDate.parse(test, DATE_FORMATTER);
    System.out.println(date);

Output:

2021-05-03

Java assumes that the days of the week are abbreviated Mo., Di., Mi., Do., Fr., Sa., So. (at least my Java 11 does; I think there are Java version where the abbreviations come without the dots by default). Since your abbreviation was Mon for Montag (Monday), we needed to provide our own abbreviations. This is what I do through the map. I don’t know which abbreviations you are getting for the other days of the week, so please fill the right ones into the map yourself.

The other possible solution of course is to make sure the strings you are getting use Java’s abbreviations. Then you can use EEE in your format pattern string as in your question, which would make the formatter somewhat simpler.

What went wrong in your code?

There are three issues with what you tried:

  1. As I said, EEE in your format pattern string expects a two-letter day-of-week abbreviation like Mo. so cannot accept Mon. This caused the exception you saw.
  2. FF is for the “day of week in month”. So you were really trying to parse your string as the 3rd Monday of May 2021, which was why I asked whether you expected 17th of May. Lower case dd is for day of month.
  3. Upper case YY for year is wrong. Upper case Y is for week-based year and only useful with a week number. For year you would need lower case y with SimpleDateFormat. With DateTimeFormatter you may use u or y with a different meaning for years before year 1.

Links

Sign up to request clarification or add additional context in comments.

6 Comments

very strange, java.time.DateTimeFormatter has a different interpretation of F - it just gives back the weekday as number (e.g. it returns 1 for 2021-11-22; while SimpleDateFormat returns 4) IDEone
@user16320675 The pattern letters are inspired from Unicode but with some variation. For F the standard says Day of Week in Month (numeric). The example (2) is for the 2nd Wed in July. The way I read the docs both SimpleDateFormat and DateTImeFormatter follow this faithfully. I will do some experiments.
Really!! @user16320675 The Java 8 documentation of DateTimeFormatter says that F is week-of-month. In Java 11 the documentation is changed to day-of-week-in-month (in agreement with Unicode), but you are right, it still seems to produce the day number of the aligned week of the month: 1 on the 1st of the month, 2 on 2nd through 7 on 7th, then 1 on 8th, etc. Is it a bug?
Their understanding of what day-of-week-in-month means neither agrees with Unicode nor with SimpleDateFormat. They may have fixed it the way they wanted to, but I still call it a bug. @user16320675
agreed. The DateTimeFormatter implementation is kind of useless, basically day-of-month modulo 7 - the SimpleDateFormat / Unicode definition is more powerful (like having an event every second Monday of a month)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.