日付/時刻のペアのバイナリ シリアル化を実行する最良の方法は何でしょうか?
これまでの私の最善の推測は、POSIX の time() および mktime() 関数によって返されたエポックからの秒数を格納し、取得時に localtime() を使用して「人間が読める」構造に戻すことです。
タイムスタンプは、さまざまなタイムゾーンのコンピューターによって保存および取得されることに注意してください。
これは、正確にどのデータに興味があるかによって異なります。
time_t
ある種の浮動小数点型 (独自の問題を引き起こす可能性がある) を使用しない限り、明らかに、POSIXは一般にそれを提供しません。他の言語やライブラリの時刻形式 (JavaScript や Java など) は、これに対処するために、固定エポックからの秒数ではなく、固定日付からのミリ秒数を使用します。time_t
やJavaScript Dataなど) に対して相対的に定義された形式を使用する方が、ローカル時間 + タイム ゾーンを保存するよりもおそらく優れています。time_t
のようなものを使用する場合は、32 ビット数ではなく 64 ビット数として保存する必要があります。(64 ビットの数値として格納する場合でも、C ランタイムmktime
とlocaltime
実装が 64 ビットtime_t
値をサポートしていない可能性があることに注意してください。)特に 2038 年問題に関して: それを処理することが保証されている POSIX API を知りません。それを処理することが保証されているライブラリが必要な場合は、boost::date_time
. Project 2038 FAQには、C ランタイムの 2038 サポートのテストに関する情報が含まれています。そのページによると、最新の 64 ビット Linux システムは影響を受けないはずです。最近のバージョンの Visual C++ も影響を受けません。(こちら を参照してください。) ライブラリが現在 64 ビットtime_t
値をサポートしていない場合でも、64 ビット int をシリアル化し、それを 32 ビットにキャストして処理することができます。そうすれば、ディスク上のデータ構造は少なくとも準拠し、2038 年が問題になる前にライブラリが更新されることが期待されます。
タイムスタンプは、さまざまなタイムゾーンのコンピューターによって保存および取得されることに注意してください。
また、そのタイムゾーンも保存する必要がありますか? 保存されたローカルの日付と時刻に関心がありますか、それとも単に瞬間に関心がありますか?
基本的に、あなたにとって重要な情報を見つけ出し、それを保存するようにしてください。
あなたは自分自身に答えました。現地の人間の状況(夏時間、タイムゾーン、24時間など)に応じて、オンデマンドで人間が読める形式に変換される、コンピューターが理解できる時間値が最適です。収納も小さいです。
バイナリ型とどのようにやり取りするかによって異なります。常に POSIX 関数を使用している場合は、time_t 値で問題ありません。Windows では、日付を取得するためにフォーマットに変換する必要があります。もちろん、常にバイナリ値を UTC として保存し、この元の値にオフセットを適用しないでください。
もう 1 つの方法 (最速ではありません) は、文字列を格納し、関数ライブラリに関連付けないことです。もちろん、バイナリ値 1345739726 が POSIX 呼び出しを使用して作成されたことが確実にわかっている場合は、その値を Windows システムに移動すれば変換できます。文字列形式は、どの時点が表現されているかについての疑問を取り除きます。string sTime = "年:月:月日:週日:時:分:秒:夏時間:GMTOffset"