Практика
Работа с датой и временем в Delphi

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика


Стандартный тип дата-время - TDateTime, определенный в модуле System, представляет собой вещественное число типа Double, целая часть которого задает число дней (в том числе и отрицательное), прошедших с 30 декабря 1899 г., а дробная часть - прошедшую долю текущего дня. Так, 35065.75 дает 1 января 1996 г., 18.00. Следует иметь в виду, что символьное представление даты-времени определяется региональной установкой Windows. Здесь под региональной установкой понимается следующее. В разных странах даты, время, а также вещественные числа записываются по-разному. Например, в одних странах в вещественных десятичных числах дробная часть отделяется от целой точкой, а в других - запятой (так, кстати, обозначаются десятичные числа и в нашей стране, однако пользоваться такой записью в тексте самой программы, написанной на Object Pascal, нельзя). По-разному записываются дата и время. Windows позволяет привести символьное представление таких параметров в соответствие с принятыми в данной стране правилами. Delphi может использовать эти установки для соответствующего представления таких параметров. Так, для России следует вводить информацию о дате и времени в виде dd.MM.yy H:mm:ss, где dd - день месяца; ММ - месяц; уу - год; Н - часы; mm - минуты; ss - секунды.

При задании значения даты-времени следует обратить внимание не только на сами значения, но и на знаки препинания. Несущественные части даты-времеи (например, секунды, минуты, часы) можно справа отбросить. В этом случае считается, что соответствующая часть равна нулю. Если в дате-времени отброшено еще и значение года, считается, что имеется в виду текущий год. Обычно тип дата-время используется в параметрах вариантного типа как один из допустимых вариантов, но может использоваться и самостоятельно для фиксации информации о времени.

Примечание. Следует иметь в виду, что при записи года двумя последними цифрами фактический год зависит от текущего года и глобальной переменной заданной в Delphi - TwoDigitYearCenturyWindow. По умолчанию эта переменная имеет значение, равное 50, что означает, что в конце этого столетия и начале следующего задаваемые двумя цифрами годы будут относиться к XX в., если число несколько больше 50, и к XXI в., если число несколько меньше 50.

В модуле SysUtils определен ряд стандартных функции работы с параметрами типа даты-времени.

  • Time - текущее время. Функция возвращает текущее значение времени в формате TTime.
  • Date - текущая дата. Функция возвращает текущее значение даты в формате TDate.
  • Now - текущая дата и время. Функция возвращает текущее значение даты и времени в формате TDateTime.
  • DateTimeToStr(DateTime) - символьное представление даты и времени. Функция формирует для параметра DateTime типа TDateTime символьное представление даты и времени с учетом региональной установки Windows и возвращает полученную строку в качестве результата своей работы.
  • DateTimeToString(Result, Format, DateTime) - сформатированное символьное представление даты и времени. Процедура формирует символьное представление параметра DateTime типа TDateTime с учетом формата, заданного строкой Format, и помещает результат в строку Result.
  • DateToStr(Date) - символьное представление даты. Функция формирует для параметра Date типа TDateTime или TDate символьное представление даты с учетом региональной установки Windows и возвращает полученную строку в качестве результата своей работы.
  • DayOfWeek(Date) - день недели. Функция возвращает день недели заданной даты Date типа TDateTime или TDate в виде числа от 1 до 7, причем нумерация начинается с воскресенья.
  • TimeToStr(Time) - символьное представление времени. Функция формирует для параметра Time типа TDateTime или TTime символьное представление времени с учетом региональной установки Windows и возвращает полученную строку в качестве результата своей работы.
  • DecodeDate(Date, Year, Month, Day) - выделение в дате года, месяца, дня. Процедура выделяет из параметра Date типа TDateTime или TDate год, месяц, день и помещает их соответственно в параметры Year, Month и Day типа Word.
  • DecodeTime(Date, Hour, Min, Sec, MSec) - выделение во времени часа, минуты, секунды и числа миллисекунд. Процедура выделяет из параметра Date типа TDateTime или TTime час, минуту, секунду и число миллисекунд и помещает их соответственно в параметры Hour, Min, Sec и MSec типа Word.
  • EncodeDate(Year, Month, Day) - формирование даты из компонент. Функция формирует из заданного года, месяца и дня (заданных в параметрах Year, Month, Day) комплексный параметр типа TDateTime и возвращает его как результат работы.
  • EncodeTime(Hour, Min, Sec, MSec) - формирование времени из компонент. Функция формирует из заданных часа, минуты, секунды и числа миллисекунд (заданных в параметрах Hour, Min, Sec, MSec) комплексный параметр типа TDateTime и возвращает его как результат работы.
  • FormatDateTime(Format, DateTime) - сформатированное символьное представление даты и времени. Функция формирует символьное представление параметра DateTime типа TDateTime с учетом формата, заданного строкой Format, и возвращает полученную строку как результат своей работы.
  • StrToDate(S) - преобразование символьного представления даты в тип TDateTime. Функция преобразовывает символьное представление даты, находящееся в строке S, в формат TDateTime или TDate и возвращает полученную величину как результат своей работы. Дата должна быть задана в соответствии с региональной установкой Windows.
  • StrToTime(S) - преобразование символьного представления времени в тип TDateTime. Функция преобразовывает символьное представление времени, находящееся в строке S, в формат TDateTime или TTime и возвращает полученную величину как результат своей работы. Время должно быть задано в соответствии с региональной установкой Windows.
  • StrToDateTime(S) - преобразование символьного представления даты и времени в тип TDateTime. Функция преобразовывает символьное представление даты и времени, находящееся в строке S, в формат TDateTime и возвращает полученную величину как результат своей работы. Дата и время должны быть заданы в соответствии с региональной установкой Windows.
