Datums- und Uhrzeittyp zur Verwendung mit Protobuf


74

Ich denke darüber nach, Protokollpuffer für den Datenaustausch zwischen einem Linux- und einem Windows-basierten System zu verwenden.

Was ist das empfohlene Format zum Senden von Datums- / Uhrzeitwerten (Zeitstempel)? Das Feld sollte bei der Serialisierung klein sein.

Antworten:


47

Obwohl Sie nicht sagen, welche Sprachen Sie verwenden oder welche Genauigkeit Sie benötigen, würde ich vorschlagen, Unix-Zeit zu verwenden , die in a codiert ist int64. Es ist in den meisten Sprachen und Plattformen ziemlich einfach zu handhaben (siehe hier für ein Windows-Beispiel), und Protobufs verwendet eine Varint-Codierung , die die Größe klein hält, ohne den darstellbaren Bereich zu stark einzuschränken.


17
verwendet nur 4 Bytes bis 2038 ... kann das nicht übertreffen
— JoelFan

4
Die Unix-Zeit verbraucht nur 4 Bytes, was eine recht effiziente Codierung darstellt. Für Daten nach 2038 sind jedoch mehr als 4 Bytes erforderlich
— JoelFan

3
Die Unix-Zeit wird nicht in Bezug auf die Anzahl der benötigten Bytes angegeben, sondern als die Anzahl der Sekunden seit der Epoche. Traditionell wurde es als 32-Bit-Ganzzahl dargestellt, aber die meisten Betriebssysteme verwenden heute 64-Bit-Ganzzahlen.
— JesperE

10
Mein Punkt ist: Wenn Sie Unix Time in Protobuf verwenden, werden Sie nur 4 Bytes verwenden ... was bedeutet, dass Unix Time gut ist ... das ist alles, was ich sage!
— Nebenbei füge

6
Ist es nicht 5? Varint-Codierung.
— Hounshell

126

TimestampSeit protobuf 3.0 gibt es einen Nachrichtentyp. So erstellen Sie ihn im Modell:

syntax = "proto3";

import "google/protobuf/timestamp.proto";

message MyMessage {
    google.protobuf.Timestamp my_field = 1;
}

timestamp.proto Die Datei enthält Beispiele für die Verwendung von Timestamp, einschließlich Linux- und Windows-Programmen.

Beispiel 1: Zeitstempel von POSIX berechnen time().

Timestamp timestamp;
timestamp.set_seconds(time(NULL));
timestamp.set_nanos(0);

Beispiel 2: Zeitstempel von POSIX berechnen gettimeofday().

struct timeval tv;
gettimeofday(&tv, NULL);

Timestamp timestamp;
timestamp.set_seconds(tv.tv_sec);
timestamp.set_nanos(tv.tv_usec * 1000);

Beispiel 3: Zeitstempel aus Win32 berechnen GetSystemTimeAsFileTime().

FILETIME ft;
GetSystemTimeAsFileTime(&ft);
UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;

// A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
// is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
Timestamp timestamp;
timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));

Was ist mit JavaScript?
— Neurotransmitter

4
Ich bin mir nicht sicher, ob dies eine vollständige Antwort wert ist, aber die Frage fragt nach Zeitstempeln und Datumsangaben. Betrachten Sie also google.type.Date, wenn Sie keine höhere Genauigkeit benötigen.
— Micseydel

1
@micseydel: OP hat nach einem "kleinen" Datentyp gefragt. google.type.Date ist 3 Zoll und hat eine geringere Genauigkeit als das einfache Senden eines int64 mit einem Unix-Zeitstempel. Es gibt nur sehr wenige Fälle, in denen google.type.Date wünschenswert ist, mit Ausnahme der einfachen menschlichen Lesbarkeit. Natürlich kombiniert das Binärformat von Protobuf die 3 Ints so gut es geht, aber im Allgemeinen scheint es nicht ideal zu sein, wenn es auf die Größe ankommt.
— DoomGoober

8

In der neuesten Protobuf-Version (3.0) - Für C # ist Timestamp ein WellKnownType verfügbar. Überprüfen Sie dies

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.