我正在尝试将代码从Java 8迁移到OpenJDK 11,在我试图解析日期字符串之前,一切进展都非常顺利。我有大量这些数据字符串来自数据库(不,我不能更改数据库),它们在Java 7中解析得很好,但在Java 11中失败。
一些注意事项:
有人能给我指明正确的方向吗?我最终需要对这些字符串做日期计算。
谢谢!
布鲁斯
package utility;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;
public class OpenJDK11DateDisaster {
public static void main(String args[])
{
/*
* Example of the date string that works with Java 8 but fails to
* parse in OpenJDK 11.
*
* Note: The Locale is identical between the two versions (US, English)
*
*/
/* Java 8 Output...
Java Version = 1.8.0_265
Broken Date = September 1, 2015 3:13:29 AM MDT
Convert mills to a date.
From mills date = September 1, 2015 3:13:29 AM MDT
Broken Date = September 1, 2015 3:13:29 AM MDT
Attempting to parse broken date.
Date in mills = 1441098809000
From mills date = September 1, 2015 3:13:29 AM MDT
Java 11 output...
Java Version = 11.0.8
Broken Date = September 1, 2015 3:13:29 AM MDT
Convert mills to a date.
From mills date = September 1, 2015 at 3:13:29 AM MDT
Broken Date = September 1, 2015 3:13:29 AM MDT
Attempting to parse broken date.
java.text.ParseException: Unparseable date: "September 1, 2015 3:13:29 AM MDT"
Unable to parse broken date.
Adding in the at...
at java.base/java.text.DateFormat.parse(DateFormat.java:395)
at utility.OpenJDK11DateDisaster.main(OpenJDK11DateDisaster.java:60)
Fixed date = September 1, 2015 at 3:13:29 AM MDT
java.text.ParseException: Unparseable date: " September 1, 2015 at 3:13:29 AM MDT"
at java.base/java.text.DateFormat.parse(DateFormat.java:395)
at utility.OpenJDK11DateDisaster.main(OpenJDK11DateDisaster.java:89)
Unable to parse fixed date.
*/
System.out.println("Java Version = " + System.getProperty("java.version"));
// This is the date that will parse in Java 7 but fails in Java 11
String BrokenDate = "September 1, 2015 3:13:29 AM MDT";
System.out.println("Broken Date = " + BrokenDate);
// Broken date converted to mills in Java 7.
long mills = 1441098809000L;
System.out.println("Convert mills to a date.");
DateFormat df2 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.US);
Date millDate = new Date(mills);
System.out.println("From mills date = " + df2.format(millDate));
System.out.println("Broken Date = " + BrokenDate);
/*
* Parse these old dates.
*/
System.out.println("Attempting to parse broken date.");
df2 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.US);
Date date = null;
try {
date = df2.parse(BrokenDate) ;
} catch (ParseException e) {
e.printStackTrace();
System.out.println();
System.out.println("Unable to parse broken date.");
// For some reason, they now put an "at" word between the date and the time.
// Here we put the "at" back in and see.
// See if we can fix it.
System.out.println("Adding in the at...");
StringList fields = Acl.split(BrokenDate, ' ');
String FixedDate = "";
Iterator iter = fields.iterator();
int count = 0;
while (iter.hasNext() ) {
String field = (String)iter.next();
count++;
FixedDate += " " + field;
if (count == 3) {
// add an at
FixedDate += " at";
}
}
System.out.println("Fixed date = " + FixedDate);
// Now see if it will parse
try {
date = df2.parse(FixedDate);
} catch (ParseException e2) {
e2.printStackTrace();
System.out.println();
System.out.println("Unable to parse fixed date.");
System.exit(-1);
}
System.out.println("Was able to parse Fixed Date " + date);
}
mills = date.getTime(); // From the BrokenDate
// Should be -62112243600000 as computed on a Java 7 machine
System.out.println("Date in mills = " + mills);
// Convert the mills to a date.
millDate = new Date(mills);
System.out.println("From mills date = " + df2.format(millDate));
}
}发布于 2020-10-13 15:14:45
根据文档https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/text/DateFormat.html,您似乎需要完整的格式
LONG is longer, such as January 12, 1952 or 3:30:32pm
FULL is pretty completely specified, such as Tuesday, April 12, 1952 AD or 3:30:42pm PST.如果可能的话,在解析方法(第395行)中在DateFormat.java上放置一个断点,以了解正在发生的事情。
发布于 2020-10-13 22:37:44
一个安全的选项是将MDT替换为相应的时区说明符Mountain Standard Time。
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String dateTimeStr = "September 1, 2015 3:13:29 AM MDT".replace("MDT", "Mountain Standard Time");
ZonedDateTime zdt = ZonedDateTime.parse(dateTimeStr,
DateTimeFormatter.ofPattern("MMMM d, u h:m:s a zzzz", Locale.ENGLISH));
System.out.println(zdt);
// Custom format
String formatted = zdt.format(DateTimeFormatter.ofPattern("EEEE MMMM dd uuuu 'at' hh:mm:ss a", Locale.ENGLISH));
System.out.println(formatted);
}
}输出:
2015-09-01T03:13:29-06:00[America/Denver]
Tuesday September 01 2015 at 03:13:29 AM注意:遗留的java.util日期-时间类已经过时,容易出错,它们的格式化API SimpleDateFormat也是如此。我建议您停止完全使用它们,转而使用现代日期时间API。在日期:时间上了解更多关于现代日期时间API的信息。
如果您是为您的Android项目这样做,并且您的Android级别仍然不符合Java-8,那么请检查通过desugaring提供的Java 8+ API和如何在安卓项目中使用ThreeTenABP。
带有遗留API的:
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) throws ParseException {
String dateTimeStr = "September 1, 2015 3:13:29 AM MDT".replace("MDT", "Mountain Standard Time");
Date date = new SimpleDateFormat("MMMM d, yyyy h:m:s a zzzz", Locale.ENGLISH).parse(dateTimeStr);
System.out.println(date);
// Custom format
String formatted = new SimpleDateFormat("EEEE MMMM dd yyyy 'at' hh:mm:ss a", Locale.ENGLISH).format(date);
System.out.println(formatted);
}
}https://stackoverflow.com/questions/64337726
复制相似问题