уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Про то, как используются такие хэлперы я рассказывал буквально недавно, так что повторяться особенно не буду. Скажу только, что те хэлперы которые я собрал особенно нового ничего не привносят в работу с 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.

Вот такой получился небольшой модуль с хэлперами.

Скачать исходник: Исходники —> Прочие
5 1 голос
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
7 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
IL
IL
24/09/2012 11:00

Завести бы под это дело открытый репозиторий на 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, нашлось бы много желающих их использовать. А так придется отложить до нескорого апгрейда.

mopsicus
24/09/2012 13:30

Спасибо! Пригодится

loginzaMeuN4POMA5k1drbP8ZQVx
loginzaMeuN4POMA5k1drbP8ZQVx
24/09/2012 17:45

10.Init(DoubleVar) — выглядит конечно очень интуитивно понятно, но IMHO гораздо лучше так: doubleVar.RoundToInt.ToString

Николай Зверев
24/09/2012 18:59

Пробежал пост по диагонали. Мне не понравилось:
а) 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
ter
01/10/2012 13:14

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