feat: add localtime() function, app method
This commit is contained in:
parent
e76a6e5f6d
commit
dac91406c7
4 changed files with 122 additions and 0 deletions
|
|
@ -35,6 +35,7 @@ from importlib.metadata import version
|
|||
import humanize
|
||||
|
||||
from wuttjamaican.util import (
|
||||
localtime,
|
||||
load_entry_points,
|
||||
load_object,
|
||||
make_title,
|
||||
|
|
@ -527,6 +528,14 @@ class AppHandler: # pylint: disable=too-many-public-methods
|
|||
"""
|
||||
return make_full_name(*parts)
|
||||
|
||||
def localtime(self, dt=None, tzinfo=True):
|
||||
"""
|
||||
This returns a datetime in the system-local timezone. It is a
|
||||
convenience wrapper around
|
||||
:func:`~wuttjamaican.util.localtime()`.
|
||||
"""
|
||||
return localtime(dt=dt, tzinfo=tzinfo)
|
||||
|
||||
def make_utc(self, dt=None, tzinfo=False):
|
||||
"""
|
||||
This returns a datetime local to the UTC timezone. It is a
|
||||
|
|
@ -799,6 +808,10 @@ class AppHandler: # pylint: disable=too-many-public-methods
|
|||
"""
|
||||
if value is None:
|
||||
return ""
|
||||
|
||||
if not value.tzinfo:
|
||||
value = self.localtime(value)
|
||||
|
||||
return value.strftime(self.display_format_datetime)
|
||||
|
||||
def render_error(self, error):
|
||||
|
|
|
|||
|
|
@ -190,6 +190,58 @@ def make_full_name(*parts):
|
|||
return " ".join(parts)
|
||||
|
||||
|
||||
def localtime(dt=None, tzinfo=True):
|
||||
"""
|
||||
This returns a datetime in the system-local timezone. By default
|
||||
it will be *zone-aware*.
|
||||
|
||||
See also the shortcut
|
||||
:meth:`~wuttjamaican.app.AppHandler.localtime()` method on the app
|
||||
handler.
|
||||
|
||||
See also :func:`make_utc()` which is sort of the inverse.
|
||||
|
||||
:param dt: Optional :class:`python:datetime.datetime` instance.
|
||||
If not specified, the current time will be used.
|
||||
|
||||
:param tzinfo: Boolean indicating whether the return value should
|
||||
have its :attr:`~python:datetime.datetime.tzinfo` attribute
|
||||
set. This is true by default in which case the return value
|
||||
will be zone-aware.
|
||||
|
||||
:returns: :class:`python:datetime.datetime` instance in
|
||||
system-local timezone.
|
||||
"""
|
||||
# thanks to this stackoverflow post for the timezone logic,
|
||||
# since as of now we don't have that anywhere in config.
|
||||
# https://stackoverflow.com/a/39079819
|
||||
# https://docs.python.org/3/library/datetime.html#datetime.datetime.astimezone
|
||||
|
||||
# use current time if none provided
|
||||
if dt is None:
|
||||
dt = datetime.datetime.now(datetime.timezone.utc)
|
||||
dt = dt.astimezone()
|
||||
if tzinfo:
|
||||
return dt
|
||||
return dt.replace(tzinfo=None)
|
||||
|
||||
# otherwise may need to convert timezone
|
||||
if dt.tzinfo:
|
||||
dt = dt.astimezone()
|
||||
if tzinfo:
|
||||
return dt
|
||||
return dt.replace(tzinfo=None)
|
||||
|
||||
# naive value returned as-is..
|
||||
if not tzinfo:
|
||||
return dt
|
||||
|
||||
# ..unless tzinfo is wanted, in which case this assumes naive
|
||||
# value is in the UTC timezone
|
||||
dt = dt.replace(tzinfo=datetime.timezone.utc)
|
||||
return dt.astimezone()
|
||||
|
||||
|
||||
def make_utc(dt=None, tzinfo=False):
|
||||
"""
|
||||
This returns a datetime local to the UTC timezone. By default it
|
||||
|
|
@ -200,6 +252,8 @@ def make_utc(dt=None, tzinfo=False):
|
|||
:meth:`~wuttjamaican.app.AppHandler.make_utc()` method on the app
|
||||
handler.
|
||||
|
||||
See also :func:`localtime()` which is sort of the inverse.
|
||||
|
||||
:param dt: Optional :class:`python:datetime.datetime` instance.
|
||||
If not specified, the current time will be used.
|
||||
|
||||
|
|
|
|||
|
|
@ -426,6 +426,11 @@ app_title = WuttaTest
|
|||
name = self.app.make_full_name("Fred", "", "Flintstone", "")
|
||||
self.assertEqual(name, "Fred Flintstone")
|
||||
|
||||
def test_localtime(self):
|
||||
dt = self.app.localtime()
|
||||
self.assertIsInstance(dt, datetime.datetime)
|
||||
self.assertIsNotNone(dt.tzinfo)
|
||||
|
||||
def test_make_utc(self):
|
||||
dt = self.app.make_utc()
|
||||
self.assertIsInstance(dt, datetime.datetime)
|
||||
|
|
@ -516,6 +521,11 @@ app_title = WuttaTest
|
|||
dt = datetime.datetime(2024, 12, 11, 8, 30, tzinfo=datetime.timezone.utc)
|
||||
self.assertEqual(self.app.render_datetime(dt), "2024-12-11 08:30+0000")
|
||||
|
||||
dt = datetime.datetime(2024, 12, 11, 8, 30)
|
||||
text = self.app.render_datetime(dt)
|
||||
# TODO: should override local timezone for more complete test
|
||||
self.assertTrue(text.startswith("2024-12-"))
|
||||
|
||||
def test_render_error(self):
|
||||
|
||||
# with description
|
||||
|
|
|
|||
|
|
@ -165,6 +165,51 @@ class TestLoadObject(TestCase):
|
|||
self.assertIs(result, TestCase)
|
||||
|
||||
|
||||
class TestLocaltime(TestCase):
|
||||
|
||||
def test_current_time(self):
|
||||
|
||||
# has tzinfo by default
|
||||
dt = mod.localtime()
|
||||
self.assertIsInstance(dt, datetime.datetime)
|
||||
self.assertIsNotNone(dt.tzinfo)
|
||||
now = datetime.datetime.now()
|
||||
self.assertAlmostEqual(int(dt.timestamp()), int(now.timestamp()))
|
||||
|
||||
# no tzinfo
|
||||
dt = mod.localtime(tzinfo=False)
|
||||
self.assertIsInstance(dt, datetime.datetime)
|
||||
self.assertIsNone(dt.tzinfo)
|
||||
now = datetime.datetime.now()
|
||||
self.assertAlmostEqual(int(dt.timestamp()), int(now.timestamp()))
|
||||
|
||||
def test_convert_with_tzinfo(self):
|
||||
sample = datetime.datetime(2024, 9, 15, 13, 30, tzinfo=datetime.timezone.utc)
|
||||
|
||||
# has tzinfo by default
|
||||
dt = mod.localtime(sample)
|
||||
self.assertIsInstance(dt, datetime.datetime)
|
||||
self.assertIsNotNone(dt.tzinfo)
|
||||
|
||||
# no tzinfo
|
||||
dt = mod.localtime(sample, tzinfo=False)
|
||||
self.assertIsInstance(dt, datetime.datetime)
|
||||
self.assertIsNone(dt.tzinfo)
|
||||
|
||||
def test_convert_without_tzinfo(self):
|
||||
sample = datetime.datetime(2024, 9, 15, 13, 30)
|
||||
|
||||
# has tzinfo by default
|
||||
dt = mod.localtime(sample)
|
||||
self.assertIsInstance(dt, datetime.datetime)
|
||||
self.assertIsNotNone(dt.tzinfo)
|
||||
|
||||
# no tzinfo
|
||||
dt = mod.localtime(sample, tzinfo=False)
|
||||
self.assertIsInstance(dt, datetime.datetime)
|
||||
self.assertIsNone(dt.tzinfo)
|
||||
|
||||
|
||||
class TestMakeUTC(TestCase):
|
||||
|
||||
def test_current_time(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue