Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.12.09;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.047 c
15-1194525911
Sonia
2007-11-08 15:45
2007.12.09
Может еще кто-то помнит Фортран....


2-1195026930
dmdel
2007-11-14 10:55
2007.12.09
Имя компьютера


2-1194868661
cosy
2007-11-12 14:57
2007.12.09
найдите ошибку пожалуста уже 2 часа на этот сорц смотрю


15-1193175070
Прочее
2007-10-24 01:31
2007.12.09
Как сделать чтобы в OnKeyPress проходило сообщение VK_UP ?


2-1195193315
DevilDevil
2007-11-16 09:08
2007.12.09
помогите выделить TTreeNode





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский