我试图用波兰语言环境中的格式d MMMM-yyyy解析日期(2020年12月3日(,但无法解析。但是,为什么同样的解析在英语等任何其他语言环境中都能正常工作呢?下面是不起作用的代码示例。有人能帮忙吗?
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();
}
您似乎混淆了解析和格式化。
由于您在English
中输入了日期字符串,您需要使用Locale.ENGLISH
来解析,并且您需要使用另一个具有Locale("pl", "PL")
的SimpleDateFormat
实例来使用new Locale("pl", "PL")
格式化所获得的java.util.Date
对象。
演示:
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();
}
}
}
输出:
Thu Dec 03 00:00:00 GMT 2020
3 grudnia 2020
我相信您已经知道,日期-时间对象只存储日期-时间信息*1,并且没有格式化信息。打印时,日期-时间对象打印其类的toString
实现返回的字符串。此外,java.util.Date
对象并不代表真正的日期-时间类,因为它只存储毫秒(例如,new Date()
对象是用January 1, 1970, 00:00:00 GMT
的毫秒数实例化的(,当您打印它时,它会计算JVM时区中的日期时间并打印相同的时间,即,如果您在世界任何地方的给定时刻执行以下两行,
Date date = new Date();
System.out.println(date.getTime());
你会得到相同的号码。查看此答案以获取演示。
java.util
的日期时间API和它们的格式API、SimpleDateFormat
已经过时,并且由于如此多的此类黑客,它们是错误的。建议完全停止使用它们,并切换到现代日期时间API。有关现代日期时间API的更多信息,请访问跟踪:日期时间。
注意:如果您正在为Android项目工作,并且您的Android API级别仍然不符合Java-8,请检查通过desugaring和如何在Android项目中使用ThreeTenABP提供的Java 8+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);
}
}
输出:
2020-12-03
3 grudnia 2020
*1现代日期时间API还存储时区信息。查看概览以了解有关这些类的更多信息
当试图确定解析的问题时,总是做相反的事情,即生成输出,看看解析的输入应该是什么样子。这项技术对于所有与解析相关的问题都非常有用,无论是解析日期字符串、XML文档、JSON文本等。
因此,我们尝试以给定格式打印日期值,以查看解析时的预期:
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()));
在Java7中,我得到了3 grudzień 2020
在Java 8、9、11和14中,我得到了3 grudnia 2020
。
如果要解析3 December 2020
,请使用例如Locale.ENGLISH
。