2

使用 MQL4 我在处理datetime.

我想做的是datetime按月或按年排列。

现在我这样做。

datetime myDate;

myDate[0] = D'2010.01.01 00:00';
myDate[1] = D'2010.02.01 00:00';
myDate[2] = D'2010.03.01 00:00';
myDate[3] = D'2010.04.01 00:00';
.
.

但是我想在下面这样做

myDate[0] = D'2010.01.01 00:00';
for (int i = 1;i < 6 ;i+=){
    myDate[i] = myDate[i - 1] + 1year;
}

在月份的情况下,

myDate[0] = D'2010.01.01 00:00';
for (int i = 1; i < 12 ; i++){
    myDate[i] = myDate[i - 1] + 1month
}

问:如何计算加法1month1year

4

5 回答 5

4

使用MqlDateTime,TimeToStructStructToTime结构如下:

MqlDateTime time;
TimeToStruct(TimeCurrent(),time);

time.year++;
time.mon++;
datetime newTime = StructToTime(time);
于 2020-04-30T16:56:12.470 回答
3

MQL4文档声明datetime类型在内部表示为自商定的时间尺度数据 (being 1970-01-01 00:00) 以来的秒数。

这表示(并稍微完善了语法合规性)
代码
可能会读取

oneYear = 60 * 60 * 24 * 365;   // yes, astronomers would kill me
                                // for not solving those seconds,
                                // that sum up until a leap year
                                // consumes 'em on Feb-29th day     :o)

另一种选择
,以便以
datetime
舒适的方式进行操作,寻址
datetime的自然组件是hacky,但值得:StringToTime

string TimeToString( datetime aDatetimeVALUE,
                     int aModeOfDISPLAY = TIME_DATE|TIME_MINUTES
                    )

将包含自 01.01.1970 以来经过的时间(以秒为单位)的值转换为stringof"yyyy.mm.dd hh:mi"格式。

在这里,可以简单地将 +1 添加到此中间格式的正确位置(无需处理 中存在的所有派生和受影响的值struct MqlDateTime,其中day_of_weekday_of_year绝对不是我最喜欢在移动 +1 个月后重新计算的值等.

aCurrentYEAR  = int(  StringSubstr( aDatetimeSTRING, 0, 4 ) );
aCurrentMONTH = int(  StringSubstr( aDatetimeSTRING, 5, 2 ) );
aCurrentDAY   = int(  StringSubstr( aDatetimeSTRING, 8, 2 ) );

aNextYEAR     = aCurrentYEAR  + 1;
aNextMONTH    = aCurrentMONTH + 1;

最后

StringFormat( "%04d.%02d.%02d 00:00", aYearNUMBER, aMonthNUMBER, aDayNUMBER )

将重新组装以调用另一个 MQL4 标准函数:

datetime StringToTime( string aDatetimeSTRING )

该函数将包含时间或日期"yyyy.mm.dd [hh:mi]"格式的字符串转换为datetime类型。

另一种方法可以通过使用完全分解datetime的算法来使用

int aYE  = TimeYear(      aDatetimeVALUE );
int aMO  = TimeMonth(     aDatetimeVALUE );
int aDA  = TimeDay(       aDatetimeVALUE );
int aHO  = TimeHour(      aDatetimeVALUE );
int aMI  = TimeMinute(    aDatetimeVALUE );
int aDoW = TimeDayOfWeek( aDatetimeVALUE );
int aDoY = TimeDayOfYear( aDatetimeVALUE );

datetime aSameTimeNextYEAR = StructToTime( (MqlDateTime) { aYE + 1,
                                                           aMO,
                                                           aDA,
                                                           aHO,
                                                           aMI,
                                                           aDoW,
                                                           aDoY
                                                           }
                                           );
于 2016-11-12T07:47:40.737 回答
0
int month = PeriodSeconds(PERIOD_MONTH);

对于 year - 不确定您是否可以使用一些常量,但看起来 12 个月是可以的,另一种选择是使用MqlDateTime分配 year 然后转换为datetimeusing StructToTime()

更新:月份不是一个好方法,因为每个月都有不同的秒数

于 2016-11-12T15:40:43.627 回答
0

我附上了一个说明循环的脚本。

基本逻辑:

  1. 将 31 天添加到定义的日期时间
  2. 获取新月份,忽略特定日期
  3. 将新日期生成为带有新月份的字符串
  4. 将字符串转换为新的日期时间
  5. 将 31 天添加到这个新的日期时间
  6. 从 2 开始重复

    void OnStart(){

       datetime myDate[6];
       myDate[0] = D'2010.01.01 00:00';
       Print(TimeToStr(myDate[0]));

       datetime dTempDate = myDate[0];
       int iSecondsIn31Days = 24*60*60*31, iTempMonth = 0;

       for(int i=1; i<6; i++){
          iTempMonth = TimeMonth(dTempDate + iSecondsIn31Days); //add 31 days and get the month, we don't care whether the day is the 1st, 2nd, or 3rd, we just want the month
          myDate[i] = dTempDate = StrToTime(TimeYear(myDate[0]) +"." +iTempMonth +"." +TimeDay(myDate[0])); //format the string to datetime
          Print(TimeToStr(myDate[i])); //to verify
       }

    }

在此处输入图像描述

于 2017-04-06T12:15:22.677 回答
0

您需要使用的方法

MqlDateTime , StructToTime ,TimeToStruct

您可以使用这些以更少的步骤完成工作

于 2020-04-24T19:33:00.757 回答