简体   繁体   English

无法在 Java 的波兰语言环境中解析格式为 d MMMM yyyy 的日期

[英]Unable to Parse a date of format d MMMM yyyy in Polish Locale in Java

I tried to parse the date (3 December, 2020) with format d MMMM yyyy in Polish Locale but it is unable to parse.我尝试在波兰语语言环境中使用格式 d MMMM yyyy 解析日期(2020 年 12 月 3 日),但无法解析。 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();
    }

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") .由于您输入的日期字符串为English ,因此您需要使用Locale.ENGLISH进行解析,并且您需要另一个带有Locale("pl", "PL")SimpleDateFormat实例来格式化获得的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: 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 *1 and no formatting information .我相信您已经知道日期时间 object 只存储日期时间信息*1没有格式信息 On printing, a date-time object prints the string returned by the toString implementation of its class.在打印时,日期时间 object 打印其 class 的toString实现返回的字符串。 Also, a java.util.Date object does not represent a true date-time class as it stores just the milliseconds (eg 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 ie if your execute the following two lines at a given moment in any part of the world, Also, a java.util.Date object does not represent a true date-time class as it stores just the milliseconds (eg new Date() object is instantiated with the number of milliseconds from January 1, 1970, 00:00:00 GMT ) 并且当您打印它时,它会计算 JVM 时区中的日期时间并打印相同的内容,即如果您在世界任何地方的给定时刻执行以下两行,

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. java.util 的日期时间java.util及其格式 API、 SimpleDateFormat已过时,并且由于有很多这样的黑客攻击,它们很容易出错。 It is recommended to stop using them completely and switch to the modern date-time API .建议完全停止使用它们并切换到现代日期时间 API Learn more about the modern date-time API at Trail: Date Time .Trail: Date Time中了解有关现代日期时间 API 的更多信息。

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 . 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:使用现代日期时间 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: Output:

2020-12-03
3 grudnia 2020

*1The modern date-time API store also the timezone information. *1 现代日期时间 API还存储时区信息。 Check Overview to learn more about these classes.检查概述以了解有关这些课程的更多信息。

When trying to determine problems with parsing, always do the opposite, ie generate output, to see what the input for parsing should look like.当试图确定解析问题时,总是做相反的事情,即生成 output,看看解析的输入应该是什么样子。 This is a technique that is very useful for all parsing related issues, whether parsing date strings, XML documents, JSON texts, etc.这是一种对所有解析相关问题都非常有用的技术,无论是解析日期字符串、XML 文档、JSON 文本等。

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 .在 Java 7 中,我得到3 grudzień 2020
In Java 8, 9, 11, and 14, I get 3 grudnia 2020 .在 Java 8、9、11 和 14 中,我得到3 grudnia 2020

If you want to parse 3 December 2020 , then use eg Locale.ENGLISH .如果您想解析3 December 2020 ,请使用例如Locale.ENGLISH

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM