Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.12.09;
Скачать: CL | DM;

Вниз

Разница между датами   Найти похожие ветки 

 
Andy BitOff (ppc)   (2007-11-08 13:07) [0]

Здравствуйте.
Что-то у меня уже башка не варит, сижу парюсь и шарики за ролики заходят...
Никак не удается получить разничу между датами в формате dd.mm.yy.
Например.
05.11.2007 и 08.11.2007 должно получиться 03.00.00, но при работе с типом дата месяц (как и год) не может быть равен 0.
Может кто подскажет как это можно реализовать?


 
Johnmen ©   (2007-11-08 13:09) [1]

Никак. Разница между датами есть интервал, измеряемый в фиксированных единицах. Напр. в секундах или сутках.


 
Skyle ©   (2007-11-08 13:10) [2]

А что хочется получить?
какая должна быть разница между 05.11.2007 и 05.11.2006?


 
clickmaker ©   (2007-11-08 13:12) [3]


> должно получиться 03.00.00

в смысле, нужно отдельно представлять сколько разница в днях, месяцах и годах?
тогда можно свою структуру завести
TDateDiff = record
 Days: integer;
 Months: integer;
 Years: integer;
end;
ну и форматировать в строку


 
Ega23 ©   (2007-11-08 13:12) [4]


> какая должна быть разница между 05.11.2007 и 05.11.2006?


525600 минут


 
Skyle ©   (2007-11-08 13:13) [5]


> Ega23 ©   (08.11.07 13:12) [4]
> > какая должна быть разница между 05.11.2007 и 05.11.2006?
> 525600 минут

В смысле минус?


 
Andy BitOff (ppc)   (2007-11-08 13:17) [6]

Забыл сказать. КОНЕЧНО результат в стринг,ну я думал это и понятно. ;)

> какая должна быть разница между 05.11.2007 и 05.11.2006?
00.00.01
А что это не очевидно?
Визуально и поработав мозгами это очевидно, а вот программная реализация, чего-то мне не дается.


 
engine ©   (2007-11-08 13:19) [7]

> [0] Andy BitOff (ppc)   (08.11.07 13:07)

function DatesBetween (FirstDate, SecondDate : TDateTime) : String;
begin
Result := IntToStr(DaysBetween(FirstDate, SecondDate)) + "." +
          IntToStr(MonthsBetween(FirstDate, SecondDate)) + "." +
          IntToStr(YearsBetween(FirstDate, SecondDate));
end;


Что-то типа того, не запускал, но должно работать.


 
Desdechado ©   (2007-11-08 13:28) [8]

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


 
Sergey13 ©   (2007-11-08 13:36) [9]

> [6] Andy BitOff (ppc)   (08.11.07 13:17)
> 00.00.01
> А что это не очевидно?

А тебя не смущает, что столь "очевидный" результат пересчитанный в другие единицы (дни, минуты и т.д.) для разных лет будет отличаться друг от друга?


 
stud ©   (2007-11-08 13:40) [10]

engine ©   (08.11.07 13:19) [7]

интересный должен результат получиться))))))


 
Andy BitOff (ppc)   (2007-11-08 13:50) [11]

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


 
Johnmen ©   (2007-11-08 13:53) [12]


> engine ©   (08.11.07 13:19) [7]

"Работать" это что? Отсутствие ошибок в программе? Или правильный результат?


 
Johnmen ©   (2007-11-08 13:54) [13]


> Далее с этими данными никаких действий производиться не
> будет.

М.б. тебе они и не нужны вовсе?


 
Andy BitOff (ppc)   (2007-11-08 14:05) [14]

Johnmen © (08.11.07 13:54) [13]
Ну ты же умный человек. Неужели я бы стал тратить свое время, трафик и ваше время, если бы мне это было не надо.
Обычно (если, что бывает редко) я что-то здесь спрашиваю, то это значит, что я действительно зашел в тупик и не вижу выхода.
Я переписал уже три или четыре раза функцию для решения этой задачи, но так и не приуспел в этом. Поэтому и обратился сюда.
Сейчас обдумываю еще вариант, но мозги уже закипают.


 
engine ©   (2007-11-08 14:06) [15]

> [12] Johnmen ©   (08.11.07 13:53)

Мдя, не подумал. Результат интересный получился. )))


 
Johnmen ©   (2007-11-08 14:08) [16]


> Andy BitOff (ppc)   (08.11.07 14:05) [14]

Дело в том, что неглупые грамотные люди тебе уже и сказали и намекнули, что никак. Поясняю - ни один, тобой придуманный "алгоритм", не будет правильным. Т.е. не будет давать верных с любой т.з. решений.


 
Andy BitOff (ppc)   (2007-11-08 14:21) [17]

Johnmen © (08.11.07 14:08) [16]
Неверю.
Любую задачу, тем более эту, можно решить/запрограммировать. Другое дело сколько понадобится для этого ресурсов (чел/часов, нервов и т.п).


 
engine ©   (2007-11-08 14:36) [18]

> [17] Andy BitOff (ppc)   (08.11.07 14:21)

function DatesBetween (FirstDate, SecondDate : TDateTime) : String;
var
  CountDays, CountMonth, CountYear : Integer;
  i, Year1, Year2 : Integer;
begin
 CountYear := YearOf(SecondDate) — Yearof(FirstDate);
 if MonthOf(SecondDate) < MonthOf(FirstDate) then
  begin
    dec(CountYear);
    CountMonth := 12 &#151; MonthOf(FirstDate) + MonthOf(SecondDate)
  end
  else
    CountMonth := MonthOf(SecondDate) &#151; MonthOf(FirstDate);
 if DayOf(SecondDate) < DayOf(FirstDate) then
  begin
    dec(CountMonth);
    CountDays := DaysInMonth(FirstDate)  &#151; DayOf(FirstDate) + DayOf(SecondDate);
  end else
   CountDays := DayOf(SecondDate) &#151; DayOf(FirstDate);
 Result := IntToStr(CountDays) + "." +
           IntToStr(CountMonth) + "." +
           IntToStr(CountYear);
end;


Вот вариант. Только требует обработки напильником


 
Johnmen ©   (2007-11-08 14:54) [19]


> engine ©   (08.11.07 14:36) [18]

Что получится
29.02.1996 - 28.02.1995 = ?
01.03.1996 - 28.02.1995 = ?


 
engine ©   (2007-11-08 15:05) [20]

> [19] Johnmen ©   (08.11.07 14:54)

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


 
Leonid Troyanovsky ©   (2007-11-08 15:29) [21]


> Andy BitOff (ppc)   (08.11.07 14:21) [17]

> Неверю.
> Любую задачу, тем более эту, можно решить/запрограммировать.

А и задачи-то никакой нет.
Скажем, что это некорректная постановка.

--
Regards, LVT.


 
Anatoly Podgoretsky ©   (2007-11-08 15:42) [22]


> Неужели я бы стал тратить свое время,
>  трафик и ваше время, если бы мне это было не надо.

Не функции надо переписывать, а разработать теорию, по которой интервал 30 дней можно будет преобразовать в любую дату, разработаешь - нобелевку получишь.


 
Desdechado ©   (2007-11-08 16:09) [23]

Дата - это точка на оси времени. Разница между датами - это отрезок между точками. Нельзя отрезок представить в виде одной точки.


 
OP   (2007-11-08 16:27) [24]


> Дата - это точка на оси времени. Разница между датами -
> это отрезок между точками. Нельзя отрезок представить в
> виде одной точки.

Согласен, максимум что можно - посчитать разницу между датами в днях... но такой ведь вариант его не устраивает...


 
Anatoly Podgoretsky ©   (2007-11-08 16:35) [25]

