Каталог решений - Определение текущей даты на основании данных онлайн сервисов

Определение текущей даты на основании данных онлайн сервисов

Определение текущей даты на основании данных онлайн сервисов

В наличии

Пример получения текущей даты-времени на примере сервиса yandex.ru

Категория:

Описание

Т.к. в свое время я не нашел внятных примеров, решил выложить свой пример для yandex, может кому поможет и сократит время.

Основным родом моей деятельности является синхронизация данных между УС на базе 1С и различными другим базами данных.

Механизм обмена в данном случае не важен, важно другое — период синхронизации и то по долгу службы столкнулся с одной проблемой.

Нередко пользователи переводят дату на компьютере в будущее-прошлое. Причины для этого разные и не буду в них вдаваться. Важно, что при подобной смене метод 1С ТекущаяДата() обращается к параметрам системы и возвращает дату будущую-прошлую, что приводит в моем случае к неверной установке периода синхронизации и, как следствие, к к получению неактуальных данных.

Попытки решить вопрос административно, т.е. запретом изменения даты на компьютере, как правило не приводят к результату, клиент по собственным причинам не желает менять принципы своей работы.

Поэтому было принято решение переопределять текущую дату на основании данных онлайн сервиса.

Были эксперименты с сервисами time.nist.gov, ntp.psn.ru, time.windows.com, timeserver.ru, wwp.greenwichmeantime.com, но yandex.ru показался мне наиболее удачным в плане надежности, т.к. с прочими периодически возникали проблемы соединения.

Для подключения к сервису используется типовое HTTPСоединение и дальнейшее распарсивание строки ответа с приведением к типу Дата.

	//Тело POST-запроса, сюда yandex вернет ответ 
	ТелоPOSTЗапроса = "";
	
	//POST-запрос на сервер-приёмник
	СерверПриемник = "www.yandex.ru"; //имя сервера без протокола (http) и порта
	
	// сформируем пустой запрос, нам от yandex ничего не нужно, а при пустом запросе в ответ он как и пошлет текущее дату-время
	ЗаголовкиHTTP = Новый Соответствие;
	ЗаголовкиHTTP.Вставить("Content-Type", "text/html;charset=UTF-8");

	Таймаут = 120;
	SSL =  Новый ЗащищенноеСоединениеOpenSSL();
	НТТР = Новый HTTPСоединение(СерверПриемник, , , , , Таймаут, SSL);

	Попытка
		//Формируем HTTP запрос
		ЗапросHTTP = Новый HTTPЗапрос("", ЗаголовкиHTTP);
		ЗапросHTTP.УстановитьТелоИзСтроки(ТелоPOSTЗапроса); //Устанавливает строку, из которого будет прочитано тело POST-запроса.
		
		//Ответ от сервера получим в возвращаемом значении типа HTTPОтвет
		ОтветHTTP = НТТР.ОтправитьДляОбработки(ЗапросHTTP);
	Исключение
		ТекстСообщения = НСтр("ru = 'Неудачная попытка соединения с '")  + СерверПриемник + ": " + ОписаниеОшибки();
		Сообщить(ТекстСообщения);
		Возврат;
	КонецПопытки;
	
	ЗаголовкиОтвета = ОтветHTTP.Заголовки;
	Если ЗаголовкиОтвета.Количество() > 0 Тогда
		Для каждого КлючИЗначение Из ЗаголовкиОтвета Цикл
			// в ответе много всякого, но нас интересует только DATE
			Если КлючИЗначение.Ключ = "Date" Тогда
				Сообщить("Дата = " +РаспарситьСтрокуЗначения(КлючИЗначение.Значение, Истина));
				Сообщить("ДатаВремя = " +РаспарситьСтрокуЗначения(КлючИЗначение.Значение, Ложь));
				Прервать;
			КонецЕсли;
		КонецЦикла; //Для каждого КлючИЗначение Из ЗаголовкиОтвета
	КонецЕсли;
	
	ОтветHTTP = NULL;

Самое интересно происходит в процедуре РаспарситьСтрокуЗначения(), которая и занимается разбором ответа от сервиса и приведением его к типу Дата.

