時刻からエポック秒(UNIX時間、シリアル値)を求める式。

何故か、コンピュータの世界では、1970年1月1日午前0時0分0秒からの秒数で時刻を扱うことが標準になっています。
1970年以前に生まれた人の誕生日はどうやって扱うのかしらん?…なんて思ったりするのですが、それはさておき、MQL4 でも、TimeCurrent() や、TimeLocal() で得られる値は、1970/01/01 から経過した秒数です。


秒数そのままでは扱うのが面倒なので、TimeSeconds()や、TimeMinutes() のような時刻取得関数や、TimeToStr() のような日付時刻変換を使うことが多いと思いますが、逆に、日付時刻から秒数を求めたいことがあります。他のプログラミング言語では簡単に変換できるのに、MQL4 ではそれらしいコードがすぐに見つからなかったので以下の関数を用意しました。

datetime GetEpoch(int sec,int min,int hour,int day,int month,int year){
   int year_day[]={0,0,31,59,90,120,151,181,212,243,273,304,334};
   datetime leap_day,epoch_day;

   leap_day = (year - year % 4) / 4 - (year - year % 100) / 100 + (year - year % 400) / 400 - 477;
   epoch_day = 365 * (year - 1970) + leap_day;
   epoch_day = epoch_day + year_day[month] + day - 1;
   if( (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) && (month <= 2))
   epoch_day = epoch_day - 1;
   return( ((epoch_day * 24 + hour) * 60 + min) * 60 + sec);
}


一応、1989〜2010の間の1000データで検算したので正しく動作すると思います。
(というか、他の言語で同様の計算をしているのを移植しただけなので正しいはずです。笑。これも、きっと junaさんか、誰かの役に立つでしょう…




…と書いてる途中に、朝倉さんから StrToTime() を使う方が簡単よ っと教わりました。

datetime GetEpoch(int sec,int min,int hour,int day,int month,int year){
   return(StrToTime(year+"."+month+"."+day+" "+hour+":"+min)+sec );
}

年月日時分を文字列に繋いで StrToTime() で変換後、秒を足しています。


何故、秒だけ別扱いにしているのかというと、

//数字を詰めて並べた場合
Alert(StrToTime("2010.3.2 3:0:15"));// 結果は1267498800 で ×

//ゼロ埋め有り
Alert(StrToTime("2010.03.02 03:00:15"));// 結果は1267498815 で ○

//分の部分だけゼロ埋め有り
Alert(StrToTime("2010.3.2 3:00:15"));// 結果は1267498815 で ○

StrToTime で秒まで変換したい場合、分の部分だけは2桁で書かないと正しく動かないバグ?がある為です。
トレードで扱う時刻は秒を無視出来る事が多いので、気にしなくて良いと思いますが、秒単位のデータを扱う時に知らないと嵌まるのでメモとして遺しておきます。