reminder-bot/bot/utils/formatting.py

117 lines
3.0 KiB
Python

"""Formatting utilities for dates, times, and text."""
from datetime import datetime, timedelta
from typing import Optional
def format_datetime(dt: datetime, include_time: bool = True) -> str:
"""
Format datetime for display.
Args:
dt: datetime object
include_time: Whether to include time in output
Returns:
Formatted datetime string
"""
if include_time:
return dt.strftime("%d.%m.%Y в %H:%M")
else:
return dt.strftime("%d.%m.%Y")
def format_timedelta(td: timedelta) -> str:
"""
Format timedelta for human-readable display.
Args:
td: timedelta object
Returns:
Formatted string (e.g., "2 дня", "5 часов")
"""
total_seconds = int(td.total_seconds())
if total_seconds < 0:
return "просрочено"
days = total_seconds // 86400
hours = (total_seconds % 86400) // 3600
minutes = (total_seconds % 3600) // 60
if days > 0:
days_word = get_plural_form(days, "день", "дня", "дней")
if hours > 0:
hours_word = get_plural_form(hours, "час", "часа", "часов")
return f"{days} {days_word} {hours} {hours_word}"
return f"{days} {days_word}"
elif hours > 0:
hours_word = get_plural_form(hours, "час", "часа", "часов")
if minutes > 0:
minutes_word = get_plural_form(minutes, "минута", "минуты", "минут")
return f"{hours} {hours_word} {minutes} {minutes_word}"
return f"{hours} {hours_word}"
else:
minutes_word = get_plural_form(minutes, "минута", "минуты", "минут")
return f"{minutes} {minutes_word}"
def get_plural_form(number: int, form1: str, form2: str, form5: str) -> str:
"""
Get correct plural form for Russian language.
Args:
number: The number
form1: Form for 1 (день)
form2: Form for 2-4 (дня)
form5: Form for 5+ (дней)
Returns:
Correct plural form
"""
n = abs(number) % 100
n1 = n % 10
if 10 < n < 20:
return form5
if n1 == 1:
return form1
if 2 <= n1 <= 4:
return form2
return form5
def format_interval_days(days: int) -> str:
"""
Format interval in days for display.
Args:
days: Number of days
Returns:
Formatted string (e.g., "каждый день", "каждые 3 дня")
"""
if days == 1:
return "каждый день"
else:
days_word = get_plural_form(days, "день", "дня", "дней")
return f"каждые {days} {days_word}"
def truncate_text(text: str, max_length: int = 50, suffix: str = "...") -> str:
"""
Truncate text to maximum length.
Args:
text: Text to truncate
max_length: Maximum length
suffix: Suffix to add if truncated
Returns:
Truncated text
"""
if len(text) <= max_length:
return text
return text[:max_length - len(suffix)] + suffix