[MQL4] datetime を long にキャストすると 1970/1/1 からの秒になる
参考
Datetime Type - Integer Types - Data Types - Language Basics - MQL4 Reference
公式ドキュメントによると、datetime
は 1970/1/1 からの秒を格納する 8 bytes の型だそうです。
これは long
と同じサイズで、相互変換が可能です。
どちらを使っていても動作上問題はないのですが、以下のような特徴があるので使い分けると良いでしょう。
datetime
日付文字列との相互変換が容易。実際の日付を表す場合に使用。long
純粋な秒を表す場合に使用。
キャストしてみる
1 2 3 4 5 6 | datetime date1 = D '2008.01.01' ; long date1_sec = ( long ) date1; printf ( "%lld" , date1_sec); // 結果 // 1199145600 |
この値、UNIX Time として知られている1もので、Linux 等では簡単に調べられます。
$ date -u --date='2008/01/01' +%s 1199145600 |
一致しました。
datetime にはタイムゾーンという概念がないので、どのタイムゾーンを表しているのかは別途考えなければなりません。
差分計算の結果は、long で受けた方が良い
上記定義より datetime と datetime の差分計算結果も datetime に格納することが出来ます。
1 2 3 4 5 6 7 | datetime date1 = D '2008.01.01' ; datetime date2 = D '2008.01.02' ; datetime date3 = date2 - date1; Print ( TimeToString (date3, TIME_DATE)); // 結果 // 1970.01.02 |
差分結果が 1970.01.02
という意味のないものになってしまいました。
date3
に格納されている値は 1970/1/1 からの秒なので、使用時に long
にキャストすれば実行上問題はありません。
しかし、せっかく相互変換が可能な型なのですから、実体を表した使い方をした方が良いだろうと思います。
つまり、以下のように差分は long
で受ける方が自然です。
1 2 3 4 5 6 7 | datetime date1 = D '2008.01.01' ; datetime date2 = D '2008.01.02' ; long time_delta = date2 - date1; printf ( "%lld" , time_delta); // 結果 // 86400 (= 60 * 60 * 24) |
なお、差分が4バイト2を超えるような計算は、特殊なケースに限られるはずです。
つまり、int
で受けても実害はないと思われますが、メモリに余裕がある系ではそういった最適化はしない方が無難です。
最近の PC でメモリが枯渇することはあまり無いですよね?
差分が負になっても datetime で扱えるが、やはり long で受けた方が良い
以下のように、負の値を datetime
に入れることも可能ですが、TimeToString() は正しく動作しません。
やはり、long
で受けておく方が無難でしょう。
1 2 3 4 5 6 7 | datetime date1 = D '2008.01.01' ; datetime date2 = D '2008.01.02' ; datetime date3 = date1 - date2; printf ( "%s : %lld" , TimeToString (date3, TIME_DATE), date3); // 結果 // : -86400 |
最大値は 8bytes ではない
公式ドキュメントによれば、datetime
の最大値は 3000/12/31
(≒ 0x7933FFF7F
3)だそうです。
実際は 5bytes 程度ということですね。
ところで、正確な時間まで調べてみたところ、本当の最大値は 3001/01/01 07:59:59
になりました。
1 2 3 4 5 6 7 8 9 | datetime date1 = 0x0793406FFF; printf ( "%lld %s" , date1, TimeToString (date1, TIME_DATE|TIME_MINUTES|TIME_SECONDS)); // 結果 // 32535244799 3001.01.01 07:59:59 datetime date2 = 0x0793407000; printf ( "%lld %s" , date2, TimeToString (date2, TIME_DATE|TIME_MINUTES|TIME_SECONDS)); // 結果 // 32535244800 |
環境依存の可能性もありますし、1000年近い未来の数時間など誤差でしかありませんが。