| 
| 
 | Вопрос # 2 432/ вопрос открыт / | 
 |  Приветствую, уважаемые эксперты!Подскажите, как решить такую задачу:
 есть две даты dt1, dt2 : TDateTime;
 пусть dt2>dt1
 есть поля YY, MM, DD, hh, mm, ss: integer;
 Как оптимальней получить в эти поля разность лет, месяцев, дней, часов, минут, секунд сответственно?
 
 Конечная цель - нужно сформировать строку YYMMDDhhmmss
 
 Спасибо.
 
|  |   Вопрос задал: HotMan (статус: Посетитель)Вопрос отправлен: 19 февраля 2009, 11:33
 Состояние вопроса: открыт, ответов: 1.
 |  Ответ #1. Отвечает эксперт: min@y™ В модуле DateUtils.pas есть функция:
 procedure DecodeDateTime(const AValue: TDateTime; out AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word);Вычитай из большей даты меньшую, а эту разность подставляй в эту функцию. Вот и всё. 
 З.Ы. Посмотри в хэлпе инфу по функциям этого модуля. Там есть много интересного.
 
|  | Ответ отправил: min@y™ (статус: Доктор наук)Время отправки: 19 февраля 2009, 11:42
 Оценка за ответ: 3
 |  
 Мини-форум вопросаВсего сообщений: 6; последнее сообщение — 19 февраля 2009, 14:06; участников в обсуждении: 3. 
|   | HotMan (статус: Посетитель), 19 февраля 2009, 11:57 [#1]:DecodeDateTime возвращает следующее для дат, разнстью в 1 день: YY=1899; MM=12; DD=31; hh=0; mm=0; ss=0
 
 А хочется получить результат такой:
 YY=0; MM=0; DD=1; hh=0; mm=0; ss=0
 |  
|   | HotMan (статус: Посетитель), 19 февраля 2009, 12:04 [#2]:Пробовал взять HoursBetween - если разность больше суток, то hh>24, а нужно получить значение относительно 24. Для часов то конечно можно и поделить результат на 24, а для количества дней в месяце?
 |  
|   | HotMan (статус: Посетитель), 19 февраля 2009, 12:30 [#3]:Вот что получилось: now:= date +time;
 
 vdt:=now +365+ 23/24;// год+23 часа
 
 
 YY:=YearsBetween(now, vdt);
 if YY>0 then now:=IncYear(now,YY);
 MM:=MonthsBetween(now, vdt);
 if MM>0 then now:=IncMonth(now,MM);
 DD:=DaysBetween(now, vdt);
 if DD>0 then now:=IncDay(now,DD);
 hh:=HoursBetween(now, vdt);
 if hh>0 then now:=IncHour(now,hh);
 m:=MinutesBetween(now, vdt);
 if m>0 then now:=IncMinute(now,m);
 ss:=SecondsBetween(now,vdt);
 |  
|   | HotMan (статус: Посетитель), 19 февраля 2009, 12:30 [#4]:это уже дает нужный резльтат   |  
|   | min@y™ (статус: Доктор наук), 19 февраля 2009, 12:38 [#5]:Да, действительно, это так, как ни странно. Я попробовал написать пример. Вот, посмотри:
 
 program p2432;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils, DateUtils;
 
var
  YTD, TD: TDateTime;
  AYear, AMonth, ADay: Integer;
  AHour, AMinute, ASecond, AMilliSecond: Int64;
 
begin
  YTD:= Yesterday(); // Вчерашняя дата
  TD:= Date(); // Сегодняшняя дата
 
  AYear:= YearsBetween(TD, YTD);
  AMonth:= MonthsBetween(TD, YTD) mod 12;
  ADay:= DaysBetween(TD, YTD) mod 365; // <--- Без учёта високостных годов
  AHour:= HoursBetween(TD, YTD) mod 24;
  AMinute:= MinutesBetween(TD, YTD) mod 1440;
  ASecond:= SecondsBetween(TD, YTD) mod 86400;
  AMilliSecond:= MilliSecondsBetween(TD, YTD) mod 86400000;
 
  WriteLn('AYear = ', AYear, ' ',
          'AMonth = ', AMonth, ' ',
          'ADay = ', ADay, ' '#13#10,
          'AHour = ', AHour, ' ',
          'AMinute = ', AMinute, ' ',
          'ASecond = ', ASecond, ' ',
          'AMilliSecond = ', AMilliSecond);
 
  ReadLn;
end.Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | Тов. Женька (статус: 3-ий класс), 19 февраля 2009, 14:06 [#6]:На вот, помозгуй над этим. Здесь производится расчет стажа, но, думаю, нарастить функционал проблем не будет. 
 procedure TDM.CalcStage(DateBegin, DateEnd : TDateTime);
 var
 Date1, Date2 : TDateTime;
 Years, Months, Days : Integer;
 begin
 Years := YearsBetween(DateBegin, DateEnd);
 Date1 := IncYear(DateBegin, Years);
 Months := MonthsBetween(Date1, DateEnd);
 Date2 := IncMonth(Date1, Months);
 Days := DaysBetween(Date2, DateEnd);
 end;
 |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |