Про то, как используются такие хэлперы я рассказывал буквально недавно, так что повторяться особенно не буду. Скажу только, что те хэлперы которые я собрал особенно нового ничего не привносят в работу с Integer, Char и TDateTime — просто немного упрощают работу с этими типами в Delphi XE3 и избавляют от написания некоторых функций преобразования.
Думаю, что этот модуль может оказаться полезен тем разработчикам, которые часто работают с API различных онлайн-сервисов типа Google Calendar где часто приходится переводить строковые значения, парсить текст на предмет различных цифр, дат, переводить время в локальное, UTC и т.д. и т.п.
Record helper for integer
Описание
type TInt32Helper = record helper for integer public function Equals(Value: integer):boolean; function ToString:string; function ToHex(Digits:integer): string; function Init(Value: double):integer;overload; function Init(Value: double; ToCeil:boolean):integer;overload; procedure Parse(const Value: string);overload; procedure Parse(const Value: string; Pos: integer);overload; end;
Из приведенного описания класса некоторого пояснения заслуживает разве, что последние два метода — Init и Parse.
function Init(Value: double):integer;overload; function Init(Value: double; ToCeil:boolean):integer;overload;
Присваивает переменной типа Integer новое значение, округляя параметр Value.
Первый вариант функции использует для округления метод Round. Например:
var i:integer; begin WriteLn(i.Init(2.7).ToString);//получим на выходе "3" end;
Второй вариант функции, в зависимости от параметра ToCeil округляет Value либо до ближайшего большего, либо меньшего значения и, соответственно, для округления использует либо метод Ceil, либо Floor. Например:
var i:integer; begin WriteLn(i.Init(2.7,True).ToString);//использует для округления Ceil и вернет значение 3 WriteLn(i.Init(2.7,False).ToString);//использует для округления Floor и вернет значение 2 end;
Следующая пара функций:
function Parse(const Value: string):integer;overload; function Parse(const Value: string; Pos: integer):integer;overload;
парсит строку и получает из неё целые числа. Функция работает следующим образом:
- передаваемая в Value строка может состоять из любого количества любых символов, в т.ч. может и не одержать ни одной цифры;
- если в строке не найдено ни одной цифры, то функция вернет значение -1;
- функция «понимает» знаки «+» и «-«, которые могут стоять перед числом;
- функция принимает за результат любую последовательность вида {знак}{любое_количество_цифр}. Если строка, содержит число, выходящее за диапазон -2147483648..2147483647, то функция вернет значение -1;
- если в функцию передается строка, содержащая число с плавающей точкой, то дробная часть числа при парсинге отсекается без округления
- если в функцию передается строка, содержащая несколько чисел, то overload-версия функции может получить число, содержащееся под номером Pos в строке
Теперь несколько примеров использования этой функции:
var i:integer; begin WriteLn(i.Parse('Минимальное значение для Integer равно -2147483648').ToString); //-2147483648 WriteLn(i.Parse('Это число выходит за диапазон для Integer 2147483649').ToString);//-1 WriteLn(i.Parse('В строке нет "+" - 214 положительное число').ToString); //214 WriteLn(i.Parse('А так будет отрицательное число - -----214, а лишние - "обрубятся" ').ToString);//-214 WriteLn(i.Parse('Число -214.45555 преобразуется в -214').ToString); //-214 //overload WriteLn(i.Parse('-214.45555.12345 - здесь три числа и второе равно....', 2).ToString);//45555 WriteLn(i.Parse('Первое число -2, второе +4, третье -5', 1).ToString); //-2 WriteLn(i.Parse('Первое число -2, второе +4, третье -5', 2).ToString); //4 WriteLn(i.Parse('Первое число -2, второе +4, третье -5', 3).ToString); //-5 WriteLn(i.Parse('Первое число -2, второе +4, третье -5', 4).ToString); //-1 т.к. чисел всего три end
Record helper for Char
Здесь все уже было фактически готово, ещё, если мне не изменяет память, в Delphi 2009 — в модуле Character. Соответственно и хэлпер использует методы из этого модуля со всеми их (методов) достоинствами и недостатками. Поэтому приведу просто описание класса без пояснения того, что делает каждый из методов:
TCharHelper = record helper for char function IsControl: boolean; function IsDigit: boolean; function IsHighSurrogate: boolean; function IsLetter: boolean; function IsLetterOrDigit: boolean; function IsLower: boolean; function IsLowSurrogate: boolean; function IsNumber: boolean; function IsPunctuation: boolean; function IsSeparator: boolean; function IsSurrogate: boolean; function IsSymbol: boolean; function IsUpper : boolean; function IsWhiteSpace: boolean; function ToLower: Char; function ToUpper: Char; function NumericValue: Double; function UnicodeCategory(C: Char): TUnicodeCategory; function Replicate(Count: integer):string; end;
Тем, кто не знаком с классом TCharacter — ссылочка на небольшой пост по теме.
Record helper for TDateTime
Основное назначение этого хэлпера можно определить так — преобразование строк, содержащих различные формы записи даты/времени в TDateTime. Конечно, я не ставил перед собой целью «вбить» в хэлпер абсолютно все формы записи даты/времени, т.к. чего только стоит таблица с форматами ISO, однако те формы записи, которые мне встречались наиболее часто в хэлпере используются. Итак, как выглядит сам хэлпер:
TDateTimeHelper = record helper for TDateTime private function MatchIndex(const DTString: string):integer; function ISODateTimeToDateTime(const ISODateTime: string):TDateTime; function SQLiteDateTimeToDateTime(const SQLiteDateTime: string):TDateTime; public function SetFromString(const ADateTimeStr: string):TDateTime;overload; function SetFromString(const ADateTimeStr; AFormat: TFormatSettings):TDateTime;overload; function SystemToUTC: TDateTime; function UTCToSystem: TDateTime; function ToString: string;overload; function ToString(AFormat: string): string;overload; end;
Методы хэлпера работают следующим образом:
function SetFromString(const ADateTimeStr: string):TDateTime;overload; function SetFromString(const ADateTimeStr; AFormat: TFormatSettings):TDateTime;overload;
Устанавливают новое значение, полученное из строки ADateTimeStr для переменной.
function SetFromString(const ADateTimeStr; AFormat: TFormatSettings):TDateTime;overload;
Использует для преобразования метод StrToDateTime. Как работает StrToDateTime можно почитать, например, здесь или прямо в модуле SysUtils, где этот метод реализован.
function SetFromString(const ADateTimeStr: string):TDateTime;overload;
Преобразует строку содержащую дату/время в формате ISO или формате, используемом при работе с БД SQLite. Поддерживаются следующие форматы записи:
- YYYY-MM-DD
- YYYY-MM-DDTHH:MMZ
- YYYYMMDDTHHMMZ
- YYYY-MM-DDTHH:MM:SS.ZZZZ+HH:MM
- YYYYMMDDTHHMMSS
- YYYY-MM-DD HH:MM
- YYYY-MM-DD HH:MM:SS
- YYYY-MM-DD HH:MM:SS.SSS
- YYYY-MM-DDTHH:MM
- YYYY-MM-DDTHH:MM:SS
- YYYY-MM-DDTHH:MM:SS.SSS
Пример:
var dt:TDateime; begin WriteLn(dt.SetFromString('20121212T0300').ToString);//12.12.2012 03:00:00 WriteLn(dt.SetFromString('20121212T0300').ToString('yyyy, ddd, mmm hh:mm:ss:zzz'))//2012, Ср, дек 03:00:00:000 end;
Собственно, в примерах выше представлен и пример использования метода ToString.
function SystemToUTC: TDateTime;
Преобразует текущее значение переменной к времени UTC.
function UTCToSystem: TDateTime;
Преобразует текущее значение переменной в системное время (местное). SystemToUTC и UTCToSystem не записывают полученное значение в переменную в отличие от SetFromString.
Вот такой получился небольшой модуль с хэлперами.
Завести бы под это дело открытый репозиторий на github.
Кстати, TDateTimeHelper там недавно завели https://github.com/colinj/TDateTimeHelper хотя функционал другой.
Обсуждение здесь http://blogs.embarcadero.com/michaelswindell/2012/09/15/34860/
Может быть удастся их объединить? Кстати, если есть хэлперы с одинаковыми именами, то будут ли они одновременно доступны типу, например,
uses Colin.DateTimeHelper, Vlad.DateTimeHelper;
Now.EndOfMonth.SystemToUTC.ToString;
Если бы Embarcadero портировало хелперы типов в XE2, нашлось бы много желающих их использовать. А так придется отложить до нескорого апгрейда.
IL, я пробовал в свой модуль добавить record helper for string — после этого «родной» хэлпер стал недоступен, хотя имена были разные. На GitHub’е, как я понял, хэлпер реализует в основном методы из DateUtils — в принципе добавить их в хэлпер не составит большого труда =)
Спасибо! Пригодится
10.Init(DoubleVar) — выглядит конечно очень интуитивно понятно, но IMHO гораздо лучше так: doubleVar.RoundToInt.ToString
Пробежал пост по диагонали. Мне не понравилось:
а) i.Init(2.7).ToString //получим на выходе «3»
ИМХО — не инутитивно, что 2.7 будет округлено. Интуитивнее Round(2.7).ToString
б) Init(2.7,True) / Init(2.7,False) — аналогично, зачем? И так есть Ceil и Floor, подменять всем изместные функции магическим Init?
в) i.Parse(‘Это число выходит за диапазон для Integer 2147483649’).ToString);//-1
i.Parse(‘Первое число -2, второе +4, третье -5’, 4).ToString); //-1 т.к. чисел всего три
выдавать -1 в результат — плохо. Лучше генерить исключение. Хотя как пример того, что можно делать в хелперах — интересно.
Влад, рекорд и класс хелпер для типа может быть только один согласно документации. Так что не мудрено что после добавления своего родной перестает работать.
ter, вот это вот и жалко, что «согласно документации» =) Было б неплохо взять и «допилить» тот же TStringHelper чуток под свои нужды