Разместите нашу кнопку!

Новые статьи:

Programming articles

Создание сайтов на шаблонах

Множество вариантов работы с графикой на канве

Шифруем файл с помощью другого файла

Перехват API функций - Основы

Как сделать действительно хороший сайт

Создание почтового клиента в Delphi 7

Применение паскаля для решения геометрических задач

Управление windows с помощью Delphi

Создание wap сайта

Операционная система unix, термины и понятия

SQL враг или друг

Возникновение и первая редакция ОС UNIX

Оптимизация проекта в Delphi

Ресурсы, зачем нужны ресурсы

Термины программистов 20 века

Советы по созданию собственного сайта с нуля

Шифруем файл с помощью пароля

Фракталы - геометрия природы

Crypt - Delphi программа для шифрования

Рассылка, зачем она нужна и как ее организовать?

Учебник по C++ для начинающих программистов

Уроки для изучения ассемблера

Загадочный тип PCHAR

Средства по созданию сайтов

Операторы преобразования классов is и as

Borland Developer studio 2006. Всё в одном

Создание базы данных в Delphi, без сторонних БД


Software engineering articles



Date time в Delphi

Нестандартные функции работы с датой/временем

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

Задача первая:

    Что, получиться если мы вычтем одну дату из другой? Правильный ответ на этот вопрос, будет период работы, а что нам скажет Delphi?

     23.01.07- 21.11.06= 03.03.1900 круто, да … и кто же из нас не прав, черт побери. Общепризнанной практикой исчисления стажа является, примерно такой алгоритм.
23.01.07 -
21.11.06
-------------
2

    Итого 2 месяца 2 дня. Два месяца получились при переброске года в месяцы (12 месяцев). Вот этот алгоритм и требуется описать. Сразу сойдемся на мнении, что в году у нас 360 дней (12 месяцев по 30 дней), это, по-моему, еще из Excel вылезло. Алгоритм очень простой мы расщепляем дату на дни месяцы и годы, и производим, то, что выше указанно, а ответ мы вернем в виде строки.

function Period(BeginDate, EndDate: Tdatetime): string;
var
SubDate:Tdatetime;
md,mm,my:integer;
begin
SubDate:=EndDate-BeginDate;
md:=dayof(EndDate)-dayof(begindate);
mm:=monthof(EndDate)-monthof(begindate);
my:=yearof(EndDate)-yearof(begindate);
if md<0 then begin
         md:=md+30;
         mm:=mm-1;
         end;
if mm<0 then begin
         my:=my-1;
         mm:=mm+12;
         end;
Period:=inttostr(md)+'.'+inttostr(mm)+'.'+inttostr(my);
end;

    Вот таким образом вы считаем период работы.

Задача вторая:

    Что же дальше? Период мы почитали, а теперь надо сложить периоды, что бы не шокировать себя, складывать TDateTime'ы мы не станем. А сразу напишем функцию, которая сложит нам две даты, полученные в прошлой задачке.

function SummaPeriod(BeginDate, EndDate: string): string;
var
bd,bm,by:integer;
ed,em,ey:integer;
sd,sm,sy:integer;
begin
randomize;
bd:=dayof(strtodate(BeginDate));
bm:=monthof(strtodate(BeginDate));
by:=yearof(strtodate(BeginDate))-2000;
ed:=dayof(strtodate(EndDate));
em:=monthof(strtodate(EndDate));
ey:=yearof(strtodate(EndDate))-2000;
sd:=bd+ed;
sm:=bm+em;
sy:=by+ey;
if sd>=30 then
         begin
         sd:=sd-30;
         sm:=sm+1;
         end;
if sm>=12 then
         begin
         sm:=sm-12;
         sy:=sy+1;
         end;
SummaPeriod:=inttostr(sd)+'.'+inttostr(sm)+'.'+inttostr(sy);
end;

     Сразу предвижу ваш вопрос, а что это за хрень? by:=yearof(strtodate(BeginDate))-2000; Вы можете разложить строку и получить то, же самое.

Задача третья:

     Имеется период работы, описанный двумя переменными типа TdateTime (начало периода и конец периода) требуется определить входит некоторая дата в этот интервал. Сложность заключается, прежде всего, в том, что невозможно описать тип TdateTime без указания года. Как, например, в случае 23 февраля, 8 марта, новый год (самый веселый праздник). Для описания веселых "Красных дней календаря" будем использовать тип String. Функция, которая определяет вхождение даты в заданный диапазон, получилась примерно такой:

function Holydays(BeginDate, EndDate: Tdatetime;holyday: string): integer;
var
output:integer;
md:string;
begin
md:=holyday+'.'+inttostr(yearof(EndDate));
if (CompareDateTime(strtodate(md), EndDate)<=0) and
     (CompareDateTime(BeginDate,strtodate(md))<=0)then
         begin
         output:=1;
         end else output:=0;
if output=0 then
       begin
md:=holyday+'.'+inttostr(yearof(BeginDate));
if (CompareDateTime(strtodate(md), EndDate)<=0) and
       (CompareDateTime(BeginDate,strtodate(md))<=0)then
         begin
         output:=1;
         end else output:=0;
         end;
Holydays:=output;
end;

    Если в результате выполнения получается "1", то дата в заданный диапазон входит, в противном случае нет.
    Рассмотрим алгоритм действий данной функции поподробнее. BeginDate - начало периода, EndDate - окончание периода, holyday - собственно праздник (в формате "23.02") md:=holyday+'.'+inttostr(yearof(EndDate)); - приводим дату праздника в соответствие с типом TDateTime значение года берется из окончания периода (для случая, когда начало периода, было в одном году, а окончание уже в другом). После чего проводим проверку на вхождение в заданный диапазон:

if (CompareDateTime(strtodate(md), EndDate)<=0) and
      (CompareDateTime(BeginDate,strtodate(md))<=0)then
         begin
         output:=1;
         end else output:=0;

    Но, не все так гладко как может показаться, в случае с входными данными вида начало периода- 27.11.06, окончание периода - 10.01.07, праздник 29.11 (маловероятно звучит, но у нас и такие чудеса бывают), а посему мы приводим дату в соответствие md:=holyday+'.'+inttostr(yearof(BeginDate)); и работает! Вот такая полезная статистическая функция получилась. Теперь можно создавать базу данных русских праздников и вычитать их из отпуска сотрудника. -- С уважением, Антон mailto:AntonCH82@mail.ru

Обсудить на форуме




Warning: require_once(/home/program/programmersclub.ru/docs/60c3403e55019aa8da82c567fcf8afa0/sape.php): failed to open stream: No such file or directory in /home/program/programmersclub.ru/docs/datetimeanton/index.php on line 868

Fatal error: require_once(): Failed opening required '/home/program/programmersclub.ru/docs/60c3403e55019aa8da82c567fcf8afa0/sape.php' (include_path='.:/home/program/programmersclub.ru/php') in /home/program/programmersclub.ru/docs/datetimeanton/index.php on line 868