Тепеть разберем некоторые функции на примерах.

DateTimeToString
procedure TForm1.Button1Click(Sender: TObject);
const
  DateTimeFormat: array[1..30] of string =
     ( 'd', 'dd', 'ddd', 'dddd', 'ddddd',
       'dddddd', 'e', 'ee', 'm', 'mm',
       'mmm', 'mmmm', 'yy', 'yyyy', 'h',
       'hh', 'n', 'nn', 's', 'ss', 'z',
       'zzz', 't', 'tt', 'am/pm', 'a/p',
       'dd.mm.yy hh:mm:ss',
       'am/pmhh:mm:ss dd.mm.yyyy',
       'dd.mmm.yyyy', 'dd mmmm yyyy' );
var
  i: integer;
  s, str: string;
  dt: TDateTime;
begin
   dt := Now;
   for i := 1 to 30 do
   begin
      DateTimeToString( s, DateTimeFormat[i], dt );
      str := str + s + #13;
   end;
   ShowMessage( str );
end;

DateTimeToStr
procedure TForm1.Timer1Timer(Sender: TObject);
var
  DT: TDateTime;
begin
   DT := Now;
   Form1.Caption := DateTimeToStr( DT );
end;

DateToStr
procedure TForm1.Timer1Timer(Sender: TObject);
var
  MyDate: TDate;
begin
   MyDate := Date;
   Form1.Caption := DateToStr( MyDate );
end;

TimeToStr
procedure TForm1.Timer1Timer(Sender: TObject);
var
  MyTime: TTime;
begin
   MyTime := Time;
   Form1.Caption := TimeToStr( MyTime );
end;

А сейчас попробуем написать часы, применяя описанные выше процедуры и функции. С созданием цифровых часов не должно возникнуть никаких проблем, а вот с аналоговыми нужно повозиться. Но мы, как настоящие программисты, не боимся трудностей, и возьмемся за реализацию этой задачи. И первое, что мы сделаем при запуске программы, узнаем координаты центра часов и вычислим радиус.

procedure TForm1.FormCreate(Sender: TObject);
begin
   x := PaintBox1.Width div 2;
   y := PaintBox1.Height div 2;
   if x > y then
      radius := y - 5
   else
      radius := x - 5;
end;

