Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 时区有冒号时如何解决解析异常?_Java_Datetime_Simpledateformat_Date Format - Fatal编程技术网

Java 时区有冒号时如何解决解析异常?

Java 时区有冒号时如何解决解析异常?,java,datetime,simpledateformat,date-format,Java,Datetime,Simpledateformat,Date Format,我正在以字符串的形式从Web服务接收DateTime。此DateTime字符串的一个示例是:“DateTime”:“2021-06-06T04:54:41-04:00” 这个2021-06-06T04:54:41-04:00或多或少地匹配ISO-8601格式,所以我使用了这个模式来解析它:yyyy-MM-dd'T'HH:MM:ssZ。但是,响应日期时间的时区部分中的冒号会导致问题2021-06-06T04:54:41-04:00给出了解析异常,但2021-06-06T04:54:41-0400进

我正在以
字符串的形式从Web服务接收
DateTime
。此
DateTime
字符串的一个示例是:
“DateTime”:“2021-06-06T04:54:41-04:00”

这个
2021-06-06T04:54:41-04:00
或多或少地匹配ISO-8601格式,所以我使用了这个模式来解析它:
yyyy-MM-dd'T'HH:MM:ssZ
。但是,响应日期时间的时区部分中的冒号会导致问题
2021-06-06T04:54:41-04:00给出了解析异常,但
2021-06-06T04:54:41-0400进行了解析

下面的代码应该更好地解释它:

public void stringToDate() {

        String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";  //ISO - 8601 Format
        TimeZone timeZoneEST = TimeZone.getTimeZone("US/Eastern");
        SimpleDateFormat sdf = new SimpleDateFormat(pattern, new Locale("en", "US"));
        sdf.setLenient(false);
        sdf.setTimeZone(timeZoneEST);
        
        String timeFromWebService = "2021-06-06T04:54:41-04:00";
        try {
            Date parsedDate = sdf.parse(timeFromWebService); // not working because of colon in timezone part
            System.out.println(parsedDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        
        try {
            Thread.sleep(1000);  //sleep to avoid interleaving output from stacktrace (above) and syso (below)
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        
        String timeFromWebServiceModified = "2021-06-06T04:54:41-0400";  //removed colon from timezone part
        try {
            Date parsedDate = sdf.parse(timeFromWebServiceModified); // working because colon is removed in timezone part
            System.out.println(parsedDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        
    }

我希望在不修改响应的情况下处理此解析
DateTime
。关于如何解析原始
DateTime
的任何建议。任何关于使用哪种模式的建议都将非常有用。

java.util
日期时间API及其格式化API,
SimpleDataFormat
已经过时且容易出错。建议完全停止使用,并切换到*

解决方案使用
java.time
,现代API:

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d'T'H:m:s[XXX][XX][X]", Locale.ENGLISH);
        
        //Test
        Stream.of(
                    "2021-06-06T04:54:41-04:00",
                    "2021-06-06T04:54:41-0400",
                    "2021-06-06T04:54:41-04",
                    "2021-06-06T04:54:41Z"                  
        ).forEach(s -> System.out.println(OffsetDateTime.parse(s, dtf)));
    }
}
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41Z
输出:

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d'T'H:m:s[XXX][XX][X]", Locale.ENGLISH);
        
        //Test
        Stream.of(
                    "2021-06-06T04:54:41-04:00",
                    "2021-06-06T04:54:41-0400",
                    "2021-06-06T04:54:41-04",
                    "2021-06-06T04:54:41Z"                  
        ).forEach(s -> System.out.println(OffsetDateTime.parse(s, dtf)));
    }
}
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41Z

检查

了解更多关于
java.time
、来自的*

使用传统API的解决方案:

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d'T'H:m:s[XXX][XX][X]", Locale.ENGLISH);
        
        //Test
        Stream.of(
                    "2021-06-06T04:54:41-04:00",
                    "2021-06-06T04:54:41-0400",
                    "2021-06-06T04:54:41-04",
                    "2021-06-06T04:54:41Z"                  
        ).forEach(s -> System.out.println(OffsetDateTime.parse(s, dtf)));
    }
}
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41Z
SimpleDataFormat
没有指定可选模式的功能,就像我们使用方括号和
DateTimeFormatter
一样。在这种情况下,您可以创建多个
SimpleDataFormat
实例,并对每个实例进行尝试

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) {
        SimpleDateFormat sfdArr[] = {
                            new SimpleDateFormat("y-M-d'T'H:m:sXXX", Locale.ENGLISH),
                            new SimpleDateFormat("y-M-d'T'H:m:sXX", Locale.ENGLISH),
                            new SimpleDateFormat("y-M-d'T'H:m:sX", Locale.ENGLISH)
        };
        
        String []strDateTimeArr = {
                    "2021-06-06T04:54:41-04:00",
                    "2021-06-06T04:54:41-0400",
                    "2021-06-06T04:54:41-04",
                    "2021-06-06T04:54:41Z"                  
        };
        
        for(String s : strDateTimeArr) {
            Date date = null;
            for(SimpleDateFormat sdf : sfdArr) {
                try {
                    date = sdf.parse(s);
                }catch(ParseException e) {
                    //...
                }
            }
            System.out.println(date);
        }
    }
}


*无论出于何种原因,如果您必须坚持使用Java6或Java7,您可以使用哪个backport将大部分Java.time功能移植到Java6&7。如果您正在为Android项目工作,并且您的Android API级别仍然不符合Java-8,请检查并确认。

我建议您不要使用
时区
简化格式
日期
。这些类设计得很糟糕,而且很早就过时了,
SimpleDateFormat
尤其是出了名的麻烦。相反,只需使用
OffsetDateTime
from及其一个arg
parse
方法。我将继续讨论j8+api:-)。这是我在j8+api中看到的另一个问题——如果你认为值得的话,你能投票支持Q吗。