- - PR -
DateTime型をエポック値に変換してから戻す際の誤差について
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2008-12-23 06:41
いつもお世話になっております。
みやぼんです。 VisualStudio2008(.NET3.5)で開発しております。 DateTime型⇔エポック値の変換ができるような関数を作成しましたが 1年1月1日のみ時刻部分が09:00と返ってきてしまうことに 疑問を覚えましたので投稿させて頂きました。 どなたかご存知の方がおられましたら、ご教示頂けませんでしょうか? 【ソースコード】 private void button1_Click(object sender, EventArgs e) { DateTime abc = new DateTime(1, 1, 1); long cde = toEpochTime(abc); DateTime efg = fromEpochTime(cde); this.textBox1.Text = efg.ToString(); //↑ここで表示される値が0001/01/01 9:00:00になります。 //↑0001年01月02日の場合は、0001/01/02 0:00:00になります。 } private static long toEpochTime(DateTime dt) { long epo = (dt.ToUniversalTime().Ticks - 621355968000000000) / 10000; return epo; } private static DateTime fromEpochTime(long epo) { DateTime dt = new DateTime(epo * 10000 + 621355968000000000); return dt.ToLocalTime(); } | ||||
|
投稿日時: 2008-12-23 07:29
universal に変換しているから。
| ||||
|
投稿日時: 2008-12-23 08:34
いつもお世話になっております。
みやぼんです。 Jittaさん、ご回答ありがとうございます。 下記のようにすれば、1年1月1日について誤差がなくなりました。 private static long toEpochTime(DateTime dt) { long epo = (dt.ToUniversalTime().Ticks - 621355968000000000) / 10000; return epo; } private static DateTime fromEpochTime(long epo) { DateTime dt = new DateTime(epo * 10000 + 621355968000000000); return dt.ToUniversalTime(); } 説明不足で申し訳ございませんが、 私が聞きたかったのは、最初のコードで DateTime abc = new DateTime(1, 1, 1); とすると 結果値が0001/01/01 9:00:00となり DateTime abc = new DateTime(1, 1, 2); とすると 結果値が0001/01/02 0:00:00 となる。 1月1日と1月2日でなぜ9時間ずれるのかということです。 同じuniversal変換なのになぜ、差異が出てしまうのかを疑問視しております。 | ||||
|
投稿日時: 2008-12-23 11:27
西暦1年1月1日 00:00:00 JST がサポート範囲外だからでしょう。
DateTimeの最小値は西暦1年1月1日 00:00:00 UTC (= 09:00:00 JST) です。 | ||||
|
投稿日時: 2008-12-23 11:56
スフレさんの通りです。
西暦1年1月1日 00:00:00 JST を UTCに変換(ToUniversalTime)したところで 西暦-1年12月31日 15:00:00 UTC になるんですね。これは範囲外なので 西暦1年1月1日 00:00:00 UTC に修正されて(OutOfRangeException が発生していたら気がつけた?)、これを JST に変換(dt.ToLocalTime)しているので、9時間の誤差がでます。なので、正確には 西暦1年1月1日 00:00:00 JST 〜 西暦1年1月1日 09:00:00 JST が、西暦1年1月1日 09:00:00 JST に復元されてしまう。 という現象だったはずです。 | ||||
|
投稿日時: 2008-12-23 16:55
スフレさん、Jittaさん
ご回答、誠にありがとうございます。 >西暦1年1月1日 00:00:00 JST がサポート範囲外だからでしょう。 まったく知りませんでした。。 >OutOfRangeException が発生していたら気がつけた? はい、調査のきっかけになっていたと思います。 本当にご回答ありがとうございます! | ||||
|
投稿日時: 2008-12-23 17:46
ん?解決した?本当に? long epo = (dt.ToUniversalTime().Ticks - 621355968000000000) / 10000; ローカル時間からユニバーサル時間を出して変換。 DateTime dt = new DateTime(epo * 10000 + 621355968000000000).ToUniversalTime(); ユニバーサル時間のエポック値をローカル時間として扱って DateTime を構築。それをユニバーサル時間に変換。 合計で、18時間の誤差が出ません? 本当は、最初のであっていて、西暦1年1月1日 00:00:00 JST 〜 西暦1年1月1日 09:00:00 JST の範囲については、「範囲外の例外」としなければならないのでは? | ||||
|
投稿日時: 2008-12-24 23:57
ご返信が遅くなりまして、申し訳ございません。
解決しました。 >本当は、最初のであっていて その通りです。 最初の処理で且つ、西暦1年1月1日 00:00:00 JST〜西暦1年1月1日 09:00:00 JSTは 誤差が出ることで納得頂きました。 >DateTimeの最小値は西暦1年1月1日 00:00:00 UTC (= 09:00:00 JST) が決め手になりました。 ありがとうございます! |