1

I tried to parse the date (3 December, 2020) with format d MMMM yyyy in Polish Locale but it is unable to parse. But why the same parsing is working fine in any other locale like english, etc. Below is the code sample which is not working. Can anyone please help on this ?

    Locale loc = new Locale("pl", "PL");
    String date = "3 December 2020";
    SimpleDateFormat sdFormat =
            new SimpleDateFormat("d MMMM yyyy", loc);
    sdFormat.setLenient(false);
    try {
        Date d = sdFormat.parse(date);
        System.out.println(d);
    } catch (ParseException e) {
        e.printStackTrace();
    }
Amit Agarwal
  • 67
  • 1
  • 1
  • 12
  • Does this answer your question? [Parsing date in polish locale in Joda?](https://stackoverflow.com/questions/26723987/parsing-date-in-polish-locale-in-joda) – Bishan Dec 04 '20 at 04:25
  • December may not be recognized in Polish, try changing to 12 and use MM – Don Ha Dec 04 '20 at 04:26
  • 1
    I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `LocalDate` and `DateTimeFormatter`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Dec 04 '20 at 04:43

2 Answers2

1

It seems you got confused with parsing and formatting.

Since your input date string in English, you need to use Locale.ENGLISH for parsing and you need another instance of SimpleDateFormat with Locale("pl", "PL") to format the obtained java.util.Date object with new Locale("pl", "PL").

Demo:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class Main {
    public static void main(String args[]) {
        Locale loc = new Locale("pl", "PL");
        String date = "3 December 2020";
        SimpleDateFormat sdfForParsing = new SimpleDateFormat("d MMMM yyyy", Locale.ENGLISH);
        SimpleDateFormat sdfForFormatting = new SimpleDateFormat("d MMMM yyyy", loc);
        sdfForParsing.setLenient(false);
        try {
            Date d = sdfForParsing.parse(date);
            System.out.println(d);
            String localiseByPolish = sdfForFormatting.format(d);
            System.out.println(localiseByPolish);

        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

Output:

Thu Dec 03 00:00:00 GMT 2020
3 grudnia 2020

I believe you already know that a date-time object stores just the date-time information*1and no formatting information. On printing, a date-time object prints the string returned by the toString implementation of its class. Also, a java.util.Date object does not represent a true date-time class as it stores just the milliseconds (e.g. new Date() object is instantiated with the number of milliseconds from January 1, 1970, 00:00:00 GMT) and when you print it, it calculates the date-time in your JVM's timezone and prints the same i.e. if your execute the following two lines at a given moment in any part of the world,

Date date = new Date();
System.out.println(date.getTime());

you will get the same number. Check this answer for a demo.

The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and because of so many such hacks, they are error-prone. It is recommended to stop using them completely and switch to the modern date-time API. Learn more about the modern date-time API at Trail: Date Time.

Note: If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Using the modern date-time API:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;
import java.util.Locale;

public class Main {
    public static void main(String args[]) {
        Locale loc = new Locale("pl", "PL");
        String date = "3 December 2020";
        DateTimeFormatter dtfForParsing = DateTimeFormatter.ofPattern("d MMMM yyyy", Locale.ENGLISH)
                                            .withResolverStyle(ResolverStyle.LENIENT);
        DateTimeFormatter dtfForFormatting = DateTimeFormatter.ofPattern("d MMMM yyyy", loc);
        LocalDate localeDate = LocalDate.parse(date, dtfForParsing);
        System.out.println(localeDate);
        String localiseByPolish = localeDate.format(dtfForFormatting);
        System.out.println(localiseByPolish);
    }
}

Output:

2020-12-03
3 grudnia 2020

*1The modern date-time API store also the timezone information. Check Overview to learn more about these classes.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
-1

When trying to determine problems with parsing, always do the opposite, i.e. generate output, to see what the input for parsing should look like. This is a technique that is very useful for all parsing related issues, whether parsing date strings, XML documents, JSON texts, etc.

So, we try printing a date value with the given format, to see what it would expect when parsing:

Locale loc = new Locale("pl", "PL");
SimpleDateFormat sdFormat = new SimpleDateFormat("d MMMM yyyy", loc);
sdFormat.setLenient(false);

Calendar cal = Calendar.getInstance(loc);
cal.clear();
cal.set(2020, Calendar.DECEMBER, 3);
System.out.println(sdFormat.format(cal.getTime()));

In Java 7, I get 3 grudzień 2020.
In Java 8, 9, 11, and 14, I get 3 grudnia 2020.

If you want to parse 3 December 2020, then use e.g. Locale.ENGLISH.

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • OP has specifically mentioned `"3 December 2020"` as the date string to be processed. Why are you suggesting to change the problem to align it with your solution? – Arvind Kumar Avinash Dec 04 '20 at 13:43
  • @ArvindKumarAvinash Please read the answer. Now read last line again. If OP want `"3 December 2020"` to parse, then OP cannot use Polish locale, but must use e.g. English locale, and *that's the only code change suggested* by this answer. --- The rest is guidance for how to **research** the problem, so OP can decide what to do about it. It's often very difficult to fix a problem if you don't understand how it is wrong. This helps you figure out how/why it is failing. – Andreas Dec 04 '20 at 13:47