Генератор случайных дат

Дата публикации

На моем сайте есть материал про то, как генерировать числа. Анализируя статистику сайта, я обратил внимание на то, что многие попадают на эту статью, разыскивая генератор дат. Так давайте сделаем такое приложение, чтобы пользователи не покидали мой ресурс недовольными.

Скачать готовое приложение можно тут.

В воде разработки генератора дат мы научимся:

  • В компоненте DateTimePicker  избавляться от времени (В TDateTime оставить только дату).
  • Находить разность между двумя датами.
  • Прибавлять к дате дня, часы, минуты и секунды.

Давайте поймем, как реализовать вышестоящие пункты, после этого мы без труда напишем программу-генератор дат.

Для начала хотелось бы сказать пару с лов о типе, в котором хранится дата и время – это тип TDateTime. TDateTime, по факту, обыкновенный Double (число с плавающей точной).  На примере станет все ясно:

Число 41813,3983375463 не что иное, как  23.06.2014 9:33:36.  Все, что до запятой – это год месяц и день (в 41813 хранится 23.06.2014). Все, что после запятой отвечает за часы, минуты секунды и тд. 0,3983375463 – это 9:33:36.

 

В DateTimePicker оставить только дату.

Это достаточно простая манипуляция. Для этого всего на всего в свойстве Time необходимо поставить 0. В общем случае, чтобы избавиться от времени в TDateTime нужно выделить целую часть. Приведу пример, где мы получаем текущую дату и время, после чего от времени избавляемся (Получить текущую дату без времени Delphi).

var
  T: TDatetime;
begin
  T:= Now();
  T:=Int(T)
end;

 

Разность между двумя датами

В Delphi предусмотрено много процедур и функций для работы с временем. Многие из них описаны в модуле DateUtils. Одна из таких функций возвращает разницу между двумя датами в днях – DaysBetween.

function DaysBetween(const ANow, AThen: TDateTime): Integer;

Как параметры нужно передать две даты, на выходе получаем целое число.

 

Как изменить дату на день, час, минуту, секунду

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

Чтобы прибавить час нужно сложить дату с единицей, деленной на 24 (в сутках 24 часа) и так далее по аналогии.  В примере, к текущей дате прибавим день, час, минуту и секунду.

var
  T: TDatetime;
begin
  T:= Now();
  T:=T+1; // Прибавляем день
  T:=T+1/24;  // Прибавляем час
  T:=T+1/1440; // Прибавляем минуту
  T:=T+1/86400; // Прибавляем секунду
end;

 

Генератор дат

Теперь можно приступить к написанию генератора дат.  Программа будет генерировать нужное количество дат в выбранном временном интервале. При желании можно будет генерировать дату с временем. Накидаем форму. У меня получилось так:

Generator dat

На форме расположены компоненты: 2 DateTimePicker,  button, Checkbox, Edit, ListBox, label, UpDown. Произведем настройки:  У обоих DateTimePicker установите свойство Time = 0:00:00, для этого просто впишите в это свойство 0. У компонента UpDown в свойстве Associate  выберете Edit, в моем случае он называется ECount. Это поле нужно, чтобы указывать количество генерируемых дат.  Подпишите компоненты.

Собственно генерация будет происходить следующим образом.

DateTimeToStr(DTPStart.DateTime + Random(n) + (Random(24) / 24) + (Random(60) / 1440) + (Random(60) / 86400))

Логика следующая: К первой дате мы прибавляем случайное количество дней, но столько, чтобы не выйти за вторую дату. После прибавляем случайное количество часов, но не более 24. По аналогии прибавляем минуты и секунды.

Приведу код получившейся программы с комментариями.

unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, DateUtils;
type
  TForm1 = class(TForm)
    DTPStart: TDateTimePicker;
    DTPFinish: TDateTimePicker;
    LBDate: TListBox;
    BGen: TButton;
    ECount: TEdit;
    UDCount: TUpDown;
    LCount: TLabel;
    CBTime: TCheckBox;
    procedure BGenClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.BGenClick(Sender: TObject);
var
  n,i: Integer;
begin
  // Получаем разность между датами
  n := DaysBetween(DTPStart.DateTime, DTPFinish.DateTime);
  // Очищаем ListBox
  LBDate.Items.Clear;
  // В <a href="/studentam/delphi/109-tsikl-for-v-delphi">цикле</a> генерируем даты, столько, сколько указано пользователем
  for i := 0 to StrToInt(ECount.Text) - 1 do
  begin
  // Если нужно генерировать с временем
    if CBTime.Checked then
    begin
  // Генерация даты с временем
      LBDate.Items.Add(DateTimeToStr(DTPStart.DateTime + Random(n) +
        (Random(24) / 24) + (Random(60) / 1440) + (Random(60) / 86400)));
    end
  // Если нужны только даты
    else
  // Генерация даты
      LBDate.Items.Add(DateToStr(DTPStart.DateTime + Random(n)));
  end;
end;
end.

Добавить комментарий



Обновить

Комментарии   

 
0 #3 Кое-кто 11.12.2015 23:48
Цитирую Maxim:

Дата хранится 41813,398337546 3. Поэтому ничего преобразовывать не нужно.
Можно по-разному отображать.

Может быть Вам и не нужно, а мне нужно. Для меня число 41813,398337546 3 не имеет смысла и я совершенно не понимаю как туда запихнута дата.
И я в общем-то не про программировани е имел ввиду, а вообще, что это за протокол записи времени?
Цитировать
 
 
0 #2 Maxim 11.12.2015 22:14
Цитирую Кое-кто:
Во-первых, как число(41813,3983375463) преобразовать снова в дату и наоборот, дату в такое число?

Дата хранится 41813,398337546 3. Поэтому ничего преобразовывать не нужно.
Можно по-разному отображать.
ShowMessage(Dat eToStr(41813.39 83375463));
ShowMessage(flo attostr(41813.3 983375463));
Цитировать
 
 
0 #1 Кое-кто 11.12.2015 20:06
Во-первых, как число(41813,398 3375463) преобразовать снова в дату и наоборот, дату в такое число?
Цитировать
 
Thursday the 14th. icq 486350790
Copyright 2012

©