Выдалась под вечер свободная минутка и решил немного покодить. В целом проблем с вопросом «Что кодить?» не возник, т.к. открытых тем в блоге валом,но решил продолжить работы над 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. А на сегодня все ;)
Гы, знакомое лицо на фотке :D
Нашёл кого вешать в программерский блог. Котов надо! :))))
По поводу картики…это человеческий облик Гугла для потенциальных рекламодателей :)
За «страшнй код» спасибо :) Всмысле спасибо, что не поленились выложить в коммент ещё один вариант функции более компактный и красивый.
ох, а девушка та какая шикарная, отвлекает немного от статьи, а так интересно:)