[英]Exception parsing string to Date
I cannot see why this code is failing:我看不出为什么这段代码失败了:
@Test
public void test() {
final SimpleDateFormat sdf= new SimpleDateFormat("yyyyMMddHHmm");
try {
sdf.setLenient(false);
Date d = sdf.parse("202003290230");
} catch (ParseException e){
e.printStackTrace();
}
}
I get the exception java.text.ParseException: Unparseable date
.我收到异常
java.text.ParseException: Unparseable date
。
If I set sdf.setLenient(true)
then it works, but the time in the object Date returned is '03:30' and not '02:30'.如果我设置
sdf.setLenient(true)
那么它可以工作,但是 object 返回日期中的时间是“03:30”而不是“02:30”。
Can someone explain me what's going on in here?有人可以解释一下这里发生了什么吗? Thanks.
谢谢。
As OH GOD SPIDERS noted in a comment your real problem is that that time doesn't exist in you default time zone because of the spring forward , the transition to summer time (DST).正如 OH GOD SPIDERS 在评论中指出的那样,您真正的问题是,由于spring forward (过渡到夏令时(DST)),您的默认时区中不存在该时间。
I recommend that you use java.time, the modern Java date and time API, for your date and time work.我建议您使用 java.time,现代 Java 日期和时间 API,用于您的日期和时间工作。 The short-sighted answer is: use
LocalDateTime
from java.time.短视的答案是:使用 java.time 中的
LocalDateTime
。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmm");
String dateTimeString = "202003290230";
LocalDateTime ldt = LocalDateTime.parse(dateTimeString, formatter);
System.out.println(ldt);
Output is: Output 是:
2020-03-29T02:30
2020-03-29T02:30
A LocalDateTime
is a date and time without time zone. LocalDateTime
是没有时区的日期和时间。 So it doesn't discover that the time doesn't exist in your time zone.因此,它不会发现您的时区中不存在时间。 The result is 2:30 as in the string.
结果是字符串中的 2:30。
It seems you're in a Central European time zone or some other time zone where summer time began on the last Sunday in March, and the clocks were turned forward from 2 to 3 (AM).您似乎处于中欧时区或其他时区,夏季时间从 3 月的最后一个星期日开始,时钟从 2 点(上午)调快到 3 点。 So there was no 2:30.
所以没有2:30。 Supposing that you want to know, you may do:
假设你想知道,你可以这样做:
ZoneId zone = ZoneId.of("Europe/Paris");
ZonedDateTime zdt = ldt.atZone(zone);
if (zdt.toLocalDateTime().equals(ldt)) {
System.out.println("The time " + zdt + " exists");
} else {
System.out.println("The time " + ldt + " does not exist in " + zone);
}
The time 2020-03-29T02:30 does not exist in Europe/Paris
欧洲/巴黎不存在时间 2020-03-29T02:30
java.time too gives you 3:30 instead of 2:30 when given a time in the spring gap. java.time 在 spring 间隙中给定时间时也会给您 3:30 而不是 2:30。 So when converting back from
ZonedDateTime
to LocalDateTime
in this case we don't get the same time again, which we use for detecting the non-existing time.因此,在这种情况下,当从
ZonedDateTime
转换回LocalDateTime
时,我们不会再得到相同的时间,我们用它来检测不存在的时间。
I further recommend that you use ZonedDateTime
for past dates and times, not LocalDateTime
.我进一步建议您将
ZonedDateTime
用于过去的日期和时间,而不是LocalDateTime
。
This project is made with Java6 and the company doesn't want to update it, …
这个项目是用 Java6 做的,公司不想更新它,…
java.time has been backported, and I have tested the code above with the backport, ThreeTen Backport, see the link at the bottom. java.time 已经被反向移植,我已经用反向移植,ThreeTen Backport 测试了上面的代码,见底部的链接。
org.threeten.bp
with subpackages.org.threeten.bp
导入日期和时间类。 The date and time classes you were trying to use, Date
and SimpleDateFormat
, are poorly designed and long outdated.您尝试使用的日期和时间类
Date
和SimpleDateFormat
设计不佳且早已过时。 In your case they showed a behaviour that depends on a time zone that isn't present in the code at all, which is quite confusing.在您的情况下,他们表现出的行为取决于代码中根本不存在的时区,这非常令人困惑。 I recommend that you don't use those classes.
我建议您不要使用这些类。
java.time
was first described. java.time
。java.time
to Java 6 and 7 (ThreeTen for JSR-310). java.time
到 Java 6 和 7 的 backport(ThreeTen for JSR-310)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.