【问题标题】:MetaTrader 4 / MQL4 Time is off by -5 hours but only when using epoc timeMetaTrader 4 / MQL4 时间关闭 -5 小时,但仅在使用纪元时间时
【发布时间】:2020-05-07 13:14:06
【问题描述】:

我正在使用在 Ubuntu 16.04 的 WINE 中运行的 MetaTrader4。我有一个简单的内联函数,可以使用这一行将时间和各种其他信息保存到文件中:

FileWrite(data_filehandle, "sys_time:" + (string)TimeLocal() + "." + StringFormat("%06lu", usec_instance) + ", sym:" + (string)Symbol() + ", tick_time:" + (string)last_tick.time + ", ask:" + (string)last_tick.ask + ", bid:" + (string)last_tick.bid);

使用指令:

#property strict

将导致它以日期时间格式输出时间。 删除该指令将导致它以 epoc 格式输出时间。

当它使用日期时间格式(通过使用'#property strict')时,时间是正确的。

它输出:

sys_time:2020.01.21 07:38:02.994394, sym:EURUSD, tick_time:2020.01.21 14:38:03, ask:1.1104, bid:1.1103

这与我的系统时间正确匹配。

现在如果我删除“#property strict”以切换到 epoc 时间

它输出:

sys_time:1579592538.630395, sym:EURUSD, tick_time:1579617738, ask:1.1105, bid:1.11041

我的当地时间是:

$ date '+%s'
1579610544

$ date '+%Z %z'
EST -0500

我的时间:1579610544 - MT4 LocalTime:1579592538 = 18006 秒(比我晚 5 小时 6 秒)

您知道是什么原因造成的吗? 如果是 +5 小时,我可能会稍微不那么困惑,因为那是格林威治标准时间。 但它是 -5 小时,这是夏威夷。 另外...为什么一种格式的时间正确,而另一种格式的时间不正确?



其他信息

我使用额外的 MQL4 函数运行了一些测试。我让他们不断地将结果输出到我的文本文件中。然后我迅速将一个 BASH 脚本拼凑起来以检查结果。我发现了以下内容:

在 MT4 中使用此代码

FileWrite(data_filehandle, "TimeDaylightSavings(): " + (string)TimeDaylightSavings());
FileWrite(data_filehandle,"TimeLocal(): "+(string)TimeLocal());
FileWrite(data_filehandle,"TimeGMTOffset(): "+(string)TimeGMTOffset());
FileWrite(data_filehandle,"TimeGMT(): "+(string)TimeGMT()+"\n\n");

将此输出提供给我的文本文件(大约每秒一个新记录):

TimeDaylightSavings(): 0
TimeLocal(): 1579601184
TimeGMTOffset(): 18000
TimeGMT(): 1579619184

我创建了这个 BASH 脚本来实时扫描和检查结果:

#!/bin/bash

IFS=$'\n'$'\b';

while true
do
        my_time=$(date);
        my_epoc=$(date '+%s');
        my_record="$( cat EURUSD_price_data.txt| dos2unix | tail -5 )";


        mt4_time_local=$( echo "$my_record" | grep -w 'TimeLocal' );
        echo "Reading line: $mt4_time_local";
        mt4_time_local=$(echo $mt4_time_local | awk '{print $2}' );

        echo "My time: $my_time  -- My epoc: $my_epoc -- MT4_TimeLocal epoc: $mt4_time_local -- Difference: $(( $my_epoc - $mt4_time_local ))";

        mt4_time_GMT=$( echo "$my_record" | grep -w 'TimeGMT' );
        echo "Reading line: $mt4_time_GMT";
        mt4_time_GMT=$(echo $mt4_time_GMT | awk '{print $2}' );
        echo "My time: $my_time  -- My epoc: $my_epoc -- MT4_TimeGMT epoc: $mt4_time_GMT -- Difference: $(( $my_epoc - $mt4_time_GMT ))";


        echo "";
        sleep 1;
done

得到了这个结果:

