Accurately serializing and deserializing a SysTime in binary format

Steven Schveighoffer schveiguy at gmail.com
Tue Jul 21 12:21:16 UTC 2020


On 7/21/20 7:44 AM, Ecstatic Coder wrote:
> On Tuesday, 21 July 2020 at 11:01:20 UTC, drug wrote:
>> On 7/20/20 10:04 PM, Ecstatic Coder wrote:
>>> I'm currently implementing a small open source backup tool (dub), and 
>>> therefore I need to accurately store the file modification SysTime in 
>>> binary format, so that I can later load this SysTime from the 
>>> snapshot file to compare it with the current file modification SysTime.
>>>
>>> Having unfortunately not understood how to do this from the SysTime 
>>> documentation, in despair, I've tried to directly serialize the 16 
>>> bytes of the SysTime value. This worked fine until I call the 
>>> ".toISOString()" on the deserialized SysTime, which inevitably 
>>> crashes the executable ;)
>>
>> That is probably a bug. I serialize SysTime as long by means msgpack 
>> for exchanging between C++ client and D server and it works pretty nice.
>>
> 
> Ah thanks for telling me :)
> 
> The loaded byte array in the union type was indeed the same as the saved 
> one, so I immediately thought it was crashing because of some hidden 
> pointer for timezone or something which was then pointing to garbage at 
> reloading, causing the crash of the ".toISOString" call.

Not a bug.

8 of those 16 bytes is a pointer to the timezone, which is going to be 
different on different processes.

What you should do I think is serialize the stdTime [1], and set the 
time zone to whatever you want:

long serialize(SysTime st) { return st.stdTime; }
SysTime deserialize(long st) { return SysTime(st, UTC()); }

The stdTime is always stored as UTC to make math a lot easier. The time 
zone is only used for display.

-Steve

[1] https://dlang.org/phobos/std_datetime_systime.html#.SysTime.stdTime


More information about the Digitalmars-d-learn mailing list