使用DateTimeFormatterBuilder解析非UTC日期 - java

我正在尝试解析从Bitbucket event payload收到的以下日期字符串:

2017-09-19T10:39:36+1000

当输入日期的偏移量为+0000时,它可以工作,但+1000不能。

这是一个稍微不标准的日期字符串(从JDK的角度来看),因为偏移量中没有冒号。因此,我制作了一个自定义的DateTimeFormatter,当偏移量为+0000时可以使用:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
    .optionalStart()
    .appendOffset("+HHMM", "+0000")
    .optionalEnd()
    .toFormatter();

但是,当偏移量如上所述为+1000时,它将失败并显示:

无法从字符串“ 2017-09-19T10:39:36 + 1000”反序列化类型java.time.OffsetDateTime的值:无法反序列化java.time.OffsetDateTime:(java.time.format.DateTimeParseException)文本'2017-09-19T10: 39:36 + 1000'无法在索引19处解析

如果接收到的日期字符串使用偏移量+0000,则它将起作用。如何解析所有时区?

更新-额外内容:

这用于构造JavaTimeModule的实例,该实例用于通知ObjectMapper输入的日期格式:

JavaTimeModule javaTimeModule = new JavaTimeModule();
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
    .optionalStart()
    .appendOffset("+HHMM", "+0000")
    .optionalEnd()
    .toFormatter();
// This also fails:
// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssx");
LocalDateTimeDeserializer deserializer = new LocalDateTimeDeserializer(formatter);
javaTimeModule.addDeserializer(LocalDateTime.class, deserializer);
// MAPPER is an instance of com.fasterxml.jackson.databind.ObjectMapper
MAPPER.registerModule(javaTimeModule);

参考方案

对于解析+1000,下面的代码将起作用。

package com.iamninad.qa;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class TimeFormat {

    public static void main(String[] args) throws IOException {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
        System.out.println(dateTimeFormatter.parse("2017-09-19T10:39:36+1000"));
        LocalDateTimeDeserializer deserializer = new LocalDateTimeDeserializer(dateTimeFormatter);

        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addDeserializer(LocalDateTime.class, deserializer);
        ObjectMapper MAPPER = new ObjectMapper();
        MAPPER.registerModule(javaTimeModule);

        // serialize object

        String s = MAPPER.writeValueAsString(new Data());
        System.out.println(s);

        // deserialize object

        String json = "{\"date\":\"2017-09-19T10:39:36-0830\"}";
        String json1 = "{\"date\":\"2017-09-19T10:39:36+1000\"}";

        Data data = MAPPER.readValue(json, Data.class);
        System.out.println(data.toString());

        Data data1 = MAPPER.readValue(json1, Data.class);
        System.out.println(data1.toString());
    }

}

class Data {
    // Just to generate a sample data
    private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
    private LocalDateTime date = LocalDateTime.parse("2017-09-19T10:39:36+1000", dateTimeFormatter);

    public LocalDateTime getDate() {
        return date;
    }

    public void setDate(LocalDateTime date) {
        this.date = date;
    }

    @Override
    public String toString() {
        return "Data{" +
                "date=" + date +
                '}';
    }
}

如果要解析+10:00,则对格式为+10:00或模式yyyy-MM-dd'T'HH:mm:ssXXX的字段使用ISO_OFFSET_DATE_TIME,它将采用任何一种格式。我猜这个问题在jdk 9中已解决

OffsetDateTime.parse("2017-09-19T10:39:36+10:00")

还只能以一种格式(即+10:00而不是+1000)解析时间,您需要将格式化程序指定为parse方法

OffsetDateTime.parse("2017-09-19T10:39:36+1000",DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZZZ"))

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java

我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…

Java-如何将此字符串转换为日期? - java

我从服务器收到此消息,我不明白T和Z的含义,2012-08-24T09:59:59Z将此字符串转换为Date对象的正确SimpleDateFormat模式是什么? java大神给出的解决方案 这是ISO 8601标准。您可以使用SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM…

java.net.URI.create异常 - java

java.net.URI.create("http://adserver.adtech.de/adlink|3.0") 抛出java.net.URISyntaxException: Illegal character in path at index 32: http://adserver.adtech.de/adlink|3.0 虽然n…

JAVA 8具有任何匹配属性的对象的过滤器列表 - java

我的要求是通过匹配任何属性的字符串来过滤对象列表。例如,假设Contact类具有三个属性:街道,城市,电话。我知道java流过滤器是如何工作的,在这里我必须将输入字符串与每个属性进行比较,如下所示:contactList.stream().filter(contact -> contact.getStreet().equals("dubai&…