Files
Odoo-Modules/fusion_clock/models/tz_utils.py
gsinghpal e56974d46f update
2026-03-16 08:14:56 -04:00

76 lines
2.4 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
"""
Timezone helpers for Fusion Clock.
All Odoo datetimes are stored in UTC. These helpers derive "today",
date boundaries, and display strings in the **user's local timezone**
so that queries, penalties, and UI all reflect the real calendar day.
Timezone resolution order:
1. Explicit employee.tz (if an employee record is available)
2. env.user.tz (logged-in portal / backend user)
3. env.company.tz (company-level default)
4. 'UTC' (last resort — should rarely happen)
"""
import pytz
from datetime import datetime, timedelta
def _resolve_tz(env, employee=None):
"""Return a pytz timezone from the best available source."""
tz_name = (
(employee.tz if employee else None)
or env.user.tz
or env.company.tz
or 'UTC'
)
try:
return pytz.timezone(tz_name)
except pytz.UnknownTimeZoneError:
return pytz.UTC
def get_local_now(env, employee=None):
"""Return the current datetime in the resolved local timezone (aware)."""
tz = _resolve_tz(env, employee)
return datetime.now(pytz.UTC).astimezone(tz)
def get_local_today(env, employee=None):
"""Return today's date in the resolved local timezone."""
return get_local_now(env, employee).date()
def get_local_day_boundaries(env, date_val, employee=None):
"""
Return (start_utc, end_utc) as **naive** UTC datetimes representing
midnight-to-midnight of *date_val* in the local timezone.
Suitable for Odoo domain filters like:
('check_in', '>=', start_utc),
('check_in', '<', end_utc),
"""
tz = _resolve_tz(env, employee)
local_start = tz.localize(datetime.combine(date_val, datetime.min.time()))
local_end = tz.localize(datetime.combine(date_val + timedelta(days=1), datetime.min.time()))
return (
local_start.astimezone(pytz.UTC).replace(tzinfo=None),
local_end.astimezone(pytz.UTC).replace(tzinfo=None),
)
def utc_to_local_str(dt_utc, env, employee=None, fmt='%I:%M %p'):
"""
Convert a naive-UTC datetime to a formatted string in local timezone.
Returns '' if dt_utc is falsy.
"""
if not dt_utc:
return ''
tz = _resolve_tz(env, employee)
aware = pytz.UTC.localize(dt_utc)
return aware.astimezone(tz).strftime(fmt)