繁体   English   中英

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

[英]Serializing Dates with Protocol Buffers

因此,经过一番搜索,建议使用int64纪元。

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

我能想到的两种策略是:

  • 将反序列化模型转换为另一个不同的模型。 这是创建一个额外的对象,我希望避免这种情况。
  • 编辑生成的模型。 我找不到有关此的任何文档,因此可能非常冒险

这里的常见做法是什么?

我为所有日期/时间创建了一个通用解决方案:

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();
}

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

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

import "google/protobuf/timestamp.proto";
message Application {
    google.protobuf.Timestamp date = 1;
}

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

使用新的 Java8 时间 API 很容易将Instant转换为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 包含Timestamp的帮助程序:

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

您永远不应该编辑生成的代码。 在许多原因中,这是一个坏主意,您编辑的代码可能不适用于 Protobuf 库的未来版本。

通常,从int64转换为某种Date对象很便宜。 我建议将数据保留为int64格式,仅在需要时按需构建LocalDate对象。

也就是说,维护单独的手写模型也是常见的做法,并且仅在解析/序列化时使用 Protobuf 类。

C# 类中生成的属性不是 .NET 日期和时间类型。 这些属性使用Google.Protobuf.WellKnownTypes命名空间中的TimestampDuration类。 这些类提供了在DateTimeOffsetDateTimeTimeSpan进行转换的方法。

   syntax = "proto3"
  
   import "google/protobuf/timestamp.proto";

message Meeting {
    string subject = 1;
    google.protobuf.Timestamp time = 2;
}  

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM