Untitled

4ae4d avatar
4ae4d
plain_text
05/06/2026 12:49 PM
4.4 KB
9
Indexable
diff --git a/services/bot/core/utils/date_time.py b/services/bot/core/utils/date_time.py
index old..new 100644
--- a/services/bot/core/utils/date_time.py
+++ b/services/bot/core/utils/date_time.py
@@ -1,44 +1,70 @@
 from datetime import datetime
 from typing import Any
 
 
-def parse_datetime(value: Any) -> str:
-    """Парсит datetime в формат ДД.ММ.ГГГГ - ЧЧ:ММ"""
+def parse_datetime_value(value: Any) -> datetime | None:
+    """Парсит значение backend-а в datetime.
+
+    Не форматирует дату для пользователя.
+    Используется в схемах.
+    """
     if value is None:
-        return ""
+        return None
 
-    # Получаем datetime объект
-    dt = None
     if isinstance(value, datetime):
-        dt = value
-    elif isinstance(value, str):
-        # Пробуем разные форматы
-        value_clean = value.replace("Z", "+00:00")
-        for fmt in [
-            "%Y-%m-%dT%H:%M:%S%z",  # 2026-04-16T20:30:00+00:00
-            "%Y-%m-%dT%H:%M:%SZ",  # 2026-04-16T20:30:00Z
-            "%Y-%m-%dT%H:%M:%S.%f%z",  # с микросекундами
-        ]:
-            try:
-                dt = datetime.strptime(value_clean, fmt)
-                break
-            except Exception:
-                continue
+        return value
 
-        if dt is None:
+    if not isinstance(value, str):
+        return None
+
+    value_clean = value.strip()
+    if not value_clean:
+        return None
+
+    # ISO/RFC3339 из backend-а: 2026-05-05T14:31:03.95006Z
+    iso_value = value_clean.replace("Z", "+00:00")
+    try:
+        return datetime.fromisoformat(iso_value)
+    except Exception:
+        pass
+
+    # Старый UI-формат, который уже мог попасть в state/данные.
+    for fmt in (
+        "%d.%m.%Y - %H:%M",
+        "%d.%m.%Y %H:%M",
+        "%Y-%m-%dT%H:%M:%S%z",
+        "%Y-%m-%dT%H:%M:%SZ",
+        "%Y-%m-%dT%H:%M:%S.%f%z",
+    ):
+        try:
+            return datetime.strptime(value_clean, fmt)
+        except Exception:
+            continue
+
+    return None
+
+
+def require_datetime(value: Any, field_name: str) -> datetime:
+    """Парсит обязательный datetime или явно падает на нарушении контракта."""
+    parsed = parse_datetime_value(value)
+    if parsed is None:
+        raise ValueError(f"Invalid datetime contract: {field_name} is required")
+    return parsed
+
+
+def format_datetime(value: Any) -> str:
+    """Форматирует datetime для отображения пользователю."""
+    dt = parse_datetime_value(value)
+    if dt is None:
+        return "—"
+
+    return dt.strftime("%d.%m.%Y - %H:%M")
+
+
+def parse_datetime(value: Any) -> str:
+    """Deprecated: оставлено для старого UI-кода.
+
+    В новых схемах использовать parse_datetime_value/require_datetime.
+    В markups использовать format_datetime.
+    """
+    formatted = format_datetime(value)
+    return "" if formatted == "—" else formatted
-    else:
-        return ""
-
-    if dt is None:
-        return ""
-
-    # Форматируем в нужный вид: 16.04.2026 - 20:30
-    return dt.strftime("%d.%m.%Y - %H:%M")






Editor is loading...
Leave a Comment