
    
Bj                        U d Z ddlZddlZddlmZ ddlmZ ddlmZ  ej                  e	      Z
	 ddlmZ daee   ed<   daee   ed<   d	aeed
<   defdZdedee   fdZdee   fdZdefdZy# e$ r	 ddlmZ Y Iw xY w)u  
Timezone-aware clock for Hermes.

Provides a single ``now()`` helper that returns a timezone-aware datetime
based on the user's configured IANA timezone (e.g. ``Asia/Kolkata``).

Resolution order:
  1. ``HERMES_TIMEZONE`` environment variable
  2. ``timezone`` key in ``~/.hermes/config.yaml``
  3. Falls back to the server's local time (``datetime.now().astimezone()``)

Invalid timezone values log a warning and fall back safely — Hermes never
crashes due to a bad timezone string.
    N)datetime)get_config_path)Optional)ZoneInfo
_cached_tz_cached_tz_nameF_cache_resolvedreturnc                     t        j                  dd      j                         } | r| S 	 ddl}t	               }|j                         rmt        |d      5 }|j                  |      xs i }ddd       j                  dd      }t        |t              r |j                         r|j                         S y# 1 sw Y   LxY w# t        $ r Y yw xY w)zRead the configured IANA timezone string (or empty string).

    This does file I/O when falling through to config.yaml, so callers
    should cache the result rather than calling on every ``now()``.
    HERMES_TIMEZONE r   Nzutf-8)encodingtimezone)osgetenvstripyamlr   existsopen	safe_loadget
isinstancestr	Exception)tz_envr   config_pathfcfgtz_cfgs         0/home/ubuntu/.hermes/hermes-agent/hermes_time.py_resolve_timezone_namer!   %   s     YY("-335F
%'kG4 .nnQ'-2.WWZ,F&#&6<<>||~% . .
  s*   +C B6+A	C 6B?;C 	CCnamec                     | sy	 t        |       S # t        t        f$ r!}t        j	                  d| |       Y d}~yd}~ww xY w)z3Validate and return a ZoneInfo, or None if invalid.Nz=Invalid timezone '%s': %s. Falling back to server local time.)r   KeyErrorr   loggerwarning)r"   excs     r    _get_zoneinfor(   @   sE    ~i  K#	
 s   
 A ;A c                  P    t         st               at        t              ada t        S )zReturn the user's configured ZoneInfo, or None (meaning server-local).

    Resolved once and cached. Call ``reset_cache()`` after config changes.
    T)r	   r!   r   r(   r        r    get_timezoner,   N   s$     02"?3
r+   c                      t               } | t        j                  |       S t        j                         j                         S )z
    Return the current time as a timezone-aware datetime.

    If a valid timezone is configured, returns wall-clock time in that zone.
    Otherwise returns the server's local time (via ``astimezone()``).
    )r,   r   now
astimezone)tzs    r    r.   r.   [   s4     
B	~||B<<>$$&&r+   )__doc__loggingr   r   hermes_constantsr   typingr   	getLogger__name__r%   zoneinfor   ImportErrorbackports.zoneinfor   __annotations__r   r   r	   boolr!   r(   r,   r.   r*   r+   r    <module>r<      s     	  , 			8	$,! "&
HX %!%# %  6  2 
hx( 
'X 'C  ,+,s   A3 3B B