Московское время

Опубликовано в AmiBroker

Как получить локальное московское время?

Если Вы (и Ваш робот) находитесь в Москве, то проблем с часовыми поясами не возникает. Компьютер настроен на московское время, биржа тоже также работает с этим временем, все прекрасно. 

Совсем другое дело, когда Ваше местоположение отличается от Московского. В этом случае время сделок в таблице сделок отличается от того, что вы видите на своих часах. В лог-файле все события помечаются локальным временем, все сообщения от биржи - московским. Путаница.

Дополнительно возникают проблемы, когда необходимо из внешнего источника взять время какого-то события и поставить метку на графике. Если локальное время не совпадает с московским, метка встанет не туда или вообще не отобразится на графике.

Есть 2 способа решения проблемы. Первый способ - простой и неправильный: всегда ставить на компьютере московское время. Минусы способа очевидны. Второй (правильный) - устанавливать локальное время компьютера в соответствии с часовым поясом, в котором Вы реально находитесь и производить пересчет в роботе локального времени к московскому, оно же время биржи.

Как? Вот текст скрипта, выводящего строковые время и дату московского региона в окно трассировки. Всегда будет выведено правильное московское время, где бы Вы не находились, при условии, что часовой пояс на Вашем компьютере установлен верно. 

// Получение поля ветки информации об установленном часовом поясе
// Возвращает смещение в секундах. function TimeZoneOffset()
{ WSHShell = CreateObject("WScript.Shell");
return 60 * WSHShell.RegRead("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation\\Bias");
} // Получение строки, содержащей текущее московское время и дату,
// форматированные в соответствии с системными настройками.
function tzNow()
{
return DateTimeToStr(DateTimeAdd(Now(5),TimeZoneOffset()+14400,in1Second));
}
_TRACE("Moscow time now is " + tzNow());

Все хорошо, да только получается, что при каждом запросе текущего времени в Москве будет подгружаться Windows Script Host. В принципе, это допустимо, но жалко разбазаривать вычислительные мощности на такую ерунду. Поэтому при первом вызове результат имеет смысл запомнить, а при всех последующих просто брать уже готовый. Перепишем первую функцию:

dnl Получения смещения локального часового пояса. 
dnl Возвращает смещение в секундах.
dnl Выполняется один раз, результат кэшируется в течение сессии во всех скриптах pushdef(`m4_bias',`"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation\\Bias"')
pushdef(`m4_timezone_offset',`"TimeZoneOffset"') function TimeZoneOffset()
{ Local Result,WSHShell; if (IsEmpty(Result = StaticVarGet(m4_timezone_offset)))
{ WSHShell = CreateObject("WScript.Shell");
StaticVarSet(m4_timezone_offset,Result = in1Minute * WSHShell.RegRead(m4_bias));
}
Return Result;
} popdef(`m4_bias')
popdef(`m4_timezone_offset')

Я использовал время Москвы как константу UTC+4 часа. Не знаю, правильно ли считать такое смещение константой или наши власти снова будут улучшать инвестиционный климат путём запрещения/разрешения/зимнего/летнего времени. На всякий случай приведу фрагмент скрипта AFL с использованием vbscript, который формирует список всех часовых поясов, которые известны установленной операционной системе. Разделителем назначу вертикальную черту, потому как запятая используется в самих названиях:

 

EnableScript("vbscript");
<%
Set objSh = CreateObject("WScript.Shell") const HKEY_LOCAL_MACHINE = &H80000002
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
szTzsKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"
objReg.EnumKey HKEY_LOCAL_MACHINE, szTzsKeyPath, arrTzSubKeys AFL("result") = "" for Each subkey In arrTzSubKeys
AFL("result") = AFL("result") & objSh.RegRead("HKLM\" & szTzsKeyPath & "\" & subkey & "\Display") & "|"
Next
%>
_TRACE(result);

Например, чтобы найти часовой пояс Москвы, нужно поискать строку "Москва" (а также "Moscow" - операционная система может быть англоязычной) и определить смещение в часах. Удобно для этого использовать регулярные выражения.

Недостаточно прав для комментирования