如何将Java字符串“EEEMMMddHH:mm:sszzzyyyy”日期类型转换为Javautil.Date“yyyy-MM-dd”
我的源日期类型是EEE MMM dd HH:mm:ss zzz yyyy. 例如,Sat Dec 12 00:00:00 KST 2020但我的目标日期类型是格式为 Java 日期类型yyyy-MM-dd。所以我制作了将Java String类型转换EEE MMM dd HH:mm:ss zzz yyyy为java util对象的方法。
private static Date getDate(String beforeDate) throws Exception{
SimpleDateFormat readFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
Date rdate = readFormat.parse(beforeDate);
SimpleDateFormat writeFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
String format = writeFormat.format(rdate);
System.out.println(format);
return writeFormat.parse(format);
}
System.out.println(format) line 打印出我期望的正确值。
2020-12-12
2020-12-12
2013-01-01
但是返回值的类型是错误的。该方法的返回值似乎没有受到影响。
System.out.println(getDate("Sat Dec 12 00:00:00 KST 2020"));
上一行Sat Dec 12 00:00:00 KST 2020再次打印。我不知道在转换 Java 日期类型时哪些代码是错误的。
回答
tl;博士
ZonedDateTime
.parse(
"Sat Dec 12 00:00:00 KST 2020" ,
DateTimeFormatter
.ofPattern( "EEE MMM dd HH:mm:ss zzz uuuu" )
.withLocale( Locale.US )
)
.toLocalDate()
.toString()
2020-12-12
避免遗留的日期时间类
您正在使用多年前被现代java.time类取代的糟糕的日期时间类。切勿使用Date, Calendar, 或SimpleDateFormat。
你说:
我的目标日期类型是格式为 yyyy-MM-dd 的 Java 日期类型。
显然,你希望Date举行一个约会。它不是。本java.util.Date类代表一个时刻,如被看见在UTC时间的日的日期。该java.sql.Date班假装仅持有一个日期,但它也确实包含了时间的日的日期为UTC看到。
java.util.Date类的众多问题之一是其toString方法的行为。该方法在生成文本时动态应用 JVM 的当前默认时区。此反功能可能会导致您感到困惑。
LocalDate
相反,您应该使用java.time.LocalDate来表示一个没有时间和时区或偏移量的日期值。
ZonedDateTime
首先使用DateTimeFormatter该类来解析整个输入字符串。这导致一个ZonedDateTime对象代表一个时刻,就像通过特定地区的人们使用的挂钟时间看到的那样。
示例代码
String input = "Sat Dec 12 00:00:00 KST 2020" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM dd HH:mm:ss zzz uuuu" ).withLocale( Locale.US ) ;
ZonedDateTime zdt = ZonedDateTime.parse( input , f ) ;
从该ZonedDateTime对象中,提取一个LocalDate.
LocalDate localDate = zdt.toLocalDate() ;
查看此代码在 IdeOne.com 上实时运行。
zdt.toString(): 2020-12-12T00:00+09:00[亚洲/首尔]
ld.toString(): 2020-12-12
关于java.time
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat。
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。Hibernate 5 & JPA 2.2 支持java.time。java.sql.*
从哪里获得 java.time 类?
- Java SE 8、 Java SE 9、 Java SE 10、 Java SE 11和更高版本 - 标准 Java API 的一部分,具有捆绑实现。
- Java 9带来了一些小功能和修复。
- Java SE 6和Java SE 7
- 大部分java.time功能在ThreeTen- Backport中向后移植到 Java 6 & 7 。
- 安卓
- 更高版本的 Android (26+) 捆绑了java.time类的实现。
- 对于早期的 Android (<26),一个称为API 脱糖的过程带来了java.time功能的一个子集,这些功能最初不是内置于 Android 中的。
- 如果脱糖不能满足您的需求,ThreeTenABP项目会将 ThreeTen-Backport(如上所述)适配到 Android。请参阅如何使用ThreeTenABP ...。