Обновлять информацию о времени будем, используя таймер, и сделаем возможность запуска/остановки часов. Запускать и останавливать таймер будем следующей процедурой.

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
   if Timer1.Enabled then
   begin
      BitBtn1.Kind := bkIgnore;
      BitBtn1.Caption := 'Пуск';
      Timer1.Enabled := not Timer1.Enabled;
   end
   else
   begin
      BitBtn1.Kind := bkCancel;
      BitBtn1.Caption := 'Стоп';
      Timer1.Enabled := not Timer1.Enabled;
   end;
end;

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

procedure TForm1.Timer1Timer(Sender: TObject);
const
  MyFormat = 'dd.mmmm.yyyy hh:mm:ss';
var
  MyTime: TTime;
  MyDate: TDate;
  DT: TDateTime;
begin
   MyDate := Date;
   Panel3.Caption := DateToStr( MyDate );
   MyTime := Time;
   DecodeTime( MyTime, H, M, S, MS );
   Panel2.Caption := TimeToStr( MyTime );
   DrawAnalogClock;
   DT := Now;
   StatusBar1.Panels.Items[0].Text := 'Полный формат даты: ' + FormatDateTime( MyFormat, DT );
end;

А вот и сама процедура рисования аналоговых часов.

procedure TForm1.DrawAnalogClock;
var
  i: integer;
begin
   // Круг циферблата
   PaintBox1.Canvas.Pen.Width := 2;
   PaintBox1.Canvas.Ellipse( x - radius,
                             y - radius,
                             x + radius,
                             y + radius );
   // Деления на циферблате
   for i := 1 to 60 do
      with PaintBox1.Canvas do
      begin
         if i mod 5 = 0 then
         begin
            // Каждое пятое деление рисуем длиннее и жирнее
            Pen.Width := 3;
            MoveTo( x + Round( ( radius - 8 ) * cos( 6*i*3.14/180 ) ),
                    y - Round( ( radius - 8 ) * sin( 6*i*3.14/180 ) ) );
         end
         else
         begin
            Pen.Width := 1;
            MoveTo( x + Round( ( radius - 5 ) * cos( 6*i*3.14/180 ) ),
                    y - Round( ( radius - 5 ) * sin( 6*i*3.14/180 ) ) );
         end;
         LineTo( x + Round( ( radius ) * cos( 6*i*3.14/180 ) ),
                 y - Round( ( radius ) * sin( 6*i*3.14/180 ) ) );
      end;

   with PaintBox1.Canvas do
   begin
      Pen.Width := 2;
      // Секундная стрелка
      MoveTo( x, y );
      LineTo( x - Round( ( radius - 10 ) * cos( 6*S*3.14/180+3.14/2 ) ),
              y - Round( ( radius - 10 ) * sin( 6*S*3.14/180+3.14/2 ) ) );
      // Минутная стрелка
      MoveTo( x, y );
      if not Smoothly.Checked then
         // Здесь минутная стрелка движется "рывками"
         LineTo( x - Round( ( radius - 25 ) * cos( 6*M*3.14/180+3.14/2 ) ),
                 y - Round( ( radius - 25 ) * sin( 6*M*3.14/180+3.14/2 ) ) )
      else
         // Здесь минутная стрелка движется плавно
         LineTo( x - Round( ( radius - 25 ) * cos( ( 6*M+6*S/60 ) * 3.14/180+3.14/2 ) ),
                 y - Round( ( radius - 25 ) * sin( ( 6*M+6*S/60 ) * 3.14/180+3.14/2 ) ) );
      // Часовая стрелка
      MoveTo( x, y );
      LineTo( x - Round( ( radius - 45 ) * cos( 30*H*3.14/180+3.14/2 ) ),
              y - Round( ( radius - 45 ) * sin( 30*H*3.14/180+3.14/2 ) ) );
   end;
end;

Из примера видно, что сделать часы, в том числе и аналоговые, не представляет из себя ничего сложного. Я думаю, не возникнет больших проблем при разборе данного примера.

.: Пример к данной статье :.


При использовании материала - ссылка на сайт обязательна