69 lines
1.4 KiB
Python
69 lines
1.4 KiB
Python
from __future__ import annotations
|
|
|
|
import calendar
|
|
from datetime import UTC, date, datetime
|
|
from zoneinfo import ZoneInfo
|
|
|
|
from flask import current_app
|
|
|
|
|
|
MONTH_NAMES = [
|
|
"",
|
|
"Januar",
|
|
"Februar",
|
|
"März",
|
|
"April",
|
|
"Mai",
|
|
"Juni",
|
|
"Juli",
|
|
"August",
|
|
"September",
|
|
"Oktober",
|
|
"November",
|
|
"Dezember",
|
|
]
|
|
|
|
|
|
def get_timezone() -> ZoneInfo:
|
|
return ZoneInfo(current_app.config["APP_TIMEZONE"])
|
|
|
|
|
|
def local_now() -> datetime:
|
|
return datetime.now(UTC).astimezone(get_timezone())
|
|
|
|
|
|
def today_local() -> date:
|
|
return local_now().date()
|
|
|
|
|
|
def previous_month(year: int, month: int) -> tuple[int, int]:
|
|
if month == 1:
|
|
return year - 1, 12
|
|
return year, month - 1
|
|
|
|
|
|
def next_month(year: int, month: int) -> tuple[int, int]:
|
|
if month == 12:
|
|
return year + 1, 1
|
|
return year, month + 1
|
|
|
|
|
|
def month_label(year: int, month: int) -> str:
|
|
return f"{MONTH_NAMES[month]} {year}"
|
|
|
|
|
|
def add_months(base_date: date, months: int) -> date:
|
|
month_index = base_date.month - 1 + months
|
|
year = base_date.year + month_index // 12
|
|
month = month_index % 12 + 1
|
|
day = min(base_date.day, calendar.monthrange(year, month)[1])
|
|
return date(year, month, day)
|
|
|
|
|
|
def month_bounds(year: int, month: int) -> tuple[datetime, datetime]:
|
|
start = datetime(year, month, 1)
|
|
next_year, next_month_value = next_month(year, month)
|
|
end = datetime(next_year, next_month_value, 1)
|
|
return start, end
|
|
|