feat: Space Booking System - MVP complet
Sistem web pentru rezervarea de birouri și săli de ședință cu flux de aprobare administrativă. Stack: FastAPI + Vue.js 3 + SQLite + TypeScript Features implementate: - Autentificare JWT + Self-registration cu email verification - CRUD Spații, Utilizatori, Settings (Admin) - Calendar interactiv (FullCalendar) cu drag-and-drop - Creare rezervări cu validare (durată, program, overlap, max/zi) - Rezervări recurente (săptămânal) - Admin: aprobare/respingere/anulare cereri - Admin: creare directă rezervări (bypass approval) - Admin: editare orice rezervare - User: editare/anulare rezervări proprii - Notificări in-app (bell icon + dropdown) - Notificări email (async SMTP cu BackgroundTasks) - Jurnal acțiuni administrative (audit log) - Rapoarte avansate (utilizare, top users, approval rate) - Șabloane rezervări (booking templates) - Atașamente fișiere (upload/download) - Conflict warnings (verificare disponibilitate real-time) - Integrare Google Calendar (OAuth2) - Suport timezone (UTC storage + user preference) - 225+ teste backend Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
79
backend/app/utils/timezone.py
Normal file
79
backend/app/utils/timezone.py
Normal file
@@ -0,0 +1,79 @@
|
||||
"""Timezone utilities for converting between UTC and user timezones."""
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
import pytz
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
def convert_to_utc(dt: datetime, from_timezone: str = "UTC") -> datetime:
|
||||
"""Convert datetime from user timezone to UTC.
|
||||
|
||||
Args:
|
||||
dt: Datetime to convert (naive or aware)
|
||||
from_timezone: IANA timezone name (e.g., "Europe/Bucharest")
|
||||
|
||||
Returns:
|
||||
Naive datetime in UTC
|
||||
"""
|
||||
if dt.tzinfo is None:
|
||||
# Naive datetime, assume it's in user timezone
|
||||
tz = pytz.timezone(from_timezone)
|
||||
dt = tz.localize(dt)
|
||||
|
||||
# Convert to UTC
|
||||
return dt.astimezone(pytz.UTC).replace(tzinfo=None)
|
||||
|
||||
|
||||
def convert_from_utc(dt: datetime, to_timezone: str = "UTC") -> datetime:
|
||||
"""Convert datetime from UTC to user timezone.
|
||||
|
||||
Args:
|
||||
dt: Datetime in UTC (naive or aware)
|
||||
to_timezone: IANA timezone name (e.g., "Europe/Bucharest")
|
||||
|
||||
Returns:
|
||||
Timezone-aware datetime in target timezone
|
||||
"""
|
||||
if dt.tzinfo is None:
|
||||
# Add UTC timezone if naive
|
||||
dt = pytz.UTC.localize(dt)
|
||||
|
||||
# Convert to target timezone
|
||||
tz = pytz.timezone(to_timezone)
|
||||
return dt.astimezone(tz)
|
||||
|
||||
|
||||
def format_datetime_tz(dt: datetime, timezone: str = "UTC", format_str: str = "%Y-%m-%d %H:%M %Z") -> str:
|
||||
"""Format datetime with timezone abbreviation.
|
||||
|
||||
Args:
|
||||
dt: Datetime in UTC (naive or aware)
|
||||
timezone: IANA timezone name for display
|
||||
format_str: Format string (default includes timezone abbreviation)
|
||||
|
||||
Returns:
|
||||
Formatted datetime string with timezone
|
||||
"""
|
||||
dt_tz = convert_from_utc(dt, timezone)
|
||||
return dt_tz.strftime(format_str)
|
||||
|
||||
|
||||
def get_available_timezones():
|
||||
"""Get list of common timezones for user selection."""
|
||||
common_timezones = [
|
||||
"UTC",
|
||||
"Europe/Bucharest",
|
||||
"Europe/London",
|
||||
"Europe/Paris",
|
||||
"Europe/Berlin",
|
||||
"Europe/Amsterdam",
|
||||
"America/New_York",
|
||||
"America/Los_Angeles",
|
||||
"America/Chicago",
|
||||
"America/Denver",
|
||||
"Asia/Tokyo",
|
||||
"Asia/Shanghai",
|
||||
"Asia/Dubai",
|
||||
"Australia/Sydney",
|
||||
]
|
||||
return common_timezones
|
||||
Reference in New Issue
Block a user