与Jackson一起仅以毫秒为单位对LocalDateTime进行序列化

时间:2019-02-22 14:21:37

标签: java jackson java-time jsr310

我想将LocalDateTime序列化为文本格式,而只显示毫秒。我尝试了以下示例:

final ObjectMapper mapper = new ObjectMapper();

mapper.registerModule(new Jdk8Module());
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);

final LocalDateTime t = LocalDateTime.of(2014, 3, 30, 12, 30, 23, 123456789);

System.out.println(mapper.writeValueAsString(t));

这将输出:

"2014-03-30T12:30:23.123456789"

因此,尽管未按照mapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)进行显示,但精度仍以纳秒为单位。

我期望:

"2014-03-30T12:30:23.123"

这是为什么?我该如何解决?

2 个答案:

答案 0 :(得分:1)

由于您禁用了WRITE_DATES_AS_TIMESTAMPS,因此启用或禁用WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS不会执行任何操作,因为localDateTime不再在时间戳表示中。

如果启用WRITE_DATES_AS_TIMESTAMPS,然后禁用WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS,您将获得所需的结果,但格式却是另一种格式([2014,3,30,12,30,23,123]),因此也不可取。

因此,基本上只有两个选项可以实现预期的结果:

  1. 最简单的方法-使用此方法: System.out.println(mapper.writeValueAsString(t.truncatedTo(ChronoUnit.MILLIS)));

    (请记住,您可以安全地删除mapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);,因为在这种情况下它不会执行任何操作。)

  2. 更复杂的方式(不缩短时间):

    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(new LocalDateTimeSerializer(dateTimeFormatter));
    
    final ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(simpleModule);
    
    final LocalDateTime t = LocalDateTime.of(2014, 3, 30, 12, 30, 23, 123456789);
    
    System.out.println(mapper.writeValueAsString(t));
    

    (在这种情况下,您甚至不需要使用JavaTimeModule)。

答案 1 :(得分:0)

我用这个方法解决:

ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule module = new JavaTimeModule();
module.addSerializer(Instant.class, new InstantSerializerWithMilliSecondPrecision());
objectMapper.registerModule(module);

对于InstantSerializerWithMilliSecondPrecision,我使用了以下方法:

public class InstantSerializerWithMilliSecondPrecision extends InstantSerializer {

    public InstantSerializerWithMilliSecondPrecision() {
        super(InstantSerializer.INSTANCE, false, new DateTimeFormatterBuilder().appendInstant(3).toFormatter());
    }

现在,即时序列化始终包含毫秒。

您可以在appendInstant参数中控制小数位数。对于appendInstant(3),我们具有: 2019-09-27T02:59:59.000Z