This commit is contained in:
2026-03-26 12:27:39 +07:00
parent a895c0f910
commit aa8fe39310
3 changed files with 81 additions and 5 deletions
+76
View File
@@ -73,3 +73,79 @@ export function getRelativeDayName(dateStr: string): string {
return "";
}
}
/**
* Функция для склонения слов (1 минута, 2 минуты, 5 минут)
*/
function getDeclension(number: number, titles: [string, string, string]): string {
const cases = [2, 0, 1, 1, 1, 2];
return titles[
(number % 100 > 4 && number % 100 < 20)
? 2
: cases[(number % 10 < 5) ? number % 10 : 5]
];
}
/**
* Основная функция форматирования времени
*/
export function timeAgo(goDateStr: string): string {
// 1. Парсим строку регуляркой, чтобы вытащить дату, время и смещение пояса.
// Игнорируем "m=+..." и доли секунд, так как для "5 минут назад" они не нужны.
// Группы: 1-Дата, 2-Время, 3-Часовой пояс (например +0700)
const regex = /^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})(?:\.\d+)? ([+-]\d{4})/;
const match = goDateStr.match(regex);
if (!match) {
console.error("Неверный формат даты:", goDateStr);
return goDateStr; // Возвращаем как есть в случае ошибки
}
const datePart = match[1];
const timePart = match[2];
const timezone = match[3];
// 2. Приводим к формату ISO 8601, который понимает любой браузер:
// "2026-03-26T12:11:18+0700"
const isoString = `${datePart}T${timePart}${timezone}`;
const date = new Date(isoString);
const now = new Date();
// 3. Считаем разницу в секундах
const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);
// Если дата в будущем (например, как в вашем примере 2026 год)
if (seconds < 0) {
return "в будущем";
}
// 4. Логика интервалов
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
if (seconds < 60) {
return "только что";
}
if (minutes < 60) {
return `${minutes} ${getDeclension(minutes, ['минуту', 'минуты', 'минут'])} назад`;
}
if (hours < 24) {
return `${hours} ${getDeclension(hours, ['час', 'часа', 'часов'])} назад`;
}
if (days < 7) {
return `${days} ${getDeclension(days, ['день', 'дня', 'дней'])} назад`;
}
// Если прошло больше недели, возвращаем просто дату
// Можно использовать Intl.DateTimeFormat для красоты
return date.toLocaleDateString("ru-RU", {
day: "numeric",
month: "long",
year: "numeric"
});
}