我不明白为什么这个代码会失败:
@Test
public void test() {
final SimpleDateFormat sdf= new SimpleDateFormat("yyyyMMddHHmm");
try {
sdf.setLenient(false);
Date d = sdf.parse("202003290230");
} catch (ParseException e){
e.printStackTrace();
}
}
我有个例外 java.text.ParseException: Unparseable date
.
如果我设置 sdf.setLenient(true)
然后它就工作了,但是返回的对象日期中的时间是'03:30',而不是'02:30'。
有人能解释一下这里发生了什么事吗?谢谢。
1条答案
按热度按时间ztyzrc3y1#
正如上帝蜘蛛在一篇评论中指出的那样,你真正的问题是,由于Spring的到来,时间不存在于你的默认时区中,也就是过渡到夏季时间(dst)。
java.time文件
我建议您在日期和时间工作中使用java.time,即现代的java日期和时间api。短视的答案是:使用
LocalDateTime
来自java.time。输出为:
2020-03-29t02:30
一
LocalDateTime
是一个没有时区的日期和时间。所以它不会发现时间不存在于你的时区。结果是字符串中的2:30。检测不存在的时间
似乎你在中欧时区或其他时区,夏季时间从三月的最后一个星期天开始,时钟从凌晨2点转到凌晨3点。所以没有2:30。假设你想知道,你可以:
时间2020-03-29t02:30在欧洲/巴黎不存在
java.time也会给你3:30的时间,而不是2:30的时间。所以当你从
ZonedDateTime
至LocalDateTime
在这种情况下,我们不再得到相同的时间,我们用它来检测不存在的时间。我进一步建议你使用
ZonedDateTime
过去的日期和时间,而不是LocalDateTime
.java 6?
这个项目是用java6和公司不想更新它…
time已经进行了后端口,我已经用backport测试了上面的代码,threeten backport,请参见底部的链接。
在Java8和更高版本以及更新的android设备上(api级别26),现代api是内置的。
在非android的java6和java7中,获得了三个十的backport,即现代类的backport(对于jsr310是三个十)。我不确定最新版本的threeten backport是适用于Java6还是仅适用于Java7(+)。如果这是一个问题,请返回几个版本,并找到一个同样适用于Java6的版本。
在旧的android上,要么使用desugaring,要么使用android版本的threeten backport。它叫3TENABP。在后一种情况下,请确保从导入日期和时间类
org.threeten.bp
有分装的。不要使用SimpleDataFormat
你尝试使用的日期和时间类,
Date
以及SimpleDateFormat
设计拙劣,过时已久。在您的例子中,它们显示的行为取决于代码中根本不存在的时区,这非常令人困惑。我建议你不要使用这些类。链接
oracle教程:date time解释如何使用java.time。
java规范请求(jsr)310,其中
java.time
第一次被描述。三十后港工程
java.time
到Java6和Java7(jsr-310为310)。通过desugaring提供Java8+API
threetenabp,android版threeten backport
问:如何在android项目中使用threetenabp,有非常透彻的解释。