如何反映杰克逊在几秒钟内的时间戳?

时间:2013-12-17 13:39:17

标签: java json timestamp jackson unix-timestamp

我有一些JSON在几秒钟内有时间戳(即Unix时间戳):

{"foo":"bar","timestamp":1386280997}

要求杰克逊将其反序列化为具有时间戳的DateTime字段的对象,结果为1970-01-17T01:11:25.983Z,这是纪元后不久的一段时间,因为杰克逊假设它在毫秒。除了撕掉JSON并添加一些零之外,我怎样才能让杰克逊理解时间戳?

4 个答案:

答案 0 :(得分:25)

我编写了一个自定义deserializer来处理时间戳(以秒为单位)(Groovy语法)。

class UnixTimestampDeserializer extends JsonDeserializer<DateTime> {
    Logger logger = LoggerFactory.getLogger(UnixTimestampDeserializer.class)

    @Override
    DateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        String timestamp = jp.getText().trim()

        try {
            return new DateTime(Long.valueOf(timestamp + '000'))
        } catch (NumberFormatException e) {
            logger.warn('Unable to deserialize timestamp: ' + timestamp, e)
            return null
        }
    }
}

然后我注释了我的POGO将其用于时间戳:

class TimestampThing {
    @JsonDeserialize(using = UnixTimestampDeserializer.class)
    DateTime timestamp

    @JsonCreator
    public TimestampThing(@JsonProperty('timestamp') DateTime timestamp) {
        this.timestamp = timestamp
    }
}

答案 1 :(得分:14)

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="s")
public Date timestamp;

修改:vivek-kothari建议

@JsonFormat(shape=JsonFormat.Shape.NUMBER, pattern="s")
public Timestamp timestamp;

答案 2 :(得分:8)

与@ DrewStephens的方法非常类似,它使用Java SE TimeUnit API(在JDK1.5中引入)而不是普通的字符串连接,因此(可以说)更清洁,更具表现力:

public class UnixTimestampDeserializer extends JsonDeserializer<Date> {

    @Override
    public Date deserialize(JsonParser parser, DeserializationContext context) 
            throws IOException, JsonProcessingException {
        String unixTimestamp = parser.getText().trim();
        return new Date(TimeUnit.SECONDS.toMillis(Long.valueOf(unixTimestamp)));
    }
}

在受影响的UnixTimestampDeserializer字段中指定自定义反序列化程序(Date):

@JsonDeserialize(using = UnixTimestampDeserializer.class)
private Date updatedAt;

答案 3 :(得分:1)

除了我的ZonedDateTime对象变成了unix-timestamps(秒)而且我需要毫秒(在浏览器中初始化JS Date对象)之外,我遇到了这个确切的问题。

实现自定义序列化器/反序列化器对于应该非常简单的操作来说似乎工作太多,所以我在其他地方查看,发现可以为所需的结果配置对象映射器。

因为我的应用程序已经覆盖了Jersey提供的默认ObjectMapper,所以我只需要禁用SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS

这是我的代码

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.min.js"></script>
<script src="Scripts/bootstrap.min.js"></script>
<script
    src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.7.14/js/bootstrap-datetimepicker.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-ui-multidatespicker@1.6.6/jquery-ui.multidatespicker.min.js"></script>

<link href="App_Themes/NM_Themes/CSS/jquery-ui.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.7.14/css/bootstrap-datetimepicker.min.css" />

<td class='input-group date'>
    <input type='text' class="form-control" style="width: 218px; height: 25px" id='txtmulDos' />
</td>

<script>
    $(function () {
        $('#txtPtDOB').datetimepicker();
    });
</script>

就是这样