Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 59 additions & 5 deletions cl_sii/libs/tz_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
"""
Timezone utils
==============


Naive and aware
---------------

These concept are defined in Python standard library module datetime
`docs <https://docs.python.org/3/library/datetime.html#module-datetime>`_.

"""
from datetime import datetime
from typing import Union

Expand All @@ -14,8 +26,12 @@
]


UTC = pytz.UTC # type: PytzTimezone
TIMEZONE_CL_SANTIAGO = pytz.timezone('America/Santiago') # type: PytzTimezone
TZ_UTC = pytz.UTC # type: PytzTimezone
TZ_CL_SANTIAGO = pytz.timezone('America/Santiago') # type: PytzTimezone

# TODO: remove
UTC = TZ_UTC
TIMEZONE_CL_SANTIAGO = TZ_CL_SANTIAGO


def get_now_tz_aware() -> datetime:
Expand All @@ -31,7 +47,7 @@ def get_now_tz_aware() -> datetime:
# - `pytz.UTC.localize(datetime.utcnow())`

# source: 'django.utils.timezone.now' @ Django 2.1.3
return datetime.utcnow().replace(tzinfo=UTC)
return datetime.utcnow().replace(tzinfo=TZ_UTC)


def convert_naive_dt_to_tz_aware(dt: datetime, tz: PytzTimezone) -> datetime:
Expand All @@ -44,13 +60,13 @@ def convert_naive_dt_to_tz_aware(dt: datetime, tz: PytzTimezone) -> datetime:
>>> dt_naive.isoformat()
'2018-10-23T01:54:13'

>>> dt_tz_aware_1 = convert_naive_dt_to_tz_aware(dt_naive, UTC)
>>> dt_tz_aware_1 = convert_naive_dt_to_tz_aware(dt_naive, TZ_UTC)
>>> dt_tz_aware_1
datetime.datetime(2018, 10, 23, 1, 54, 13, tzinfo=<UTC>)
>>> dt_tz_aware_1.isoformat()
'2018-10-23T04:54:13+00:00'

>>> dt_tz_aware_2 = convert_naive_dt_to_tz_aware(dt_naive, TIMEZONE_CL_SANTIAGO)
>>> dt_tz_aware_2 = convert_naive_dt_to_tz_aware(dt_naive, TZ_CL_SANTIAGO)
>>> dt_tz_aware_2
datetime.datetime(2018, 10, 23, 1, 54, 13, tzinfo=<DstTzInfo 'America/Santiago'
-03-1 day, 21:00:00 DST>)
Expand All @@ -64,3 +80,41 @@ def convert_naive_dt_to_tz_aware(dt: datetime, tz: PytzTimezone) -> datetime:
"""
dt_tz_aware = tz.localize(dt) # type: datetime
return dt_tz_aware


def dt_is_aware(value: datetime) -> bool:
"""
Return whether datetime ``value`` is "aware".

>>> dt_naive = datetime(2018, 10, 23, 1, 54, 13)
>>> dt_is_aware(dt_naive)
False
>>> dt_is_aware(convert_naive_dt_to_tz_aware(dt_naive, TZ_UTC))
True
>>> dt_is_aware(convert_naive_dt_to_tz_aware(dt_naive, TZ_CL_SANTIAGO))
True

"""
if not isinstance(value, datetime):
raise TypeError
# source: 'django.utils.timezone.is_aware' @ Django 2.1.7
return value.utcoffset() is not None


def dt_is_naive(value: datetime) -> bool:
"""
Return whether datetime ``value`` is "naive".

>>> dt_naive = datetime(2018, 10, 23, 1, 54, 13)
>>> dt_is_naive(dt_naive)
True
>>> dt_is_naive(convert_naive_dt_to_tz_aware(dt_naive, TZ_UTC))
False
>>> dt_is_naive(convert_naive_dt_to_tz_aware(dt_naive, TZ_CL_SANTIAGO))
False

"""
if not isinstance(value, datetime):
raise TypeError
# source: 'django.utils.timezone.is_naive' @ Django 2.1.7
return value.utcoffset() is None
2 changes: 1 addition & 1 deletion cl_sii/rcv/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class _RcvCsvDialect(csv.Dialect):
class RcvCsvRowSchema(marshmallow.Schema):

EXPECTED_INPUT_FIELDS = tuple(_RCV_CSV_EXPECTED_FIELD_NAMES) + (_CSV_ROW_DICT_EXTRA_FIELDS_KEY, ) # type: ignore # noqa: E501
FIELD_FECHA_RECEPCION_DATETIME_TZ = tz_utils.TIMEZONE_CL_SANTIAGO
FIELD_FECHA_RECEPCION_DATETIME_TZ = tz_utils.TZ_CL_SANTIAGO

class Meta:
strict = True
Expand Down
19 changes: 16 additions & 3 deletions tests/test_libs_tz_utils.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
import unittest

from cl_sii.libs.tz_utils import convert_naive_dt_to_tz_aware, get_now_tz_aware # noqa: F401
from cl_sii.libs.tz_utils import ( # noqa: F401
convert_naive_dt_to_tz_aware, dt_is_aware, dt_is_naive, get_now_tz_aware,
PytzTimezone, TZ_CL_SANTIAGO, TZ_UTC,
)


class FunctionsTest(unittest.TestCase):

def test_get_now_tz_aware(self) -> None:
# TODO: implement!
# TODO: implement for 'get_now_tz_aware'
# Reuse doctests/examples in function docstring.
pass

def test_convert_naive_dt_to_tz_aware(self) -> None:
# TODO: implement!
# TODO: implement for 'convert_naive_dt_to_tz_aware'
# Reuse doctests/examples in function docstring.
pass

def test_dt_is_aware(self) -> None:
# TODO: implement for 'dt_is_aware'
# Reuse doctests/examples in function docstring.
pass

def test_dt_is_naive(self) -> None:
# TODO: implement for 'dt_is_naive'
# Reuse doctests/examples in function docstring.
pass