> Desdechado  (08.11.2007 16:09:23)  [23]

Очень весело получается в одинаковой ситуации, например с температурой, утром 24, вечером 26 градусов, по логике автора получается, что температура в больнице 2 градуса, или 1 января 0001 года.


 
Anatoly Podgoretsky ©   (2007-11-08 16:36) [26]

> OP  (08.11.2007 16:27:24)  [24]

А автор озабочен нобелевкой.


 
vpbar ©   (2007-11-08 17:00) [27]

Это

> 05.11.2007 и 08.11.2007 должно получиться 03.00.00, но при
> работе с типом дата месяц (как и год) не может быть равен

> 0.


И ЭТО

> Забыл сказать. КОНЕЧНО результат в стринг,ну я думал это
> и понятно. ;)
>  Потому что пересчет в другие единицы не подразумевается.
>

Немного противоречит друг другу.
Если второе, то просто раскладывай дату в дни месяцы и годы и вычитай. Получить чтото.


 
SergeyIT ©   (2007-11-08 18:07) [28]

Когда-то давно решал подобную задачу.
Делал как-то вот так:

function DateDiff(dat1, dat2: TDate): String;
var
  d1, d2, m1, m2, y1, y2: Word;
  i, ii, id, im, iy: Integer;
  dd, dw: TDate;
begin
 dat1 := Floor(dat1); dat2 := Floor(dat2);
 if dat2 < dat1 then
 begin
   dd := dat2; dat2 := dat1; dat1 := dd;
 end;
 DecodeDate(dat1, y1, m1, d1); DecodeDate(dat2, y2, m2, d2);
 id := 0; im := 0; iy := 0;
 dd := dat2;
 while TRUE do
 begin
   dd := EncodeDate(y2 - iy - 1, m2, d2);
   if dd < dat1 then break;
   inc(iy);
 end;
 while TRUE do
 begin
   i := m2 - im - 1;
   ii := y2 - iy;
   if i <= 0 then
   begin
    i := 12;
    dec(ii);
   end;
   dd := EncodeDate(ii, i, d2);
   if dd < dat1 then break;
   inc(im);
 end;
 dw := EncodeDate(y2 - iy, m2 - im, d2);
 while TRUE do
 begin
   dd := dw - id - 1;
   if dd < dat1 then break;
   inc(id);
 end;
 Result := IntToStr(id) + "." + IntToStr(im) + "." + IntToStr(iy);
end;

Надо проверять.
Может можно оптимизировать...

Для остальных:
Такие задачи действительно встречаются. Надо знать разницу между датами в полных годах - месяцах - днях.
Решение тривиальное - вычитанием целых годов, месяцев, дней с проверкой выхода за нижнюю границу. Не оптимально, но дает результат.


 
Shirson_   (2007-11-08 18:26) [29]

>Andy BitOff (ppc)   (08.11.07 13:17) [6]
> Забыл сказать. КОНЕЧНО результат в стринг,ну я думал это и понятно. ;)
> какая должна быть разница между 05.11.2007 и 05.11.2006?
> 00.00.01

Date in Delphi - number of days that have passed since blah-blah-blah.

05.11.2007=39391
05.11.2006=39026
15.12.2008=39797

Res:=15.12.2008-05.11.2006 = 39797-39026=771 (days)

For Your type of result, must be used abstract "year" (365 days) and abstract mounth (30 days), because, it"s not year or mount exactly, but just a measure.

procedure TForm1.Button1Click(Sender: TObject);
var d1,d2:tdatetime;
   res:real;
   Months,Years,Days:Integer;
   c:string;
begin
 d1:=strtodatetime(edit1.Text);
 d2:=strtodatetime(edit2.Text);
 Res:=d1-d2;
 If res<0 then c:="-" else c:="";
 Res:=abs(Res);
 Years:= trunc(Res/365);
 Months:= Trunc((Res - Years * 365) / 30);
 Days:= trunc(Res-Years*365-Months*30);    caption:=c+RightStr("0"+inttostr(Days),2)+"."+RightStr("0"+inttostr(Months),2)+"."+RightStr("000"+inttostr(Years),4);
