使用协议缓冲区序列化日期

Che*_*tah 6 java protocol-buffers

经过一番搜索,有人建议使用一个int64纪元.

这一切都很好,但在与我的模型交互时,我想与实际LocalDate对象进行交互,那么处理这个的策略是什么?

我能想到的两个策略是:

  • 将反序列化模型转换为另一种不同的模型.这是创建一个额外的对象,我希望避免这种情况.
  • 编辑生成的模型.我找不到任何关于此的文档,所以它可能风险很大

这里的常见做法是什么?

Che*_*tah 8

我开始为所有日期/时间创建通用解决方案:

message Timestamp {
    int64 seconds = 1;
    int32 nanos = 2;
}
Run Code Online (Sandbox Code Playgroud)

使用以下转换器:

public static Timestamp fromLocalDate(LocalDate localDate) {
    Instant instant = localDate.atStartOfDay().toInstant(ZoneOffset.UTC);
    return Timestamp.newBuilder()
        .setSeconds(instant.getEpochSecond())
        .setNanos(instant.getNano())
        .build();
}

public static LocalDate toLocalDate(Timestamp timestamp) {
    return LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp.getSeconds(), timestamp.getNanos()), ZoneId.of("UTC"))
        .toLocalDate();
}
Run Code Online (Sandbox Code Playgroud)


db8*_*b80 5

无需创建您自己的 Timestamp 版本。

您可以简单地使用google.protobuf.Timestamp):

import "google/protobuf/timestamp.proto";
message Application {
    google.protobuf.Timestamp date = 1;
}
Run Code Online (Sandbox Code Playgroud)

这是创建Date对象的标准(原型)方式。

使用新的 Java8 时间 API很容易将 an 转换Instant为 agoogle.Timestamp

LocalDate date = ...;
final Instant instant = java.sql.Timestamp.valueOf(date.atStartOfDay()).toInstant();        
Timestamp t = Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).build();
Run Code Online (Sandbox Code Playgroud)

请注意,Google protobuf lib 包含一个帮助程序Timestamp

https://github.com/google/protobuf/blob/master/java/util/src/main/java/com/google/protobuf/util/Timestamps.java