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

Выдалась под вечер свободная минутка и решил немного покодить. В целом проблем с вопросом «Что кодить?» не возник, т.к. открытых тем в блоге валом,но решил продолжить работы над Google API. Когда начинал работу над Google Celendar API, то совершенно упустил из виду простой, но вместе с тем полезный модуль. Молуль, содержащий вспомогательные величины, константы, ресурсные строки и т.д. для работы с API  в целом. Чертовски неудобно и нехорошо каждый раз в кажом модуле вспоминать про то, что забыл перевести текст описания ошибки и втукать в модуль новую ресурсную строку или константу. Поэтому, раз времени не так и много осталось до завра, а завтра — снова в бой (на работу), покой нам только снится, то решил заняться именно работой над вспомогательным модулем. Назовем модуль, например GHelper…незнаю почему, но это первое, что пришло в голову.

Первая «проблема» с которой я столкнулся при работе с Google Data — это формат представления даты.  Любая дата в Google API имеет следующий вид, например:

2006-01-23T16:28:05

Что соответствует RFC 3339 и означает:

23 января 2006 года время 16:28:05

После этой даты может стоять, например количество миллисекунд или часовой пояс или и то и другое вместе взятое. Наша цель — выделить дату и время. Первая функция преобразует время из формата RFC 3339 в формат Delphi:

function ServerDateToDateTime(cServerDate:string):TDateTime;
var Year, Mounth, Day, hours, Mins, Seconds: Word;
begin
  Year:=StrToInt(copy(cServerDate,1,4));
  Mounth:=StrToInt(copy(cServerDate,6,2));
  Day:=StrToInt(copy(cServerDate,9,2));
  hours:=StrToInt(copy(cServerDate,12,2));
  Mins:=StrToInt(copy(cServerDate,15,2));
  Seconds:=StrToInt(copy(cServerDate,18,2));
  Result:=EncodeDateTime(Year, Mounth, Day, hours, Mins, Seconds,0)
end;

Вторая функция производит обратное преобразование (с учётом миллисекунд):

function DateTimeToServerDate(DateTime:TDateTime):string;
begin
 Result := FormatDateTime('yyyy-mm-ddThh:nn:ss.zzzZ', DateTime);
end;

В принципе миллисекунда нам особо не важны, поэтому часть кода можно будет, в случае чего, убрать.
С этим вроде бы разобрались — теперь можно спокойно читать дату-время и перегонять из одного представления в другое. Двигаемся дальше. В Google Celendar API есть возможность назначать календарям определенный цвет. Причем цвет выбирается из чётко определенного набора из 21 цвета. Незнаю как Вам, а мне лично будет лень каждый раз заглядывать в документацию с целью узнать какой цвет можно использовать, а какой нет. Поэтому создал небольшой массив-констант, где каждый элемент — доступный в Google API цвет в формате HEX:

GoogleColors: array [1..21]of string = ('A32929','B1365F','7A367A','5229A3',
                                        '29527A','2952A3','1B887A','28754E',
                                        '0D7813','528800','88880E','AB8B00',
                                        'BE6D00','B1440E','865A5A','705770',
                                        '4E5D6C','5A6986','4A716C','6E6E41', '8D6F47');

В случае надобности, можно всегда перевести цвет из HEX в TColor и обратно двумя простыми функциями:

function HexToColor(Color: string): TColor;
begin
  Result :=
    RGB(
    StrToInt('$' + Copy(Color, 1, 2)),
    StrToInt('$' + Copy(Color, 3, 2)),
    StrToInt('$' + Copy(Color, 5, 2))
    );
end;
function ColorToHex(Color: TColor): string;
begin
  Result :=
  IntToHex(GetRValue(Color), 2 ) +
  IntToHex(GetGValue(Color), 2 ) +
  IntToHex(GetBValue(Color), 2 );
end;

С цветами вроде бы тоже все понятно. В любой момент массив можно увеличить. Но это всё мелочи, по сравнению с последним набором констант,используемым в Google API — константы, используеые в Google Celendar API для определения часового пояса и местоположения пользователя. Всего в Google API используется 309 констант. Каждая константа определяет часовой пояс и местоположение. Я не стал долго мудрить, а просто нашел эти константы в исходнике HTML-странички настроек календаря и накидал процедурку, которая спарсит эти константы и представит в виде массива, где каждый элемент выглядит так:

('Pacific/Guadalcanal','(GMT+11:00) Гвадалканал','+11,00','')

то есть:
первый элемент — константа, используемая в протоколе Google Data
второй элемент — текстовое описание для пользователя
третий элемент — часовой пояс
четверты элемент — зарезервировал на всякий случай, например сейчас забил в этот элемент строку ru для определения того относится ли константа к России или нет.
Пользоваться каждый раз массивом на 309 строк…по-ходу будет гемморно. Поэтому решил немного поработать с TList. Вот, что у меня получилось в итоге (чур сильно не пинать, т.к. это мой первый опыт работы с TList :)):

type
 TTimeZone = packed record
   gConst: string;
   Desc : string;
   GMT: extended;
   rus: boolean;
end;
 
type
  PTimeZone = ^TTimeZone;
 
type
  TTimeZoneList = class(TList)
  private
    procedure SetRecord(index: Integer; Ptr: PTimeZone);
    function GetRecord(index: Integer): PTimeZone;
  public
    constructor Create;
    procedure Clear;
    destructor Destroy; override;
    property TimeZone[i: Integer]: PTimeZone read GetRecord write SetRecord;
  end;
 
procedure TTimeZoneList.Clear;
var
  i: Integer;
  p: PTimeZone;
begin
  for i := 0 to Pred(Count) do
  begin
    p := TimeZone[i];
    if p <> nil then
      Dispose(p);
  end;
  inherited Clear;
end;
 
constructor TTimeZoneList.Create;
var i:integer;
    Zone:PTimeZone;
begin
  inherited Create;
  for i:=0 to High(GoogleTimeZones) do
    begin
      New(Zone);
      with Zone^ do
       begin
         gConst:=GoogleTimeZones[i,0];
         Desc:=GoogleTimeZones[i,1];
         GMT:=StrToFloat(GoogleTimeZones[i,2]);
         rus:=GoogleTimeZones[i,2]='rus';
       end;
       Add(Zone);
    end;
end;
 
destructor TTimeZoneList.Destroy;
begin
 Clear;
 inherited Destroy;
end;
 
function TTimeZoneList.GetRecord(index: Integer): PTimeZone;
begin
  Result:= PTimeZone(Items[index]);
end;
 
procedure TTimeZoneList.SetRecord(index: Integer; Ptr: PTimeZone);
var
  p: PTimeZone;
begin
  p := TimeZone[index];
  if p <> Ptr then
  begin
    if p <> nil then
      Dispose(p);
    Items[index] := Ptr;
  end;
end;

Т.е. пока в список грузятся все константы из массива и при необходимости выбираются из списка требуемые данные. Попробовал использовать это «чудо в перьях» — вроде бы все работает нормально, хотя уверен тут можно что-нибудь и улучшить.
Вот примерно такое начало положено по работе с константами и данными Google API. Пока этого модуля должно хватить для работы с Календарем, поэтому в следующий раз продолжим разбирать Google Celendar API. А на сегодня все ;)

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
3 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
lol
lol
11/02/2010 22:30

Гы, знакомое лицо на фотке :D
Нашёл кого вешать в программерский блог. Котов надо! :))))

Павел
Павел
16/02/2010 13:00

ох, а девушка та какая шикарная, отвлекает немного от статьи,  а так интересно:)