Java 使用协议缓冲区序列化日期
因此,经过一些搜索,建议使用Java 使用协议缓冲区序列化日期,java,protocol-buffers,Java,Protocol Buffers,因此,经过一些搜索,建议使用int64epoch 这一切都很好,但当与我的模型交互时,我想与实际的LocalDate对象交互,那么处理这个问题的策略是什么呢 我能想到的两种策略是: 将反序列化的模型转换为另一个不同的模型。这是创建一个额外的对象,我希望避免这种情况 编辑生成的模型。我找不到这方面的任何文档,所以这可能相当危险 这里的常见做法是什么?您不应该编辑生成的代码。在许多原因中,这是一个坏主意,您编辑的代码可能无法与Protobuf库的未来版本一起工作 一般来说,从int64转换为某种
int64
epoch
这一切都很好,但当与我的模型交互时,我想与实际的LocalDate
对象交互,那么处理这个问题的策略是什么呢
我能想到的两种策略是:
- 将反序列化的模型转换为另一个不同的模型。这是创建一个额外的对象,我希望避免这种情况
- 编辑生成的模型。我找不到这方面的任何文档,所以这可能相当危险
这里的常见做法是什么?您不应该编辑生成的代码。在许多原因中,这是一个坏主意,您编辑的代码可能无法与Protobuf库的未来版本一起工作 一般来说,从
int64
转换为某种Date
对象比较便宜。我建议将数据保留为int64
格式,只在需要时构建LocalDate
对象
也就是说,维护一个单独的手写模型,并且只在解析/序列化时使用Protobuf类也是一种常见的做法。我为所有日期/时间创建了一个通用解决方案:
message Timestamp {
int64 seconds = 1;
int32 nanos = 2;
}
使用以下转换器:
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();
}
不需要创建自己的时间戳版本 您只需使用
google.protobuf.Timestamp
():
这是创建Date
对象的标准(proto)方法
使用新的Java8时间API,很容易将即时
转换为google.Timestamp
LocalDate date = ...;
final Instant instant = java.sql.Timestamp.valueOf(date.atStartOfDay()).toInstant();
Timestamp t = Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).build();
请注意,Google protobuf lib包含时间戳的助手:
编辑生成的代码是个坏主意。这使得维护变得困难。多年以后,当你离开的时候,有人会因为你这样做而诅咒你。那么创建另一个模型的常见做法是什么呢?根据我的经验,是的。我没有考虑编辑类定义本身,只是在它生成的类中添加一个接口,该接口上有一个默认方法来进行转换。
LocalDate date = ...;
final Instant instant = java.sql.Timestamp.valueOf(date.atStartOfDay()).toInstant();
Timestamp t = Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).build();