5

我正在使用 Jackson JSON 库从我的 Android 应用程序中的服务器解析 JSON。但是,每当我收到 DateTime 时,解析请求都会失败,因为它是这种格式:

"/Date(1277931782420)/"

我知道我应该这样做:

ObjectMapper om = new ObjectMapper();
om.setDateFormat(new TicksSinceFormat());

但我不知道我是否可以使用 SimpleDateFormat(以及我将使用什么格式字符串?)或者我需要编写自己的 DateFormat 解析器。因此,如果有人可以帮助提供代码示例,我将不胜感激。

编辑: 好的,请参阅我的完整代码答案。

4

2 回答 2

5

事实证明这比我预期的要难:

public class TicksSinceFormat extends DateFormat {
    @Override
    public StringBuffer format(Date date, StringBuffer buffer, FieldPosition field) {
        long millis = date.getTime();

        return new StringBuffer("/Date(" + millis + ")/");
    }

    @Override
    public Date parse(String string, ParsePosition position) {
        int start = string.indexOf("(") + 1;
        int end = string.indexOf(")");

        String ms = string.substring(start, end);
        Date date = new Date(Long.parseLong(ms));

        position.setIndex(string.length() - 1); // MUST SET THIS
        return date;
    }

    @Override
    public Object clone() {
        return new TicksSinceFormat(); // MUST SET THIS
    }
}

使用类非常简单,只需执行以下操作:

ObjectMapper om = new ObjectMapper();
om.setDateFormat(new TicksSinceFormat())

我认为这可以更好地编码 + 当涉及到 .NET Ticks VS Java 滴答时,我需要处理差异 - 但现在就可以了。如果有人对提到的问题有更好的解决方案或更深入的了解,我稍后会处理 - 请随时发布,如果更好,我会将您的答案标记为正确的答案。

编辑:正如我在这个问题和答案中解释的那样,我已经切换到服务器上的 ServiceStack.Text 库,它返回不同的 ISO8601 格式。对于那种格式,我使用了稍微不同的解析(因为杰克逊在解析包含毫秒的 ISO8601 时遇到了麻烦)。当然,与我发布的其他代码一样 - 如果您有更好的版本,请告诉我(请发布代码/编辑这篇文章,而不是诉诸哲学修辞来说明应该如何完成):

@SuppressLint("SimpleDateFormat")
public class JacksonSimpleDateFormat extends SimpleDateFormat {
    public JacksonSimpleDateFormat() {
        if (mParser == null) {
            mParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
            mParser.setTimeZone(TimeZone.getTimeZone("UTC"));
        }
    }

    @Override
    public StringBuffer format(Date date, StringBuffer buffer, FieldPosition field) {
        return mParser.format(date, buffer, field);
    }

    private static SimpleDateFormat mParser;
    @Override
    public Date parse(String string, ParsePosition position) {
        String str = string.split("\\.")[0];

        Date date = null;
        try {
            date = mParser.parse(str);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        position.setIndex(string.length() - 1);
        return date;
    }

    @Override
    public Object clone() {
        return new JacksonSimpleDateFormat();
    }
}
于 2013-02-16T05:32:43.067 回答
3

我可能错了,因为我对 Android 开发还没有深入了解,但是您提供的格式:

"/Date(1277931782420)/"

似乎是 Unix 纪元时间。

如果是这种情况,您将不想/不需要使用SimpleDateFormat. 相反,尝试从它创建一个Long并传递给Date构造函数,考虑它是基于秒还是毫秒的纪元值。

这是一个 StackOverflow 帖子,提供了这样做的代码:https ://stackoverflow.com/a/535017/463196

于 2013-02-16T04:41:55.777 回答