Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.189.170.17] |
|
Сообщ.
#1
,
|
|
|
Подскажите кто знает, нужно выводить к-во отработанных лет,месяцев,дней (другими словами высчитать стаж). Сделал так, ниже код, но проблема с февралем, нужно трактовать занятый месяц: 1 месяц = 28, 29, 30, 31 дней? Вдобавок, дело осложняется с высокосностью годов.
Если поставить с 01.02 по 28.02 должно получится 0 лет 1 месяц 0 дней (получается 0 лет 0 месяцев 28 дней), а с 01.02 по 01.03 0лет 1 месяц 1 день (получается 0 лет 0 месяцев 29 дней) // день 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); |
Сообщ.
#2
,
|
|
|
В коде много странных действий типа прибавления одного дня к стартовой дате - но лишь в случае, если даты обмениваются.
Выходные и праздники в расчёте не учитываются? Стоит выполнить DecodeDate и по очереди сравнивать: год c учётом комбинации месяц/день что-то вроде YearsBetween = Year2 - Year1 - Ord((Month2 - Month1) * 31 + (Day2-Day1) < 0) месяц с учётом дня |
Сообщ.
#3
,
|
|
|
Цитата MBo @ учитываются и выходные праздничные дни Выходные и праздники в расчёте не учитываются? |
Сообщ.
#4
,
Сообщение отклонено: Shaggy -
|
Сообщ.
#5
,
|
|
|
Цитата MBo @ Стоит выполнить DecodeDate и по очереди сравнивать: год c учётом комбинации месяц/день что-то вроде ... А зачем? Нужно просто увеличить бОльшую дату на 1 день, выполнить DecodeDate и просто взять разности соответствующих значений лет, месяцев и дней. При этом и разное кол-во дней в месяцах, и високосные годы будут учтены автоматически. |
Сообщ.
#6
,
|
|
|
Цитата просто взять разности соответствующих значений лет, месяцев и дней Что подразумевается под "просто взять разности" Разности покомпонентные 15 марта 2017 и 17 июля 2016 - получим 1 год, -4 месяца и -2 дня? |
Сообщ.
#7
,
|
|
|
pas2а по какому алгоритму предлагает считать стаж пенсионный фонд, смотрели? кто там у нас еще отчетность со стажем собирает, у них алгоритм один или разные?
|
Сообщ.
#8
,
|
|
|
Мне кажется, если учитываются именно фактические дни, а не календарная разница, то иначе как циклом наращивания високосные годы и месяцы не посчитать. IsLeapYear и константы кол-ва дней в месяцах из DateUtils помогут.
Цитата if (iYear > 4) and (iYear < 21) then exit; sYear := IntToStr(iYear); s := Copy(sYear, Length(sYear), 1); i := StrToInt(s); Открой для себя оператор mod Цитата pas2 @ function StrDays(iDay: integer): string; function StrMonths(iMonth: integer): string; Вот так это делается правильно http://www.unicode.org/cldr/charts/latest/...ural_rules.html |
Сообщ.
#9
,
|
|
|
Цитата MBo @ Разности покомпонентные 15 марта 2017 и 17 июля 2016 - получим 1 год, -4 месяца и -2 дня? Да, я ступил. По "простому" тут не получится Тогда как-то так DecodeDate(Date1,y1,m1,d1); DecodeDate(Date2 + 1,y2,m2,d2); dY:=y2-y1; dM:=m2-m1; dD:=d2-d1; if (dM < 0) or (dM = 0) and (dD < 0) then begin dec(dY); inc(dM,12); end; if dD < 0 then begin dec(dM); if m2 = 1 then inc(dD,31) else inc(dD,DaysInAMonth(y2,m2 - 1)); end; |
Сообщ.
#10
,
|
|
|
вопрос,решен всем спасибо
|