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

24.09.18

Интеграция - WEB-интеграция

Пример получения текущей даты-времени на примере сервиса 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" + СтрокаВремя);
	
	// возвращаем полный формат даты с временем
	Возврат Дата(СтрокаГод+СтрокаМесяц+СтрокаДень+СтрокаВремя);
	
КонецФункции

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

конфигурация 8.х

См. также

Интеграция Альфа Авто 5 / Альфа Авто 6 и AUTOCRM / Инфотек

Сайты и интернет-магазины WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM разных брендов в одной информационной базе в ручном и автоматическом режиме.

36000 руб.

03.08.2020    15746    10    17    

11

Интеграция 1С — Битрикс24. Обмен задачами

Сайты и интернет-магазины Интеграция WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Интеграция 1С и Битрикс24. Разработка имеет двухстороннюю синхронизацию 1С и Битрикс24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (8.3.18.1289). При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

5040 руб.

04.05.2021    17548    6    15    

13

Интеграция с сервисом vetmanager

WEB-интеграция Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Бытовые услуги, сервис Платные (руб)

Внешняя обработка разрабатывалась для загрузки документов из Ветменеджер в 1С: Бухгалтерия 3.0

12000 руб.

02.02.2021    16359    42    49    

23

[Расширение] БОР-Навигатор.Культура

Зарплата Бюджетный учет WEB-интеграция Обмен с ГосИС Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бюджетный учет Платные (руб)

Расширение конфигурации, включающее в себя объекты, необходимые для подготовки и сдачи отчета "Штатная численность" системы "БОР-Навигатор.Культура" в программе "1С:Зарплата и кадры государственного учреждения", редакция 3.1.

8400 руб.

01.02.2019    25741    9    0    

7

Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС

Обмен с ГосИС WEB-интеграция Платформа 1С v8.3 Управляемые формы 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия государственного учреждения 1С:Документооборот 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Платные (руб)

Обработка является альтернативой механизму, разработанному фирмой 1С и заполняющему реквизиты контрагента по ИНН или наименованию. Не требуется действующей подписки ИТС. Вызывается как внешняя дополнительная обработка, т.е. используется, непосредственно, из карточки контрагента. Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС (egrul.nalog.ru) для БП 2.0, БП 3.0, БГУ 1.0, БГУ 2.0, УТ 10.3, УТ 11.x, КА 1.1, КА 2.x, УПП 1.x, ERP 2.x, УНФ 1.5, УНФ 1.6, УНФ 3.0, ДО 2.1

2400 руб.

28.04.2016    88579    160    215    

318
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Boneman 298 24.09.18 12:27 Сейчас в теме
Идея в принципе хорошая. Возьму на заметку, может где пригодится )
2. AlexPC 24.09.18 13:12 Сейчас в теме
Для клиент-серверного варианта может помочь ТекущаяДатаСеанса()
3. VictorRGB2 13 24.09.18 14:46 Сейчас в теме
(2) проверено, если изменена дата на сервере, вернет опять же измененную дату, а не текущую
собственно проблема и всплыла именно в режиме фоновых заданий, а клиенты менять дату на серверах категорически отказывались
вот и пришлось искать обходной путь
4. AlexPC 24.09.18 15:34 Сейчас в теме
(3)
клиенты менять дату на серверах категорически отказывались


Непонятно. Клиентам было разрешено менять дату на сервере 1с?
5. VictorRGB2 13 24.09.18 16:16 Сейчас в теме
(4) а кто им запретит то? мы не администрируем клиентские сервера, мы лишь поставщики решения по синхронизации данных и не более.
8. MikhailDr 25.09.18 07:41 Сейчас в теме
(5) тут проблема глобальнее, если у клиента есть доступ к серверу 1С, зачем вообще пользователю доступ к серверу
9. AlexPC 25.09.18 19:31 Сейчас в теме
(5)
а кто им запретит то? мы не администрируем клиентские сервера, мы лишь поставщики решения по синхронизации данных и не более.

А синхронизация проходит в рамках локальной сети или через интернет?
10. VictorRGB2 13 26.09.18 08:49 Сейчас в теме
(9) синхронизация через xml, формирование и чтение файлов в локальной сети, отправка и получение файлов через интернет
6. uno-c 234 25.09.18 01:03 Сейчас в теме
&НаКлиенте
Процедура СообщитьТекущееВремя(Команда)
	ХТТП = Новый HTTPСоединение("time.is",,,,,,Новый ЗащищенноеСоединениеOpenSSL);
	Ответ = ХТТП.Получить(Новый HTTPЗапрос("/Unix"));
	СтрокаОтвета = Ответ.ПолучитьТелоКакСтроку();
	Старт = СтрНайти(СтрокаОтвета, "<div id=""twd"">") + 14;
	ЮниксВремя = Число(Сред(СтрокаОтвета, Старт, 10));
	Местное = МестноеВремя(Дата(1970,1,1) + ЮниксВремя);
	Сообщить (Местное);
КонецПроцедуры
Показать
romankoav; A_Max; +2 Ответить
7. uno-c 234 25.09.18 02:13 Сейчас в теме
Можно и по Яндексу, для разнообразия используем объектную модель:
&НаКлиенте
Процедура СообщитьТекущееВремяПоЯндексу(Команда)
	ХТТП = Новый HTTPСоединение("yandex.ru",,,,,,Новый ЗащищенноеСоединениеOpenSSL);
	СтрокаОтвета = ХТТП.Получить(Новый HTTPЗапрос("/time/")).ПолучитьТелоКакСтроку();
	ЧтениеHTML = Новый ЧтениеHTML;
	ЧтениеHTML.УстановитьСтроку(СтрокаОтвета);
	ПостроительDOM = Новый ПостроительDOM;
	ДокументHTML = ПостроительDOM.Прочитать(ЧтениеHTML);
	СтрокаЖсон = ДокументHTML.Тело.Атрибуты.ПолучитьИменованныйЭлемент("data-bem").Значение;
	ЧтениеЖсон = Новый ЧтениеJSON;
	ЧтениеЖсон.УстановитьСтроку(СтрокаЖсон);
	ЖсонХДТО = ФабрикаXDTO.ПрочитатьJSON(ЧтениеЖсон);
	Сообщить (МестноеВремя(Дата(1970,1,1) + ЖсонХДТО.app.time/1000));
КонецПроцедуры
Показать
verssion; A_Max; mysm; gzharkoj; +4 Ответить
11. markers 274 06.11.18 11:26 Сейчас в теме
Как кто-то сказал "Всё новое - давно забытое старое": https://infostart.ru/public/663042/
Оставьте свое сообщение