Reading line: TimeLocal(): 1579601184
My time: Tue Jan 21 10:06:25 EST 2020  -- My epoc: 1579619185 -- MT4_TimeLocal epoc: 1579601184 -- Difference: 18001
Reading line: TimeGMT(): 1579619184
My time: Tue Jan 21 10:06:25 EST 2020  -- My epoc: 1579619185 -- MT4_TimeGMT epoc: 1579619184 -- Difference: 1

现在,如果我添加“#property strict”以切换回日期时间格式,我会得到:

TimeDaylightSavings(): 0
TimeLocal(): 2020.01.21 10:23:56
TimeGMTOffset(): 18000
TimeGMT(): 2020.01.21 15:23:56

我的系统时间:

$ date
Tue Jan 21 10:23:57 EST 2020



结论

由于某种原因,获取 epoc 时间 TimeLocal() 给出了错误的时间(夏威夷时间出于某种原因),但令人惊讶的是 TimeGMT() 给出了正确的时间,即使我在 EST 时区。

使用完全相同的代码和设置,当获取日期时间格式的时间时(使用 '#property strict' 指令),情况正好相反。 TimeLocal() 给出了正确的时间,而 TimeGMT() 给出了错误的时间(但至少它给出了正确的 GMT 时间)

这是 MT4 中的错误,还是我还没有完全理解的幕后发生的事情?

【问题讨论】:

    标签: time epoch mql4 metatrader4


    【解决方案1】:

    你知道是什么原因造成的吗?

    #property strict 是一个编译器阶段的终止开关,它改变了许多细节,MQL4 的语法正确,组合将如何在 { "old" | "" }-时尚

    (不阅读这部分文档每次 MT4 IDE 更新可能而且会让你大吃一惊,所以最好重新- 每次更新后都要阅读)

    “旧”-MQL4 使用 int32 用于 datetime 内部存储,“新”-MQL4.56789... 使用int64,所以任何翻车都更远。

    FileWrite( data_filehandle, "sys_time:"
                              + (string)TimeLocal()                    // localhost-dependent
                              + "."
                              + StringFormat( "%06lu", usec_instance )
                              + ", sym:"
                              + (string)Symbol()
                              + ", tick_time:"
                              + (string)last_tick.time                 // Fx-QUOTE-dependent
                              + ", ask:"
                              + (string)last_tick.ask
                              + ", bid:"
                              + (string)last_tick.bid
                              );
    

    有关其他内置选项,请参阅 TimeGMT()TimeGMTOffset()

    【讨论】:

      【解决方案2】:

      经过大量阅读、思考和测试,我找到了答案(虽然我不知道他们这样做时的想法)。

      问题就在这里:

      TimeDaylightSavings(): 0
      TimeLocal(): 1579601184  <-- should be the same as TimeGMT(). Epoc does not respect timezone
      TimeGMTOffset(): 18000
      TimeGMT(): 1579619184
      

      Unix epoc 时间基于 1970 年 1 月 1 日 00:00 UTC 发生的事件。 它不尊重时区。地球上的每个人在任何时候都应该是一样的。

      你也可以从原来的问题中看出,任何时候我使用:

      date '+%s'
      

      命令我的系统给我一个正确的 Unix epoc,它与 MT4 的 TimeGMT() 的输出相匹配。所以问题不是我的系统。

      但是,在上面我们可以看到 TimeLocal() 并没有按照应有的方式处理 epoc。它正在调整 unix epoc 以补偿我的时区。当它以日期时间格式显示时,这种行为可能是它完成生成正确时间的方式。问题是当它被要求以 epoc 格式生成时间时,它仍在进行时区转换,这违反了 Unix epoc 时间的真正含义。

      因此,解决方案(据我所知)是在我想要一个正确的 Unix epoc 时简单地使用 TimeGMT() 。在某些情况下我必须特别避免使用 TimeLocal() 似乎很疯狂......但我想这就是它的方式吗?

      【讨论】:

        猜你喜欢
        • 2013-04-24
        • 2018-05-28
        • 2013-07-21
        • 2018-12-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-22
        • 2012-01-30
        • 2017-09-30
        相关资源
        最近更新 更多