HPI/my/time/tz/common.py
seanbreckenridge 2cb836181b
location: add all.py, using takeout/gpslogger/ip (#237)
* location: add all.py, using takeout/gpslogger/ip, update docs
2022-04-26 21:11:35 +01:00

44 lines
1.6 KiB
Python

from datetime import datetime
from typing import Callable, cast
from ...core.common import tzdatetime, Literal
'''
Depending on the specific data provider and your level of paranoia you might expect different behaviour.. E.g.:
- if your objects already have tz info, you might not need to call localize() at all
- it's safer when either all of your objects are tz aware or all are tz unware, not a mixture
- you might trust your original timezone, or it might just be UTC, and you want to use something more reasonable
'''
TzPolicy = Literal[
'keep' , # if datetime is tz aware, just preserve it
'convert', # if datetime is tz aware, convert to provider's tz
'throw' , # if datetime is tz aware, throw exception
# todo 'warn'? not sure if very useful
]
# backwards compatibility
Policy = TzPolicy
def default_policy() -> TzPolicy:
try:
from my.config import time as user_config
return cast(TzPolicy, user_config.tz.policy)
except Exception as e:
# todo meh.. need to think how to do this more carefully
# rationale: do not mess with user's data unless they want
return 'keep'
def localize_with_policy(lfun: Callable[[datetime], tzdatetime], dt: datetime, policy: TzPolicy=default_policy()) -> tzdatetime:
tz = dt.tzinfo
if tz is None:
return lfun(dt)
if policy == 'keep':
return dt
elif policy == 'convert':
ldt = lfun(dt.replace(tzinfo=None))
return dt.astimezone(ldt.tzinfo)
else: # policy == 'error':
raise RuntimeError(f"{dt} already has timezone information (use 'policy' argument to adjust this behaviour)")