Подписка

добавить на Яндекс

Наши проекты

Delphi+Google

Google API

Google API в Delphi - проект с открытым исходным кодом.

Chrono

Chrono

Хронометр - программа для ведения списка задач.

ODFProc

ODFProc

ODFProc - работа с документами OpenOffice в Lazarus и FreePascal.

Поддержка блога

А тут я коплю на лицензию Delphi XE на iPad =).
Сумма пожертвования не фиксирована.

Публикации

Год назад

Случайный пост

Последние

Сообщения форума

Комментарии

Социальные сети

Google

Facebook

Twitter

Опрос

Вы сейчас или в ближайшем обозримом будущем планируете разрабатывать кроссплатформенное приложение с использованием Firemonkey?



Loading ... Loading ...

Блоги и сообщества

Статьи по Delphi DelphiFeeds.ru - Все Delphi-блоги Рунета Сообщество умных людей VR-Online.RU Бесплатный журнал для программистов и всех, кто интересуется IT Статьи и уроки по Delphi Новостной блог о высоких технологиях
Система Orphus
Опубликовал Vlad 11 февраля 2010 в 19:51.
Категории: Delphi в Web.


Выдалась под вечер свободная минутка и решил немного покодить. В целом проблем с вопросом "Что кодить?" не возник, т.к. открытых тем в блоге валом,но решил продолжить работы над 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;
var Year, Mounth, Day, hours, Mins, Seconds,MSec: Word;
    aYear, aMounth, aDay, ahours, aMins, aSeconds,aMSec: string;
begin
  DecodeDateTime(DateTime,Year, Mounth, Day, hours, Mins, Seconds,MSec);
  aYear:=IntToStr(Year);
  if Mounth<10 then aMounth:='0'+IntToStr(Mounth)
  else aMounth:=IntToStr(Mounth);
  if Day<10 then aDay:='0'+IntToStr(Day)
  else aDay:=IntToStr(Day);
  if hours<10 then ahours:='0'+IntToStr(hours)
  else ahours:=IntToStr(hours);
  if Mins<10 then aMins:='0'+IntToStr(Mins)
  else aMins:=IntToStr(Mins);
  case MSec of
    0..9:aMSec:='00'+IntToStr(MSec);
    10..99:aMSec:='0'+IntToStr(MSec);
    else
      aMSec:=IntToStr(MSec);
  end;
  Result:=aYear+'-'+aMounth+'-'+aDay+'T'+ahours+':'+aMins+':'+aSeconds+'.'+aMSec+'Z';
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. А на сегодня все ;)

---------------------------------
Каждый мужчина помима написания книги и т.д. должен построить дом. Специалисты из www.project-st.ru проектируют "Умные" Дома.

В прошлом посте я упоминал перчатки...сегодня предлагаю купить куртку аляску из Америки, ну или, если куртка есть, то здесь приобрести крутой ремень :)
---------------------------
Понравилась статья? Тогда:
Делись! Загружай! Плюсуй!
   Отправить PDF на   
Читай ещё статьи на WebDelphi.ru

Комментарии (4)

WP_Cloudy
  • lol пишет:

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

  • lol пишет:

    Ах, да: помимо сисечек хотелось отметить ещё местами страшный код :) Например, DateTimeToServerDate можно было написать так:

    function DateTimeToServerDate(const DateTime: TDateTime): String;
    begin
    Result := FormatDateTime(‘yyyy»-»mm»-»dd»T»hh»:»nn»:»ss».»zzz»Z»‘, DateTime);
    end;

  • Vlad пишет:

    По поводу картики…это человеческий облик Гугла для потенциальных рекламодателей :)
    За «страшнй код» спасибо :) Всмысле спасибо, что не поленились выложить в коммент ещё один вариант функции более компактный и красивый.

  • Павел пишет:

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

Ваш ответ

Внимание: Все комментарии модерируются, и это может вызвать задержку их публикации. Отправлять комментарий заново не требуется.

Пожалуйста, заключайте исходный код в тэги [code][/code].
Если код большой, то воспользуйтесь Вставкой кода на отдельной странице и оставьте в комментарии ссылку на исходник