Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PlugFox/73f017dbe42fd37b245581a40258913f to your computer and use it in GitHub Desktop.
Save PlugFox/73f017dbe42fd37b245581a40258913f to your computer and use it in GitHub Desktop.
ПреобразоватьВДату
#Область ПреобразоватьВДату
// Возвращает неопределено в случае ошибки
//
// Дата может передаваться в следующих видах:
//
// В виде строки с разделителями
//
// Время, в случае наличия, обязано разделятся символом “:”
// День, Месяц, Год обязаны отделяться друг от друга произвольными символами или пробелами
// Время может состоять только из часов и минут, секунды опциональны
// После времени может указываться смещение часового пояса (знаками + или -) в формате:
//
// ±hhmm, например: +0330
// ±h разделитель m, например: -3:30
//
//
// Дата и время могут разделяться символом “T”, до идет дата, после время
// Можно не указывать дату или время
// Желательно указывать год состоящий из 4 символов
// Прописью нельзя указать год меньший 100 - все что меньше будет распознаваться как 20XX
// Месяц в дате может быть записан прописью на латинице или кирилице, учитываются первые 3 символа
// Если дата указана - должен быть указан и год.
// В случае неоднозначной записи даты, приоритет распознования следующий:
//
// DD-MM-YY
// YY-MM-DD
// MM-DD-YY
// MM-YY-DD
// YY-DD-MM
// DD-YY-MM
//
//
//
//
//
//
// В ISO 8601:2004 формате (YYYYMMDDThh:mm:ss±hhmm)
//
// Время обязано отделяться от даты символом ‘T’
// Время, в случае наличия, обязано разделятся символом “:”, в случае отсутсвия разделителя - будет опущено.
// Количество разрядов должно соответсвовать шаблону, а именно 8 символов
// Не допускается год меньше 1000
// Дату или время можно указывать с разделителями (см. выше)
//
// Не допускается запись “YYYYMMDD” - она будет воспринята как UnixTime, добавьте или разделители или знак “T”
//
//
//
//
//
// Числом
//
// Значения до 4000 - расцениваются как год
// Значения от 4000 - как UnixTime
//
//
//
// Представлением периода, в таком случае берется значение наиболее удаленное от текущей даты
//
// Вчера
// Yesterday
// ДоКонцаЭтогоГода
// TillEndOfThisYear
// ДоКонцаЭтогоКвартала
// TillEndOfThisQuarter
// ДоКонцаЭтогоМесяца
// TillEndOfThisMonth
// ДоКонцаЭтогоПолугодия
// TillEndOfThisHalfYear
// ДоКонцаЭтойДекады
// TillEndOfThisTenDays
// ДоКонцаЭтойНедели
// TillEndOfThisWeek
// Завтра
// Tomorrow
// Месяц
// Month
// Последние7Дней
// Last7Days
// ПроизвольныйПериод
// Custom
// ПрошлаяДекада
// LastTenDays
// ПрошлаяДекадаДоТакогоЖеНомераДня
// LastTenDaysTillSameDayNumber
// ПрошлаяНеделя
// LastWeek
// ПрошлаяНеделяДоТакогоЖеДняНедели
// LastWeekTillSameWeekDay
// ПрошлоеПолугодие
// LastHalfYear
// ПрошлоеПолугодиеДоТакойЖеДаты
// LastHalfYearTillSameDate
// ПрошлыйГод
// LastYear
// ПрошлыйГодДоТакойЖеДаты
// LastYearTillSameDate
// ПрошлыйКвартал
// LastQuarter
// ПрошлыйКварталДоТакойЖеДаты
// LastQuarterTillSameDate
// ПрошлыйМесяц
// LastMonth
// ПрошлыйМесяцДоТакойЖеДаты
// LastMonthTillSameDate
// Сегодня
// Today
// СледующаяДекада
// NextTenDays
// СледующаяДекадаДоТакогоЖеНомераДня
// NextTenDaysTillSameDayNumber
// СледующаяНеделя
// NextWeek
// СледующаяНеделяДоТакогоЖеДняНедели
// NextWeekTillSameWeekDay
// СледующееПолугодие
// NextHalfYear
// СледующееПолугодиеДоТакойЖеДаты
// NextHalfYearTillSameDate
// Следующие7Дней
// Next7Days
// СледующийГод
// NextYear
// СледующийГодДоТакойЖеДаты
// NextYearTillSameDate
// СледующийКвартал
// NextQuarter
// СледующийКварталДоТакойЖеДаты
// NextQuarterTillSameDate
// СледующийМесяц
// NextMonth
// СледующийМесяцДоТакойЖеДаты
// NextMonthTillSameDate
// СНачалаЭтогоГода
// FromBeginningOfThisYear
// СНачалаЭтогоКвартала
// FromBeginningOfThisQuarter
// СНачалаЭтогоМесяца
// FromBeginningOfThisMonth
// СНачалаЭтогоПолугодия
// FromBeginningOfThisHalfYear
// СНачалаЭтойДекады
// FromBeginningOfThisTenDays
// СНачалаЭтойНедели
// FromBeginningOfThisWeek
// ЭтаДекада
// ThisTenDays
// ЭтаНеделя
// ThisWeek
// ЭтоПолугодие
// ThisHalfYear
// ЭтотГод
// ThisYear
// ЭтотКвартал
// ThisQuarter
// ЭтотМесяц
// ThisMonth
Функция ПреобразоватьВДату(Знач Значение, Шаблон = Неопределено, ВспомогательныеДанные = Неопределено) Экспорт
Попытка
Если ТипЗнч(Значение) = Тип("Дата") Или Значение = Неопределено Тогда // Если это уже дата
Возврат Значение;
ИначеЕсли ТипЗнч(Значение) = Тип("Число") Тогда // Если значение является числом
Если ЭтоГод(Значение) Тогда // Если это запись года
Возврат Дата(Значение, 1, 1);
Иначе // Ну тогда, вероятнее всего, это UnixTime
Возврат ЧислоВДату(Значение);
КонецЕсли;
ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда // Если значение является строкой
Значение = СокрЛП(НРег(РаскодироватьСтроку(Значение, СпособКодированияСтроки.КодировкаURL, "UTF-8")));
// Попробуем быстро преобразовать
результат = Неопределено;
Попытка
м = НайтиЧислаВСтроке(Значение);
Если м.Количество() = 3 Тогда
Если м[0]<32 И м[1]<13 И м[2]>31 Тогда
результат = Дата(м[2],м[1],м[0]);
ИначеЕсли м[0]>31 И м[1]<13 И м[2]<32 Тогда
результат = Дата(м[0],м[1],м[2]);
КонецЕсли;
КонецЕсли;
Исключение
КонецПопытки;
Если ТипЗнч(результат) = Тип("Дата") Тогда Возврат результат КонецЕсли;
// Если передано число записаное строкой
Если ТолькоЦифрыВСтроке(Значение, Истина) Тогда
Возврат ЧислоВДату(СтрокаВЧисло(Значение));
КонецЕсли;
// Пробуем разобрать дату из строки более сложным алгоритмом
результат = СтрокаВДату(Значение);
Если ТипЗнч(результат) = Тип("Дата") Тогда Возврат результат КонецЕсли;
// Разбираем как запись прописью
// ...
// Если передан вариант стандартного периода (Вчера, Сегодня, ЭтотГод...)
результат = ВариантСтандартногоПериода(Значение);
Если ТипЗнч(результат) = Тип("Дата") Тогда Возврат результат; КонецЕсли;
КонецЕсли;
Исключение
ОписаниеОшибки = "Ошибка преобразования даты:
|" + ОписаниеОшибки();
Сообщить(ОписаниеОшибки, СтатусСообщения.Внимание);
Возврат Неопределено;
КонецПопытки;
Возврат Неопределено;
КонецФункции
#Область Вспомогательные_функции
&НаСервере
Функция СтрокаВДату(Знач Значение)
ДлинаСтроки = СтрДлина(Значение);
РазделительДатаВремя = СтрНайти(Значение, "t");
АнглийскийАлфавит = "abcdefghijklmnopqrstuvwxyz";
Если РазделительДатаВремя > 0
И (РазделительДатаВремя = 1
Или СтрНайти(АнглийскийАлфавит, Сред(Значение, РазделительДатаВремя-1, 1))
Или СтрНайти(АнглийскийАлфавит, Сред(Значение, РазделительДатаВремя+1, 1))
) Тогда
РазделительДатаВремя = 0;
КонецЕсли; // Игнорируем разделитель T, если слева или справа от него стоят символы английского алфавита
// Запись времени
Если РазделительДатаВремя = ДлинаСтроки Тогда
ВремяСтрокой = "";
ИначеЕсли РазделительДатаВремя Тогда
ВремяСтрокой = Сред(Значение, РазделительДатаВремя+1);
Иначе
ВремяСтрокой = Значение;
КонецЕсли;
// Сначало вычленим время из строки
// Если есть время в строке, стоит двоеточие
// Очередность Часы : Минуты : Секунды
Час = 0;
Минута = 0;
Секунда = 0;
РазделительЧасовМинут = СтрНайти(ВремяСтрокой, ":");
РазделительМинутСекунд = 0;
РазделительСмещения = 0;
НачалоВремени = 0;
КонецВремени = 0;
Если РазделительЧасовМинут <> 0 Тогда
РазделительМинутСекунд = СтрНайти(ВремяСтрокой, ":",, Мин(РазделительЧасовМинут+1, ДлинаСтроки));
// Если со смещением времени
РазделительСмещенияМинус = СтрНайти(ВремяСтрокой, "-",, РазделительЧасовМинут);
РазделительСмещенияПлюс = СтрНайти(ВремяСтрокой, "+",, РазделительЧасовМинут);
РазделительСмещения = Макс(РазделительСмещенияМинус, РазделительСмещенияПлюс);
РазделительМинутСекунд = ?(РазделительСмещения<>0 И РазделительМинутСекунд>РазделительСмещения, 0, РазделительМинутСекунд);
НачалоВремени = 0;
КонецВремени = 0;
Час = ВыбратьЧислоИзСтроки(Лев(ВремяСтрокой, РазделительЧасовМинут), Ложь); // Часы
НачалоВремени = СтрНайти(ВремяСтрокой, Строка(Час), НаправлениеПоиска.СКонца, РазделительЧасовМинут-1, 1)-1;
КонецВремени = РазделительЧасовМинут+1;
Если Не ЭтоЧас(Час) Тогда ВызватьИсключение СтрШаблон("В записи %1, число %2 - не является часом.", ВремяСтрокой, Час) КонецЕсли;
Минута = ВыбратьЧислоИзСтроки(ВремяСтрокой, Истина, РазделительЧасовМинут, ?(РазделительМинутСекунд=0, ДлинаСтроки, РазделительМинутСекунд)); // Минуты
КонецВремени = Макс(КонецВремени, СтрНайти(ВремяСтрокой, Строка(Минута), НаправлениеПоиска.СНачала, РазделительЧасовМинут+1, 1) + 1);
Если Не ЭтоМинута(Минута) Тогда ВызватьИсключение СтрШаблон("В записи %1, число %2 - не является минутой.", ВремяСтрокой, Минута) КонецЕсли;
Если РазделительМинутСекунд <> 0 Тогда
Секунда = ВыбратьЧислоИзСтроки(ВремяСтрокой, Истина, РазделительМинутСекунд); // Секунды
КонецВремени = Макс(КонецВремени, СтрНайти(ВремяСтрокой, Строка(Секунда), НаправлениеПоиска.СНачала, РазделительМинутСекунд+1, 1) + СтрДлина(Секунда));
Если Не ЭтоСекунда(Секунда) Тогда ВызватьИсключение СтрШаблон("В записи %1, число %2 - не является секундой.", ВремяСтрокой, Секунда) КонецЕсли;
КонецЕсли;
КонецЕсли;
СмещениеВремени = 0;
Если РазделительСмещения<>0 Тогда
м = НайтиЧислаВСтроке(Сред(ВремяСтрокой, РазделительСмещения + 1));
Если м.Количество() Тогда
КонецВремени = Макс(КонецВремени, СтрНайти(ВремяСтрокой, м[м.ВГраница()], НаправлениеПоиска.СКонца) + СтрДлина(м[м.ВГраница()]));
Если СтрДлина(Формат(м[0], "ЧГ=0"))>2 Тогда
СмещениеВремени = (Число(Лев(Формат(м[0], "ЧГ=0"), СтрДлина(Формат(м[0], "ЧГ=0"))-2))*60*60 + Число(Прав(Формат(м[0], "ЧГ=0"), 2))*60)*?(РазделительСмещенияМинус, -1, 1);
Иначе
СмещениеВремени = (м[0]*60*60 + ?(м.Количество()>1, м[1]*60, 0))*?(РазделительСмещенияМинус, -1, 1);
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Запись даты
Если РазделительДатаВремя Тогда
ДатаСтрокой = Лев(Значение, РазделительДатаВремя-1);
Иначе
ДатаСтрокой = Лев(Значение, НачалоВремени) + Сред(Значение, КонецВремени);
КонецЕсли;
// Вычислим дату
День = 1;
Месяц = 1;
Год = 1;
м = НайтиЧислаВСтроке(ДатаСтрокой);
// Удалим нули из даты
Количество = м.Количество();
Для Счетчик = 1 По Количество Цикл
Если м[Количество-Счетчик] <> 0 Тогда Продолжить КонецЕсли;
м.Удалить(Количество-Счетчик);
КонецЦикла;
// Если месяц записан прописью
НумерацияМесяцев = ПолучитьНумерациюМесяцев();
МесяцУказанСтрокой = Ложь;
Для Каждого КлючЗначение Из НумерацияМесяцев Цикл
НазваниеМесяца = НРег(Лев(КлючЗначение.Ключ, 3));
Если Не СтрНайти(ДатаСтрокой, НазваниеМесяца) Тогда Продолжить КонецЕсли;
Месяц = Число(КлючЗначение.Значение);
МесяцУказанСтрокой = Истина;
КонецЦикла;
// Если дата не была указана
Если м.Количество() = 0 И Не МесяцУказанСтрокой Тогда
Возврат Дата(1, 1, 1, Час, Минута, Секунда) + СмещениеВремени;
ИначеЕсли м.Количество() = 1 И Не МесяцУказанСтрокой И СтрДлина(Формат(м[0], "ЧГ=0")) = 8 Тогда
Год = Цел(м[0]/10000);
Месяц = Цел(м[0]/100) - Год*100;
День = м[0] - Месяц*100 - Год*10000;
Если Не ЭтоГод(Год) Или Не ЭтоМесяц(Месяц) Или Не ЭтоДень(День,Месяц,Год) Тогда ВызватьИсключение "Неизвестная запись даты: " + ДатаСтрокой КонецЕсли;
Возврат Дата(Год, Месяц, День, Час, Минута, Секунда) + СмещениеВремени;
КонецЕсли;
// Причешем массив
Для Счетчик = 0 По ?(МесяцУказанСтрокой, 1, 2) Цикл
Если м.ВГраница() < Счетчик Тогда
м.Вставить(0, 1);
ИначеЕсли м[Счетчик] = Неопределено Или м[Счетчик] = 0 Тогда
м[Счетчик] = 1;
КонецЕсли;
КонецЦикла;
// Если в массиве больше 3 чисел
Если м.Количество() > ?(МесяцУказанСтрокой, 2, 3) Тогда ВызватьИсключение "Слишком много цифр в дате" КонецЕсли;
Если ЭтоДень(м[0],Месяц,м[1]) И ЭтоГод(м[1]) И МесяцУказанСтрокой Тогда // DD МЕСЯЦ ИЗВЕСТЕН YYYY
День = м[0]; Месяц = Месяц; Год = м[1];
ИначеЕсли ЭтоГод(м[0]) И ЭтоДень(м[1],Месяц,м[0]) И МесяцУказанСтрокой Тогда // YYYY МЕСЯЦ ИЗВЕСТЕН DD
День = м[1]; Месяц = Месяц; Год = м[0];
ИначеЕсли ЭтоДень(м[0],м[1],м[2]) И ЭтоМесяц(м[1]) И ЭтоГод(м[2]) И Не МесяцУказанСтрокой Тогда // DD.MM.YYYY
День = м[0]; Месяц = м[1]; Год = м[2];
ИначеЕсли ЭтоГод(м[0]) И ЭтоМесяц(м[1]) И ЭтоДень(м[2],м[1],м[0]) И Не МесяцУказанСтрокой Тогда // YYYY-MM-DD
День = м[2]; Месяц = м[1]; Год = м[0];
ИначеЕсли ЭтоМесяц(м[0]) И ЭтоДень(м[1],м[0],м[2]) И ЭтоГод(м[2]) И Не МесяцУказанСтрокой Тогда // MM-DD-YYYY
День = м[1]; Месяц = м[0]; Год = м[2];
ИначеЕсли ЭтоМесяц(м[0]) И ЭтоГод(м[1]) И ЭтоДень(м[2],м[0],м[1]) И Не МесяцУказанСтрокой Тогда // MM-YYYY-DD
День = м[2]; Месяц = м[0]; Год = м[1];
ИначеЕсли ЭтоГод(м[0]) И ЭтоДень(м[1],м[2],м[0]) И ЭтоМесяц(м[2]) И Не МесяцУказанСтрокой Тогда // YYYY-DD-MM
День = м[1]; Месяц = м[2]; Год = м[0];
ИначеЕсли ЭтоДень(м[0],м[2],м[1]) И ЭтоГод(м[1]) И ЭтоМесяц(м[2]) И Не МесяцУказанСтрокой Тогда // DD-YYYY-MM
День = м[0]; Месяц = м[2]; Год = м[1];
Иначе
ВызватьИсключение "Неизвестная запись даты: " + ДатаСтрокой;
КонецЕсли;
Возврат Дата(?(СтрДлина(Год)<3, 2000 + Год, Год), Месяц, День, Час, Минута, Секунда) + СмещениеВремени;
КонецФункции
// Проверяет, содержит ли строка только цифры.
//
// Параметры:
// Значение - Строка - проверяемая строка.
// ПробелыЗапрещены - Булево - если Ложь, то в строке допустимо наличие пробелов.
//
// Возвращаемое значение:
// Булево - Истина - строка содержит только цифры или пустая, Ложь - строка содержит иные символы.
//
// Пример:
// Результат = СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке("0123"); // Истина
// Результат = СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке("0123abc"); // Ложь
// Результат = СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке("01 2 3",, Ложь); // Истина
//
Функция ТолькоЦифрыВСтроке(Знач Значение, Знач ПробелыЗапрещены = Истина)
Если ТипЗнч(Значение) <> Тип("Строка") Тогда
Возврат Ложь;
КонецЕсли;
Если Не ПробелыЗапрещены Тогда
Значение = СтрЗаменить(Значение, " ", "");
КонецЕсли;
Если СтрДлина(Значение) = 0 Тогда
Возврат Истина;
КонецЕсли;
// Если содержит только цифры, то в результате замен должна быть получена пустая строка.
// Проверять при помощи ПустаяСтрока нельзя, так как в исходной строке могут быть пробельные символы.
Возврат СтрДлина(
СтрЗаменить( СтрЗаменить( СтрЗаменить( СтрЗаменить( СтрЗаменить(
СтрЗаменить( СтрЗаменить( СтрЗаменить( СтрЗаменить( СтрЗаменить(
Значение, "0", ""), "1", ""), "2", ""), "3", ""), "4", ""), "5", ""), "6", ""), "7", ""), "8", ""), "9", "")) = 0;
КонецФункции
// Преобразует исходную строку в число без вызова исключений.
//
// Параметры:
// Значение - Строка - Строка, которую необходимо привести к числу.
// Например, "10", "+10", "010", вернет 10;
// "(10)", "-10",вернет -10;
// "10,2", "10.2",вернет 10.2;
// "000", " ", "",вернет 0;
// "10текст", вернет Неопределено.
//
// Возвращаемое значение:
// Число, Неопределено - Полученное число, либо Неопределено, если строка не является числом.
//
Функция СтрокаВЧисло(Знач Значение)
Значение = СтрЗаменить(Значение, " ", "");
Если СтрНачинаетсяС(Значение, "(") Тогда
Значение = СтрЗаменить(Значение, "(", "-");
Значение = СтрЗаменить(Значение, ")", "");
КонецЕсли;
СтрокаБезНулей = СтрЗаменить(Значение, "0", "");
Если ПустаяСтрока(СтрокаБезНулей) Или СтрокаБезНулей = "-" Тогда
Возврат 0;
КонецЕсли;
ТипЧисло = Новый ОписаниеТипов("Число");
Результат = ТипЧисло.ПривестиЗначение(Значение);
Возврат ?(Результат <> 0 И Не ПустаяСтрока(СтрокаБезНулей), Результат, Неопределено);
КонецФункции
Функция НайтиЧислаВСтроке(Знач Строка)
Строка = Строка + "_"; // Добавляю символ заведомо не являющийся числом
МассивЧисел = Новый Массив;
СтрокаЧисел = "";
Для Индекс = 1 По СтрДлина(Строка) Цикл
Символ = Сред(Строка, Индекс, 1);
Если КодСимвола(Символ) >= 48 И КодСимвола(Символ) <= 57 Тогда // Код нуля - 48, код 9-ки - 57
СтрокаЧисел = СтрокаЧисел + Символ;
ИначеЕсли СтрДлина(СтрокаЧисел) > 0 Тогда
МассивЧисел.Добавить(Число(СтрокаЧисел));
СтрокаЧисел = "";
КонецЕсли;
КонецЦикла;
Возврат МассивЧисел;
КонецФункции
// Возвращает первое найденное число
// Возвращает 0, если нет числа
Функция ВыбратьЧислоИзСтроки(Знач Строка, Знач СНачала = Истина, Знач НачальнаяПозиция = 1, Знач КонечнаяПозиция = Неопределено)
ЧислоСтрокой = "";
ДлинаСтроки = СтрДлина(Строка);
КонечнаяПозиция = ?(КонечнаяПозиция=Неопределено, ДлинаСтроки, КонечнаяПозиция);
Для Индекс = НачальнаяПозиция По ДлинаСтроки Цикл
Символ = Сред(Строка, ?(СНачала, Индекс, ДлинаСтроки-Индекс+1), 1);
Если Индекс > КонечнаяПозиция Тогда
Прервать;
ИначеЕсли КодСимвола(Символ) >= 48 И КодСимвола(Символ) <= 57 Тогда // Код нуля - 48, код 9-ки - 57
ЧислоСтрокой = ЧислоСтрокой + Символ;
ИначеЕсли Не ПустаяСтрока(ЧислоСтрокой) Тогда
Прервать;
КонецЕсли;
КонецЦикла;
// Если шли с конца - перевернем результат
Если Не СНачала Тогда
ДлинаСтроки = СтрДлина(ЧислоСтрокой);
Строка = "";
Для Индекс = 1 по ДлинаСтроки Цикл
Строка = Сред(ЧислоСтрокой, Индекс, 1) + Строка;
КонецЦикла;
ЧислоСтрокой = Строка;
КонецЕсли;
Возврат ?(ПустаяСтрока(ЧислоСтрокой), 0, Число(ЧислоСтрокой));
КонецФункции
// Получает значения параметров из строки.
//
// Параметры:
// СтрокаПараметров - Строка - строка, содержащая параметры, каждый из которых представляет собой
// фрагмент вида <Имя параметра>=<Значение>, где:
// Имя параметра - имя параметра;
// Значение - его значение.
// Фрагменты отделяются друг от друга символами ';'.
// Если значение содержит пробельные символы, то оно должно быть заключено в двойные
// кавычки (").
// Например:
// "File=""c:\InfoBases\Trade""; Usr=""Director"";"
// РазделительЗаписей - Строка - символ, которым фрагменты отделяются друг от друга.
// РазделительКлючЗначение - Строка - символ, которым ключ отделяются от значения.
//
// Возвращаемое значение:
// Структура - значения параметров, где ключ - имя параметра, значение - значение параметра.
//
// Пример:
// Результат = СтроковыеФункцииКлиентСервер.ПараметрыИзСтроки("File=""c:\InfoBases\Trade""; Usr=""Director"";""", ";");
// - вернет структуру:
// ключ "File" и значение "c:\InfoBases\Trade"
// ключ "Usr" и значение "Director".
//
Функция ПараметрыИзСтроки(Знач СтрокаПараметров, Знач РазделительЗаписей = ";", Знач РазделительКлючЗначение = "=")
Результат = Новый Структура;
ОписаниеПараметра = "";
НайденоНачалоСтроки = Ложь;
НомерПоследнегоСимвола = СтрДлина(СтрокаПараметров);
Для НомерСимвола = 1 По НомерПоследнегоСимвола Цикл
Символ = Сред(СтрокаПараметров, НомерСимвола, 1);
Если Символ = """" Тогда
НайденоНачалоСтроки = Не НайденоНачалоСтроки;
КонецЕсли;
Если Символ <> РазделительЗаписей Или НайденоНачалоСтроки Тогда
ОписаниеПараметра = ОписаниеПараметра + Символ;
КонецЕсли;
Если Символ = РазделительЗаписей И Не НайденоНачалоСтроки Или НомерСимвола = НомерПоследнегоСимвола Тогда
Позиция = СтрНайти(ОписаниеПараметра, РазделительКлючЗначение);
Если Позиция > 0 Тогда
ИмяПараметра = СокрЛП(Лев(ОписаниеПараметра, Позиция - 1));
ЗначениеПараметра = СокрЛП(Сред(ОписаниеПараметра, Позиция + 1));
ЗначениеПараметра = СократитьДвойныеКавычки(ЗначениеПараметра);
Результат.Вставить(ИмяПараметра, ЗначениеПараметра);
КонецЕсли;
ОписаниеПараметра = "";
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
// Удаляет двойные кавычки с начала и конца строки, если они есть.
//
// Параметры:
// Значение - Строка - входная строка.
//
// Возвращаемое значение:
// Строка - строка без двойных кавычек.
//
Функция СократитьДвойныеКавычки(Знач Значение)
Пока СтрНачинаетсяС(Значение, """") Цикл
Значение = Сред(Значение, 2);
КонецЦикла;
Пока СтрЗаканчиваетсяНа(Значение, """") Цикл
Значение = Лев(Значение, СтрДлина(Значение) - 1);
КонецЦикла;
Возврат Значение;
КонецФункции
Функция ОставитьТолькоБуквы(Знач Значение)
Алфавит = "abcdefghijklmnopqrstuvwxyz"
+ "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
КоличествоСимволов = СтрДлина(Значение);
Для Счетчик = 1 По КоличествоСимволов Цикл
Если Не СтрНайти(Алфавит, Сред(Значение, Счетчик, 1)) Тогда Продолжить КонецЕсли;
Значение = Значение + Сред(Значение, Счетчик, 1);
КонецЦикла;
Возврат Сред(Значение, Счетчик);
КонецФункции
Функция ВариантСтандартногоПериода(Знач Значение)
Значение = ОставитьТолькоБуквы(Значение);
Если Значение = "текущаядата" Тогда Возврат ТекущаяДата() КонецЕсли;
Варианты = "
|Вчера;
|Yesterday;
|ДоКонцаЭтогоГода;
|TillEndOfThisYear;
|ДоКонцаЭтогоКвартала;
|TillEndOfThisQuarter;
|ДоКонцаЭтогоМесяца;
|TillEndOfThisMonth;
|ДоКонцаЭтогоПолугодия;
|TillEndOfThisHalfYear;
|ДоКонцаЭтойДекады;
|TillEndOfThisTenDays;
|ДоКонцаЭтойНедели;
|TillEndOfThisWeek;
|Завтра;
|Tomorrow;
|Месяц;
|Month;
|Последние7Дней;
|Last7Days;
|ПроизвольныйПериод;
|Custom;
|ПрошлаяДекада;
|LastTenDays;
|ПрошлаяДекадаДоТакогоЖеНомераДня;
|LastTenDaysTillSameDayNumber;
|ПрошлаяНеделя;
|LastWeek;
|ПрошлаяНеделяДоТакогоЖеДняНедели;
|LastWeekTillSameWeekDay;
|ПрошлоеПолугодие;
|LastHalfYear;
|ПрошлоеПолугодиеДоТакойЖеДаты;
|LastHalfYearTillSameDate;
|ПрошлыйГод;
|LastYear;
|ПрошлыйГодДоТакойЖеДаты;
|LastYearTillSameDate;
|ПрошлыйКвартал;
|LastQuarter;
|ПрошлыйКварталДоТакойЖеДаты;
|LastQuarterTillSameDate;
|ПрошлыйМесяц;
|LastMonth;
|ПрошлыйМесяцДоТакойЖеДаты;
|LastMonthTillSameDate;
|Сегодня;
|Today;
|СледующаяДекада;
|NextTenDays;
|СледующаяДекадаДоТакогоЖеНомераДня;
|NextTenDaysTillSameDayNumber;
|СледующаяНеделя;
|NextWeek;
|СледующаяНеделяДоТакогоЖеДняНедели;
|NextWeekTillSameWeekDay;
|СледующееПолугодие;
|NextHalfYear;
|СледующееПолугодиеДоТакойЖеДаты;
|NextHalfYearTillSameDate;
|Следующие7Дней;
|Next7Days;
|СледующийГод;
|NextYear;
|СледующийГодДоТакойЖеДаты;
|NextYearTillSameDate;
|СледующийКвартал;
|NextQuarter;
|СледующийКварталДоТакойЖеДаты;
|NextQuarterTillSameDate;
|СледующийМесяц;
|NextMonth;
|СледующийМесяцДоТакойЖеДаты;
|NextMonthTillSameDate;
|СНачалаЭтогоГода;
|FromBeginningOfThisYear;
|СНачалаЭтогоКвартала;
|FromBeginningOfThisQuarter;
|СНачалаЭтогоМесяца;
|FromBeginningOfThisMonth;
|СНачалаЭтогоПолугодия;
|FromBeginningOfThisHalfYear;
|СНачалаЭтойДекады;
|FromBeginningOfThisTenDays;
|СНачалаЭтойНедели;
|FromBeginningOfThisWeek;
|ЭтаДекада;
|ThisTenDays;
|ЭтаНеделя;
|ThisWeek;
|ЭтоПолугодие;
|ThisHalfYear;
|ЭтотГод;
|ThisYear;
|ЭтотКвартал;
|ThisQuarter;
|ЭтотМесяц;
|ThisMonth;";
Варианты = НРег(Варианты);
Позиция = СтрНайти(Варианты, Символы.ПС + Значение + ";");
Если Не Позиция Тогда Возврат Неопределено КонецЕсли;
Период = Новый СтандартныйПериод(ВариантСтандартногоПериода[Значение]);
Если Макс(ТекущаяДата()-Период.ДатаНачала, Период.ДатаНачала-ТекущаяДата())
> Макс(ТекущаяДата()-Период.ДатаОкончания, Период.ДатаОкончания-ТекущаяДата()) Тогда
Возврат Период.ДатаНачала;
Иначе
Возврат Период.ДатаОкончания;
КонецЕсли;
КонецФункции
Функция ПолучитьНумерациюМесяцев()
МассивСтрокой = "
|январь :01
|january :01
|февраль :02
|february :02
|март :03
|march :03
|апрель :04
|april :04
|май :05
|may :05
|июнь :06
|june :06
|июль :07
|july :07
|август :08
|august :08
|сентябрь :09
|september :09
|октябрь :10
|october :10
|ноябрь :11
|november :11
|декабрь :12
|december :12";
МассивСтрокой = СтрЗаменить(МассивСтрокой, Символы.ПС, ";");
МассивСтрокой = СтрЗаменить(МассивСтрокой, " ", "");
Возврат ПараметрыИзСтроки(МассивСтрокой, ";", ":");
КонецФункции
//Спецсимволы:
// . - любой символ
// + - один или более раз, пример ".+" - один или более любой символ.
// * - ноль или более раз, пример ".*" - любое количество любых символов (даже ни одного).
// [n-m] - символ от m до n, пример: "[0-9]+" - одна или более цифр(а).
// \d - цифра, пример \d+ - одна или более цифр(а).
// \D - не цифра.
// \s - пробельный символ - ТАБ, пробел, перенос строки, возврат каретки и т.п.
// \S - непробельный символ.
// \w - буква, цифра, подчеркивание.
// \W - не буква, не цифра и не подчеркивание соответственно.
// {m,n} - шаблон для от m до n символов, например "\d{2,4}" - от двух до четырех цифр. Можно указать одну и всего цифру для строгого соответвия.
// \ - экранирует спецсимволы. Например, "\." - символ точки.
Функция ПроверитьСтроку(Строка, Фасет)
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(
"<Model
|xmlns=""http://v8.1c.ru/8.1/xdto""
|xmlns:xs=""http://www.w3.org/2001/XMLSchema""
|xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
|xsi:type=""Model"">
|<package targetNamespace=""sample-my-package"">
|<valueType name=""testtypes"" base=""xs:string"">
|<pattern>" + Фасет + "</pattern>
|</valueType>
|<objectType name=""TestObj"">
|<property xmlns:d4p1=""sample-my-package"" name=""TestItem"" type=""d4p1:testtypes""/>
|</objectType>
|</package>
|</Model>");
Модель = ФабрикаXDTO.ПрочитатьXML(Чтение);
МояФабрикаXDTO = Новый ФабрикаXDTO(Модель);
Пакет = МояФабрикаXDTO.Пакеты.Получить("sample-my-package");
Тест = МояФабрикаXDTO.Создать(Пакет.Получить("TestObj"));
Попытка
Тест.TestItem = Строка;
Возврат Истина
Исключение
Возврат Ложь
КонецПопытки;
КонецФункции
Функция ЧислоВДату(Число)
Возврат Дата(1970,1,1,1,0,0)
+ ?(Число>64060502400 // Если UnixTime передано с милисекундами
, Число/1000
, Число);
КонецФункции
// Проверка частей даты
Функция ЭтоГод(Число) Возврат Число<4000 И Число>0 КонецФункции
Функция ЭтоМесяц(Число) Возврат Число<13 И Число>0 КонецФункции
Функция ЭтоЧас(Число) Возврат Число<25 И Число>=0 КонецФункции
Функция ЭтоМинута(Число) Возврат Число<60 И Число>=0 КонецФункции
Функция ЭтоСекунда(Число) Возврат Число<60 И Число>=0 КонецФункции
Функция ЭтоДень(Число, Месяц = 1, Год = 1)
Возврат ?(ЭтоГод(Год) И ЭтоМесяц(Месяц)
, Число<=День(КонецМесяца(Дата(Год, Месяц, 1))) И Число>0
, Ложь);
КонецФункции
#КонецОбласти
#Область Регулярное_выражение
Процедура РегулярноеВыражение(Знач Строка, Шаблон)
Строка = Строка(Строка);
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;
RegExp.MultiLine = Истина;
RegExp.Pattern = Шаблон;
Matches=RegExp.Execute(Строка);
Для Счетчик = 0 По Matches.Count()-1 Цикл
Match = Matches.Item(Счетчик);
Сообщить(Match.Value);
КонецЦикла;
КонецПроцедуры
#КонецОбласти
#КонецОбласти
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment