Calculadora de días de vida
1
Дата рождения
2
Точность
3
Resultado
`);
printWindow.document.close();
printWindow.focus();
printWindow.print();
},
parseDateInput(value) {
if (!value || !/^\d{4}-\d{2}-\d{2}$/.test(value)) return null;
const [year, month, day] = value.split("-").map(Number);
return this.makeDate(year, month - 1, day);
},
makeDate(year, monthIndex, day) {
const date = new Date(year, monthIndex, day);
date.setHours(12, 0, 0, 0);
return date;
},
getToday() {
const now = new Date();
return this.makeDate(now.getFullYear(), now.getMonth(), now.getDate());
},
toInputDate(date) {
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
},
formatDateRu(date) {
return `${String(date.getDate()).padStart(2, "0")}.${String(date.getMonth() + 1).padStart(2, "0")}.${date.getFullYear()}`;
},
utcDayNumber(date) {
return Math.floor(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) / 86400000);
},
diffCalendarDays(startDate, endDate) {
return this.utcDayNumber(endDate) - this.utcDayNumber(startDate);
},
compareDates(a, b) {
const diff = this.diffCalendarDays(a, b);
if (diff === 0) return 0;
return diff < 0 ? 1 : -1;
},
isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
},
daysInMonth(year, monthIndex) {
return new Date(year, monthIndex + 1, 0).getDate();
},
addMonthsClamped(date, monthsToAdd) {
const totalMonths = (date.getFullYear() * 12) + date.getMonth() + monthsToAdd;
const year = Math.floor(totalMonths / 12);
const month = totalMonths % 12;
const day = Math.min(date.getDate(), this.daysInMonth(year, month));
return this.makeDate(year, month, day);
},
getAnniversaryDate(birthDate, targetYear, leapRule) {
const isLeapBirthday = birthDate.getMonth() === 1 && birthDate.getDate() === 29;
if (isLeapBirthday && !this.isLeapYear(targetYear)) {
return leapRule === "mar1"
? this.makeDate(targetYear, 2, 1)
: this.makeDate(targetYear, 1, 28);
}
return this.makeDate(targetYear, birthDate.getMonth(), birthDate.getDate());
},
getExactAge(birthDate, calcDate, leapRule) {
let years = calcDate.getFullYear() - birthDate.getFullYear();
let yearAnchor = this.getAnniversaryDate(birthDate, birthDate.getFullYear() + years, leapRule);
if (this.compareDates(yearAnchor, calcDate) > 0) {
years -= 1;
yearAnchor = this.getAnniversaryDate(birthDate, birthDate.getFullYear() + years, leapRule);
}
let months = (calcDate.getFullYear() - yearAnchor.getFullYear()) * 12 + (calcDate.getMonth() - yearAnchor.getMonth());
let monthAnchor = this.addMonthsClamped(yearAnchor, months);
if (this.compareDates(monthAnchor, calcDate) > 0) {
months -= 1;
monthAnchor = this.addMonthsClamped(yearAnchor, months);
}
const days = this.diffCalendarDays(monthAnchor, calcDate);
return {
years,
months,
days,
totalMonths: years * 12 + months
};
},
getNextBirthdayInfo(birthDate, calcDate, leapRule) {
const thisYearBirthday = this.getAnniversaryDate(birthDate, calcDate.getFullYear(), leapRule);
let nextBirthday = thisYearBirthday;
if (this.compareDates(thisYearBirthday, calcDate) < 0) {
nextBirthday = this.getAnniversaryDate(birthDate, calcDate.getFullYear() + 1, leapRule);
}
return {
date: nextBirthday,
daysUntil: this.diffCalendarDays(calcDate, nextBirthday)
};
},
countWeekendDays(startDate, endDate, includeEnd) {
const totalDays = this.diffCalendarDays(startDate, endDate) + (includeEnd ? 1 : 0);
if (totalDays <= 0) return 0;
const fullWeeks = Math.floor(totalDays / 7);
const remainder = totalDays % 7;
let weekends = fullWeeks * 2;
const startWeekday = startDate.getDay();
for (let i = 0; i < remainder; i += 1) {
const weekday = (startWeekday + i) % 7;
if (weekday === 0 || weekday === 6) {
weekends += 1;
}
}
return weekends;
},
countLeapDaysInInterval(startDate, endDate, includeEnd) {
let count = 0;
for (let year = startDate.getFullYear(); year <= endDate.getFullYear(); year += 1) {
if (!this.isLeapYear(year)) continue;
const leapDay = this.makeDate(year, 1, 29);
const afterStart = this.compareDates(leapDay, startDate) >= 0;
const beforeEnd = includeEnd
? this.compareDates(leapDay, endDate) <= 0
: this.compareDates(leapDay, endDate) < 0;
if (afterStart && beforeEnd) {
count += 1;
}
}
return count;
},
decline(number, forms) {
const abs = Math.abs(number) % 100;
const last = abs % 10;
if (abs > 10 && abs < 20) return forms[2];
if (last > 1 && last < 5) return forms[1];
if (last === 1) return forms[0];
return forms[2];
},
formatAge(age) {
return [
`${age.years} ${this.decline(age.years, ["год", "года", "лет"])}`,
`${age.months} ${this.decline(age.months, ["месяц", "месяца", "месяцев"])}`,
`${age.days} ${this.decline(age.days, ["день", "дня", "дней"])}`
].join(" ");
},
capitalize(text) {
return text ? text.charAt(0).toUpperCase() + text.slice(1) : "";
}
};
document.addEventListener("DOMContentLoaded", () => LdWizApp.init());
})();