end;


If you need not abstract measure, use engine [18] variant.

P.S. Sorry for English. No computers with russian available now.


 
SergeyIT ©   (2007-11-08 18:30) [30]

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


 
Anatoly Podgoretsky ©   (2007-11-08 19:10) [31]

Ну так не дату же получать, а интервал


 
SergeyIT ©   (2007-11-08 19:14) [32]


> Никак не удается получить разничу между датами в формате
> dd.mm.yy.

Я когда-то и решал именно эту задачу.


 
Anatoly Podgoretsky ©   (2007-11-08 19:29) [33]

> SergeyIT  (08.11.2007 19:14:32)  [32]

То есть решал как получить дату 01.00.0001


 
SergeyIT ©   (2007-11-08 19:37) [34]


>решал как получить дату

Нет конечно - разницу между датами в виде - число полных лет, месяцев, дней. Просто автор сформулировал некорректно - но в его примере видно, что ему надо.


 
Malik   (2007-11-08 19:38) [35]

Кто-нибудь скажет мне скока дней в месяце, и в годе?


 
Anatoly Podgoretsky ©   (2007-11-08 19:43) [36]


> Кто-нибудь скажет мне скока дней в месяце, и в годе?

На этот вопрос ответа нет, но есть решение в полных годах, месяцах
Некоторая сложность есть с февралем


 
b z   (2007-11-08 19:44) [37]


> скока дней в месяце, и в годе?

в каком? ;)


 
SergeyIT ©   (2007-11-08 19:44) [38]


> скока дней в месяце, и в годе

В дельфи, если посмотрите сорсы, есть функции, которые дают однозначный ответ.


 
Johnmen ©   (2007-11-08 20:24) [39]


> SergeyIT ©   (08.11.07 19:37) [34]

Прошу прежде, чем решать эту "абстракцию" в "абстрактных" годах и "абстрактных" месяцах, ответить мне однозначно на [19], а также на:
Что получится
16.06.2007 - 15.07.2007 = ?
16.07.2007 - 15.08.2007 = ?
01.01.2004 - 01.03.2004 = ?
01.01.2004 - 29.02.2004 = ?

И ещё хотелось бы услышать, чем красный отличается от сладкого?


 
Malik   (2007-11-08 20:37) [40]


> Anatoly Podgoretsky ©   (08.11.07 19:43) [36]

Я это знаю
Ладно ма держи:
S:=IntToStr(Round(DaysBetween(DateTimePicker2.Date,DateTimePicker1.Date)-MonthsBetween(DateTimePicker2.Date,DateTimePicker1.Date)*365.25/12))+"."+IntToStr(MonthsBetween(DateTimePicker2.Date,DateTimePicker1.Date)mod 12)+"."+IntToStr(YearsBetween(DateTimePicker2.Date,DateTimePicker1.Date));
Учти небольшой шлиф... и должно получиться, А так даёт максимум ошибку на день из-за округлений и не определённости величин месяцов, годов



Страницы: 1 2 3 4 5 вся ветка

Текущий архив: 2007.12.09;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.035 c
1-1190293681
Lpnt
2007-09-20 17:08
2007.12.09
Отображение данных.


4-1179934533
BFG9k
2007-05-23 19:35
2007.12.09
Как определить, активна ли задача ?


15-1194406235
Slider007
2007-11-07 06:30
2007.12.09
С днем рождения ! 7 ноября 2007 среда


2-1195010238
Lebedev
2007-11-14 06:17
2007.12.09
Проблема с MediaPlayer.


15-1194952991
Красный вождь
2007-11-13 14:23
2007.12.09
Редактор разводки печатных плат