代码之家  ›  专栏  ›  技术社区  ›  dehasi

杰克逊将日期从twitter反序列化为'zoneddatetime`

  •  2
  • dehasi  · 技术社区  · 6 年前

    我想将日期从Twitter反序列化为 ZonedDateTime . 我的程序在上失败 created_at 字段反序列化。

    我的域名类

    @JsonIgnoreProperties(ignoreUnknown = true)
    public final class Tweet {
    
        public final String id;
        public final String idStr;
        public final ZonedDateTime created_at;
        public final String text;
        public final long timestamp_ms;
        public final User user;
    
    
        @JsonCreator
        public Tweet(@JsonProperty("id") String id,
                     @JsonProperty("id_str") String idStr,
                     @JsonProperty("created_at") ZonedDateTime created_at,
                     @JsonProperty("text") String text,
                     @JsonProperty("timestamp_ms") long timestamp_ms,
                     @JsonProperty("user") User user) {
            this.id = id;
            this.idStr = idStr;
            this.created_at = created_at;
            this.text = text;
            this.timestamp_ms = timestamp_ms;
            this.user = user;
        }
    }
    

    我的解析方法

    public class TweetTest {
        private static final String TWEET = "{\"created_at\":\"Mon Aug 20 13:28:07 +0000 2018\",\"id\":1031533339793129472,\"id_str\":\"1031533339793129472\",\"text\":\"juntar dinheiro pra ir na prox tour do justin bieber que eu amo\",\"source\":\"\\u003ca href=\\\"http:\\/\\/twitter.com\\/download\\/iphone\\\" rel=\\\"nofollow\\\"\\u003eTwitter for iPhone\\u003c\\/a\\u003e\",\"truncated\":false,\"in_reply_to_status_id\":null,\"in_reply_to_status_id_str\":null,\"in_reply_to_user_id\":null,\"in_reply_to_user_id_str\":null,\"in_reply_to_screen_name\":null,\"user\":{\"id\":1239680360,\"id_str\":\"1239680360\",\"name\":\"ste\",\"screen_name\":\"flowxrst\",\"location\":\"Manaus, Brasil\",\"url\":null,\"description\":null,\"translator_type\":\"none\",\"protected\":false,\"verified\":false,\"followers_count\":1444,\"friends_count\":378,\"listed_count\":5,\"favourites_count\":13566,\"statuses_count\":40091,\"created_at\":\"Sun Mar 03 19:38:25 +0000 2013\",\"utc_offset\":null,\"time_zone\":null,\"geo_enabled\":true,\"lang\":\"pt\",\"contributors_enabled\":false,\"is_translator\":false,\"profile_background_color\":\"FFFFFF\",\"profile_background_image_url\":\"http:\\/\\/abs.twimg.com\\/images\\/themes\\/theme1\\/bg.png\",\"profile_background_image_url_https\":\"https:\\/\\/abs.twimg.com\\/images\\/themes\\/theme1\\/bg.png\",\"profile_background_tile\":false,\"profile_link_color\":\"000000\",\"profile_sidebar_border_color\":\"FFFFFF\",\"profile_sidebar_fill_color\":\"DDEEF6\",\"profile_text_color\":\"333333\",\"profile_use_background_image\":false,\"profile_image_url\":\"http:\\/\\/pbs.twimg.com\\/profile_images\\/1030497329999237121\\/MLVfvoFy_normal.jpg\",\"profile_image_url_https\":\"https:\\/\\/pbs.twimg.com\\/profile_images\\/1030497329999237121\\/MLVfvoFy_normal.jpg\",\"profile_banner_url\":\"https:\\/\\/pbs.twimg.com\\/profile_banners\\/1239680360\\/1533144133\",\"default_profile\":false,\"default_profile_image\":false,\"following\":null,\"follow_request_sent\":null,\"notifications\":null},\"geo\":null,\"coordinates\":null,\"place\":null,\"contributors\":null,\"is_quote_status\":false,\"quote_count\":0,\"reply_count\":0,\"retweet_count\":0,\"favorite_count\":0,\"entities\":{\"hashtags\":[],\"urls\":[],\"user_mentions\":[],\"symbols\":[]},\"favorited\":false,\"retweeted\":false,\"filter_level\":\"low\",\"lang\":\"pt\",\"timestamp_ms\":\"1534771687826\"}";
    
        @Test
        public void jackson_parsesDateTime() throws IOException {
            DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
            ObjectMapper mapper = new ObjectMapper();
            mapper.registerModule(new JavaTimeModule());
            mapper.setDateFormat(dateFormat);
    
            Tweet tweet = mapper.readValue(TWEET, Tweet.class);
    
            Assert.assertNotNull(tweet);
        }
    
        @Test
        public void ztd_parse() throws ParseException {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy");
    
            ZonedDateTime.parse("Mon Aug 20 13:28:07 +0000 2018", formatter);
        }
    }
    

    两个测试都失败 om.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.time.zoneddatetime时间 from String "Mon Aug 20 13:28:07 +0000 2018": Text 'Mon Aug 20 13:28:07 +0000 2018' could not be parsed at index 0 错误。

    我查过StackOverflow上的类似问题, 我的 "EEE MMM dd HH:mm:ss Z yyyy" 格式看起来正确。

    我做错了?

    解决了的

    问题出在区域设置中。在添加了准确的区域设置测试之后,测试开始通过。

    对于 jackson_parsesDateTime

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "EEE MMM dd HH:mm:ss Z yyyy", locale = "en")
    @JsonProperty("created_at") ZonedDateTime created_at,
    

    对于 ztd_parse 测试

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   Michael Gantman    6 年前

    尝试在属性上添加此批注

    @JsonFormat(shape= JsonFormat.Shape.STRING, pattern="EEE MMM dd HH:mm:ss Z yyyy")
    @JsonProperty("created_at") 
    ZonedDateTime created_at;
    
        2
  •  1
  •   xingbin    6 年前

    似乎你 Locale 不匹配,请尝试使用 Locale.ENGLISH :

    SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
    

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);