java SimpleDataFormat分析字符串错误

java SimpleDataFormat分析字符串错误,java,simpledateformat,Java,Simpledateformat,//这是我的密码 public static void main(String[] args) { String a = "19900416000000"; String b = "19900415000000"; DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); df.setLenient(false); try { df.parse(a); } catch (P

//这是我的密码

 public static void main(String[] args) {

    String a = "19900416000000";
    String b = "19900415000000";
    DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
    df.setLenient(false);

    try {
        df.parse(a);
    } catch (ParseException e) {
        System.out.println("a parse error");
        e.printStackTrace();
    }

    try {
        df.parse(b);
    }catch (ParseException e){
        System.out.println("b parse error");
        e.printStackTrace();
    }
//我得到一个错误,就像这样

b parse error
java.text.ParseException: Unparseable date: "19900415000000"
    at java.text.DateFormat.parse(DateFormat.java:366)
    at org.suanhua.elasticsearch.client.ETLTest.main(ETLTest.java:179)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
那么,a和b有什么不同?为什么解析(b)得到一个错误

//这是我的意思

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

//在intellij下使用jdk8,您的问题似乎与时区有关

在我的jdk1.8.091安装中测试所有时区

String a = "19900416000000";
String b = "19900415000000";
DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
df.setLenient(false);

for (String id : TimeZone.getAvailableIDs()) {
    df.setTimeZone(TimeZone.getTimeZone(id));
    try {
        df.parse(a);
    } catch (ParseException e) {
        System.out.println(id + ": " + e);
    }
    try {
        df.parse(b);
    } catch (ParseException e) {
        System.out.println(id + ": " + e);
    }
}
输出

如果您的默认时区是上述任一时区,那么它将失败,因为1990年4月15日的午夜不存在,因为那是夏令时开始的时间,即午夜,时钟被设置为凌晨1点,因此午夜不存在。

例如,JDK8中较新的date和time类可以解析字符串并给出

1990-04-16T00:00+09:00[Asia/Chongqing]
1990-04-15T01:00+09:00[Asia/Chongqing]
您会注意到,第二个字符串在输入字符串中表示00时有01。我使用了like(编辑:添加了创建
dtf
):

如果您只需要计算机的默认时区,可以使用
ZoneId.systemDefault()

在任何情况下,既然您使用的是JDK 8,那么您是否有充分的理由坚持使用过时的类
SimpleDataFormat
和friends?较新的类通常更易于使用

但是,如果你需要赶上夏季时差中的日期时间,你必须特别处理它。例如,将其转换回
LocalDateTime
,然后查看是否得到与解析的相同的结果


PS我仍然有一个我无法令人满意地解释的观察:Andreas提到的时区之一是CTT。我认为这是指中国台湾时间,所以我希望它与亚洲/台北相同。然而,当我把后者放入代码中时,我得到了
1990-04-15T00:00+08:00[亚洲/台北]
,也就是00小时,所以这里存在午夜0:00的时间。对于Andreas提到的其他5个时区,我得到了01小时。

1990--yyyy 04--MM 16--dd 00--HH 00--MM 00--ssI使用您的代码进行了编译。没有任何错误,和金邓一样。运行代码。没有错误。无法复制。好了,代码对我来说很好,也许你有错误的导入?试着清理一下你的项目。太棒了,中华人民共和国从1986年开始尝试DST,但从1992年起放弃了DST。中国现在在全国使用一个时区(UTC+8)。非常感谢你!这个问题困扰了我很长时间
1990-04-16T00:00+09:00[Asia/Chongqing]
1990-04-15T01:00+09:00[Asia/Chongqing]
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        System.out.println(LocalDateTime.parse(b, dtf)
                               .atZone(ZoneId.of("Asia/Chongqing")));