From d737e29c6f9c3fcbdafce5f184b8cb3b234db006 Mon Sep 17 00:00:00 2001 From: Yehuda Deutsch Date: Fri, 31 Jul 2020 22:54:23 +0300 Subject: [PATCH] Add timezone option --- time_app/helpers/datetime.py | 19 ++++++++++++++++--- time_app/helpers/views.py | 11 +++++++++++ time_app/views/api.py | 12 ++++++------ time_app/views/main.py | 13 +++++++++---- 4 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 time_app/helpers/views.py diff --git a/time_app/helpers/datetime.py b/time_app/helpers/datetime.py index 69b5afa..a872a5e 100644 --- a/time_app/helpers/datetime.py +++ b/time_app/helpers/datetime.py @@ -1,8 +1,21 @@ from datetime import datetime -from zoneinfo import ZoneInfo +from zoneinfo import ZoneInfo, available_timezones -utc = ZoneInfo('UTC') +ALLOWED_TIMEZONES = available_timezones() +DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S' + + +def tz_aware_now(zone: str) -> datetime: + """ + :param str zone: Zone name in DB + :return: A timezone aware datetime object + :raises: ValueError When zone name is not supported + """ + # ZoneInfo uses a weak cache, no need to implement a local cache + if zone not in ALLOWED_TIMEZONES: + raise ValueError(f'Unsupported timezone "{zone}"') + return datetime.now(tz=ZoneInfo(zone)) def real_utc_now() -> datetime: - return datetime.now(tz=utc) + return tz_aware_now('UTC') diff --git a/time_app/helpers/views.py b/time_app/helpers/views.py new file mode 100644 index 0000000..6789841 --- /dev/null +++ b/time_app/helpers/views.py @@ -0,0 +1,11 @@ +from fastapi import HTTPException + +from .datetime import tz_aware_now + + +def get_now_in_view(zone: str = 'UTC'): + try: + now = tz_aware_now(zone=zone) + except ValueError: + raise HTTPException(status_code=400, detail=f'Zone "{zone}" is unsupported') + return now diff --git a/time_app/views/api.py b/time_app/views/api.py index deb03f4..3bf64eb 100644 --- a/time_app/views/api.py +++ b/time_app/views/api.py @@ -1,16 +1,16 @@ from fastapi import APIRouter -from time_app.helpers.datetime import real_utc_now +from time_app.helpers.views import get_now_in_view from time_app.models.main import Now router = APIRouter() -@router.get('/', name='Now', response_model=Now) -def now_view() -> dict: - return {"time": real_utc_now().strftime('%Y-%m-%d %H:%M:%S')} +@router.get('/now', name='Now', response_model=Now) +def now_view(zone: str = 'UTC') -> dict: + return {"time": f'{get_now_in_view(zone):%Y-%m-%d %H:%M:%S}'} @router.get('/diy', name='Day in year', response_model=Now) -def day_in_year_view() -> dict: - return {"time": real_utc_now().strftime('%y%j')[-4:]} +def day_in_year_view(zone: str = 'UTC') -> dict: + return {"time": f'{get_now_in_view(zone):%y%j}'[-4:]} diff --git a/time_app/views/main.py b/time_app/views/main.py index 9e10152..2fa9dad 100644 --- a/time_app/views/main.py +++ b/time_app/views/main.py @@ -1,15 +1,20 @@ from fastapi import APIRouter -from time_app.helpers.datetime import real_utc_now +from time_app.helpers.views import get_now_in_view router = APIRouter() @router.get('/', name='Now') def now_view() -> str: - return real_utc_now().strftime('%Y-%m-%d %H:%M:%S') + return f'{get_now_in_view():%Y-%m-%d %H:%M:%S}' + + +@router.get('/now', name='Now') +def now_view(zone: str = 'UTC') -> str: + return f'{get_now_in_view(zone):%Y-%m-%d %H:%M:%S}' @router.get('/diy', name='Day in year') -def day_in_year_view() -> str: - return real_utc_now().strftime('%y%j')[-4:] +def day_in_year_view(zone: str = 'UTC') -> str: + return f'{get_now_in_view(zone):%y%j}'[-4:]