Функция ВернутьЧисловойСтрокой(пМесяц)
	
	Если Найти(НРег(пМесяц), "jan") > 0 Тогда
		Возврат "01";
	ИначеЕсли Найти(НРег(пМесяц), "feb") > 0 Тогда
		Возврат "02";
	ИначеЕсли Найти(НРег(пМесяц), "mar") > 0 Тогда
		Возврат "03";
	ИначеЕсли Найти(НРег(пМесяц), "apr") > 0 Тогда
		Возврат "04";
	ИначеЕсли Найти(НРег(пМесяц), "may") > 0 Тогда
		Возврат "05";
	ИначеЕсли Найти(НРег(пМесяц), "jun") > 0 Тогда
		Возврат "06";
	ИначеЕсли Найти(НРег(пМесяц), "jul") > 0 Тогда
		Возврат "07";
	ИначеЕсли Найти(НРег(пМесяц), "aug") > 0 Тогда
		Возврат "08";
	ИначеЕсли Найти(НРег(пМесяц), "sep") > 0 Тогда
		Возврат "09";
	ИначеЕсли Найти(НРег(пМесяц), "oct") > 0 Тогда
		Возврат "10";
	ИначеЕсли Найти(НРег(пМесяц), "nov") > 0 Тогда
		Возврат "11";
	ИначеЕсли Найти(НРег(пМесяц), "dec") > 0 Тогда
		Возврат "12";
	КонецЕсли;
	
КонецФункции

Функция РаспарситьСтрокуЗначения(пЗначение, ТолькоДата = Истина)
	// строка значения заголовка типа DATE  = "Tue, 27 Dec 2016 12:12:49 GMT"
	
	СтрокаДата = "";
	разделитель = ",";
	разделительПробел = " ";
    // местное отклонение по часовому поясу от Гринвича, в примере для простоты объявлено прямо в коде, но рекомендуется выносить в параметры или в реквизиты
	ОтклонениеПоЧасововмуПоясу = 3; 
	
	// отсекаем день недели - остается "27 Dec 2016 12:12:49 GMT"
	позицияРазделитель = Найти(пЗначение, разделитель);
	СтрокаДатаВремя = СокрЛП(Сред(пЗначение, позицияРазделитель+1));
	
	// получаем значение номера дня  - "27"
	позицияРазделительПробел = Найти(СтрокаДатаВремя, разделительПробел);
	СтрокаДень = СокрЛП(Сред(СтрокаДатаВремя, 1, позицияРазделительПробел-1));
	
	// отсекаем номер дня - остается "Dec 2016 12:12:49 GMT"
	СтрокаДатаВремя = СокрЛП(Сред(СтрокаДатаВремя, позицияРазделительПробел+1));
	
	// получаем номер месяца - "Dec", после преобразорвания - "12"
	позицияРазделительПробел = Найти(СтрокаДатаВремя, разделительПробел);
	СтрокаМесяц = СокрЛП(Сред(СтрокаДатаВремя, 1, позицияРазделительПробел-1));
	СтрокаМесяц = ВернутьЧисловойСтрокой(СтрокаМесяц); 
	
	// отсекаем номер месяца - остается "2016 12:12:49 GMT"
	СтрокаДатаВремя = СокрЛП(Сред(СтрокаДатаВремя, позицияРазделительПробел+1));
	
	// получаем номер года - "2016"
	позицияРазделительПробел = Найти(СтрокаДатаВремя, разделительПробел);
	СтрокаГод = СокрЛП(Сред(СтрокаДатаВремя, 1, позицияРазделительПробел-1));
	
	// вычислили дату, если запрашивали только ее, возвращаем
	Если ТолькоДата Тогда
		Возврат Дата(СтрокаГод+СтрокаМесяц+СтрокаДень);
	КонецЕсли;
	
	// вычисляем время
	// отсекам номер года - остается "12:12:49 GMT"
	СтрокаДатаВремя = СокрЛП(Сред(СтрокаДатаВремя, позицияРазделительПробел+1));
	
	// получаем время - "12:12:49", после преобразования - "121249"
	позицияРазделительПробел = Найти(СтрокаДатаВремя, разделительПробел);
	лСтрокаВремя = СокрЛП(Сред(СтрокаДатаВремя, 1, позицияРазделительПробел-1));
	лСтрокаВремя = СтрЗаменить(лСтрокаВремя, ":", "");
	
	// расчитываем время с учетом часового пояса
	лЧасы = Число(Сред(лСтрокаВремя, 1, 2));
	лОстальное = Сред(лСтрокаВремя, 3);
	лЧасы = лЧасы + ОтклонениеПоЧасововмуПоясу;
	СтрокаВремя = Строка(лЧасы) + лОстальное;
	СтрокаВремя = ?(СтрДлина(СтрокаВремя) = 6, СтрокаВремя, "0" + СтрокаВремя);
	
	// возвращаем полный формат даты с временем
	Возврат Дата(СтрокаГод+СтрокаМесяц+СтрокаДень+СтрокаВремя);
	
КонецФункции

В результате имеем надежный, простой и быстрый способ определения точной текущей даты и времени.

has been added to your cart:
Оформление заказа