2

日付/時刻のペアのバイナリ シリアル化を実行する最良の方法は何でしょうか?

これまでの私の最善の推測は、POSIX の time() および mktime() 関数によって返されたエポックからの秒数を格納し、取得時に localtime() を使用して「人間が読める」構造に戻すことです。

タイムスタンプは、さまざまなタイムゾーンのコンピューターによって保存および取得されることに注意してください。

4

4 に答える 4

4

これは、正確にどのデータに興味があるかによって異なります。

  • 1 秒未満の精度が必要ですか? time_tある種の浮動小数点型 (独自の問題を引き起こす可能性がある) を使用しない限り、明らかに、POSIXは一般にそれを提供しません。他の言語やライブラリの時刻形式 (JavaScript や Java など) は、これに対処するために、固定エポックからの秒数ではなく、固定日付からのミリ秒数を使用します。
  • タイム ゾーン間でタイムスタンプを保存および取得する場合は、エポック (POSIXtime_tJavaScript Dataなど) に対して相対的に定義された形式を使用する方が、ローカル時間 + タイム ゾーンを保存するよりもおそらく優れています。
  • 元のタイム ゾーンを知る必要がある場合は、それも保存する必要があります。
  • 2038 年問題のため、POSIXtime_tのようなものを使用する場合は、32 ビット数ではなく 64 ビット数として保存する必要があります。(64 ビットの数値として格納する場合でも、C ランタイムmktimelocaltime実装が 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 年が問題になる前にライブラリが更新されることが期待されます。

于 2012-08-23T16:34:27.417 に答える
1

タイムスタンプは、さまざまなタイムゾーンのコンピューターによって保存および取得されることに注意してください。

また、そのタイムゾーンも保存する必要がありますか? 保存されたローカルの日付と時刻に関心がありますか、それとも単に瞬間に関心がありますか?

基本的に、あなたにとって重要な情報を見つけ出し、それを保存するようにしてください。

于 2012-08-23T16:23:42.780 に答える
0

あなたは自分自身に答えました。現地の人間の状況(夏時間、タイムゾーン、24時間など)に応じて、オンデマンドで人間が読める形式に変換される、コンピューターが理解できる時間値が最適です。収納も小さいです。

于 2012-08-23T16:29:37.037 に答える
0

バイナリ型とどのようにやり取りするかによって異なります。常に POSIX 関数を使用している場合は、time_t 値で問題ありません。Windows では、日付を取得するためにフォーマットに変換する必要があります。もちろん、常にバイナリ値を UTC として保存し、この元の値にオフセットを適用しないでください。

もう 1 つの方法 (最速ではありません) は、文字列を格納し、関数ライブラリに関連付けないことです。もちろん、バイナリ値 1345739726 が POSIX 呼び出しを使用して作成されたことが確実にわかっている場合は、その値を Windows システムに移動すれば変換できます。文字列形式は、どの時点が表現されているかについての疑問を取り除きます。string sTime = "年:月:月日:週日:時:分:秒:夏時間:GMTOffset"

于 2012-08-23T16:40:48.770 に答える