Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.02.2017, 23:36   #1
pas2
Пользователь
 
Регистрация: 02.01.2016
Сообщений: 42
Счастье Вычисление разности двух дат в месяцах

Кто знает как трактовать занятый месяц: 1 месяц = 28, 29, 30, 31 дней? Вдобавок, дело осложняется с високосностью годов. Цель определить рабочие дни: 1я дата оформление; 2я дата увольнение. Итог вывод разницу между двумя датами : отработано 0 лет 1 месяц 2 дня. Проблема заключается в месяцах 28, 29, 30, 31 дней, делаю та:
Код:
// день
function StrDays(iDay: integer): string;
begin
  Result:= ' дней ';
  case iDay of
    1, 21, 31: Result:= ' день ';
    2, 3, 4, 22, 23, 24: Result:= ' дня ';
  end;
end;

// месяц
function StrMonths(iMonth: integer): string;
begin
  Result:= ' месяцев ';
  case iMonth of
    1: Result:= ' месяц ';
    2, 3, 4: Result:= ' месяца ';
  end;
end;

// год
function StrYears(iYear: integer): string;
var
  s: string;
  sYear: string;
  i: integer;
begin
  result := ' лет ';
  if (iYear > 4) and (iYear < 21) then exit;
  sYear := IntToStr(iYear);
  s := Copy(sYear, Length(sYear), 1);
  i := StrToInt(s);
  case i of
    1: result := ' год ';
    2, 3, 4: result := ' года ';
  end;
end;

// ф-я
function StrBetweenDate(Date1, Date2: TDate): string;
var
  id, im, iy: Integer;
  d: TDate;
begin
  Result:= '';
  if Date1 < Date2 then
  begin
    d:= Date1;
    Date1:= Date2;
    Date2:= d;
    Date1:= Date1 + 1;
  end;
  d:= DaysBetween(Date1 + 1, Date2);
  id:= DayOf(d);
  im:= MonthOf(d)-1;
  iy:= YearOf(d);
  iy:= iy - 1900;

  if im = 12 then
    begin
      im:= 0;
      inc(iy);
    end;


  if id = 31 then
  begin
    id:= 0;
    inc(im);

    if im = 12 then
    begin
      im:= 0;
      inc(iy);
    end;
  end;
  Result:= (IntToStr(iy)+ StrYears(iy) + IntToStr(im) +
            StrMonths(im) + IntToStr(id)+ StrDays(id));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 aDate, date1: TDateTime;

begin
     aDate := DateTimePicker1.Date;
 date1 := DateTimePicker2.Date;

label5.Caption := StrBetweenDate(aDate, date1);
Если поставить с 01.02 по 28.02 должно получится 0 лет 1 месяц 0 дней (получается 0 лет 0 месяцев 28 дней), а с 01.02 по 01.03 0лет 1 месяц 1 день (получается 0 лет 0 месяцев 29 дней)
pas2 вне форума Ответить с цитированием
Старый 12.02.2017, 02:23   #2
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,859
По умолчанию

Цитата:
Сообщение от pas2 Посмотреть сообщение
Цель определить рабочие дни
Так при чем тут месяцы и годы?
А конкретно по вопросу могут помочь функции из DateUtils типа
Days[of]/[in][A]/[The]Month.
northener вне форума Ответить с цитированием
Старый 12.02.2017, 10:50   #3
pas2
Пользователь
 
Регистрация: 02.01.2016
Сообщений: 42
По умолчанию

Цитата:
Сообщение от northener Посмотреть сообщение
Так при чем тут месяцы и годы?
А конкретно по вопросу могут помочь функции из DateUtils типа
Days[of]/[in][A]/[The]Month.
Потому что помимо дней должно отображать месяц, год
pas2 вне форума Ответить с цитированием
Старый 12.02.2017, 12:33   #4
kropotkina-alice
Форумчанин
 
Аватар для kropotkina-alice
 
Регистрация: 27.10.2014
Сообщений: 594
По умолчанию

Цитата:
Сообщение от pas2 Посмотреть сообщение
Потому что помимо дней должно отображать месяц, год
Разность вы получаете - DaysBetween.
Теперь в хэлпе посмотрите функцию DecodeDate, там и пример для нее.
Учтите только, что нулевая дата - это не от рождества Христова , а 30 декабря 1899 года, стало быть от полученного количества лет надо отнять 1900 или 1899 (неохота открывать дельфи, так что сами потрудитесь определить)...
kropotkina-alice вне форума Ответить с цитированием
Старый 12.02.2017, 15:15   #5
pas2
Пользователь
 
Регистрация: 02.01.2016
Сообщений: 42
По умолчанию

Цитата:
Сообщение от kropotkina-alice Посмотреть сообщение
Разность вы получаете - DaysBetween.
Теперь в хэлпе посмотрите функцию DecodeDate, там и пример для нее.
Учтите только, что нулевая дата - это не от рождества Христова , а 30 декабря 1899 года, стало быть от полученного количества лет надо отнять 1900 или 1899 (неохота открывать дельфи, так что сами потрудитесь определить)...
Выше написан код ))
pas2 вне форума Ответить с цитированием
Старый 12.02.2017, 15:27   #6
kropotkina-alice
Форумчанин
 
Аватар для kropotkina-alice
 
Регистрация: 27.10.2014
Сообщений: 594
По умолчанию

Я вам про DecodeDate талдычу, которой у вас в коде нет, вместо нее вы занимаетесь изобретением колеса. читайте внимательнее...
kropotkina-alice вне форума Ответить с цитированием
Старый 12.02.2017, 15:56   #7
pas2
Пользователь
 
Регистрация: 02.01.2016
Сообщений: 42
По умолчанию

Цитата:
Сообщение от kropotkina-alice Посмотреть сообщение
Я вам про DecodeDate талдычу, которой у вас в коде нет, вместо нее вы занимаетесь изобретением колеса. читайте внимательнее...
Пардон, не заметил, сделал так, тоже что то не то

Код:
ar
 aDate, date1,dtDiff: TDateTime;
  dd, mm, yy, days: Word;
  str: string;
begin
 aDate := DateTimePicker1.Date;
 date1 := DateTimePicker2.Date;
  
days := DayOfTheYear(aDate) - 1;
 DecodeDate((date1 - Days), yy, mm, dd);
  yy := yy - YearOf(aDate);
  str := Format('Year: %d', [yy]) + #13#10 +
         Format('Month: %d', [mm]) + #13#10 +
         Format('Day: %d', [dd]);
 ShowMessage(str);
pas2 вне форума Ответить с цитированием
Старый 12.02.2017, 17:23   #8
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

http://www.programmersforum.ru/showt...C0%D2%C0%CC%C8
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 12.02.2017, 22:20   #9
pas2
Пользователь
 
Регистрация: 02.01.2016
Сообщений: 42
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Все работает в этом посте, при выборе даты 01.02.17 по 28.08.17 - отображает 27 дней, а при выборе с 01.02.17 по 01.03.17 показывает 1 месяц,по сути все четенько и правильно, а как тогда сделать для моего варианта что бы было в первом варианте 28 дней/29 дней, а во втором 1месяц 1день

Последний раз редактировалось pas2; 12.02.2017 в 22:46.
pas2 вне форума Ответить с цитированием
Старый 14.02.2017, 09:06   #10
KoToSveen
Новичок
Джуниор
 
Регистрация: 14.11.2016
Сообщений: 2
По умолчанию

Цитата:
Сообщение от pas2 Посмотреть сообщение
Кто знает как трактовать занятый месяц: 1 месяц = 28, 29, 30, 31 дней? Вдобавок, дело осложняется с високосностью годов.
DaysInAMonth (DateUtils) — возвращает количество дней в указанном месяце указанного года.


Ну и тут много интересного.

Последний раз редактировалось KoToSveen; 14.02.2017 в 09:10.
KoToSveen вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Составление программ расчёта разности двух чисел Владислав 212212 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 0 14.12.2016 17:13
Определить произведение разности первых двух цифр трехзначного числа и младшей цифры этого числа. Hoginat Паскаль, Turbo Pascal, PascalABC.NET 3 24.12.2012 22:13
Разность дат в месяцах Red_Garry Microsoft Office Excel 14 13.12.2011 21:29
Вычисление диапазонов дат, Delphi kmvas Помощь студентам 0 10.12.2010 15:32
Вычисление разницы дат Dux Общие вопросы Delphi 10 14.09.2010 15:41