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
|
import humanize
|
||||||
|
|
||||||
from wuttjamaican.util import (
|
from wuttjamaican.util import (
|
||||||
|
localtime,
|
||||||
load_entry_points,
|
load_entry_points,
|
||||||
load_object,
|
load_object,
|
||||||
make_title,
|
make_title,
|
||||||
|
|
@ -527,6 +528,14 @@ class AppHandler: # pylint: disable=too-many-public-methods
|
||||||
"""
|
"""
|
||||||
return make_full_name(*parts)
|
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):
|
def make_utc(self, dt=None, tzinfo=False):
|
||||||
"""
|
"""
|
||||||
This returns a datetime local to the UTC timezone. It is a
|
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:
|
if value is None:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
if not value.tzinfo:
|
||||||
|
value = self.localtime(value)
|
||||||
|
|
||||||
return value.strftime(self.display_format_datetime)
|
return value.strftime(self.display_format_datetime)
|
||||||
|
|
||||||
def render_error(self, error):
|
def render_error(self, error):
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,58 @@ def make_full_name(*parts):
|
||||||
return " ".join(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):
|
def make_utc(dt=None, tzinfo=False):
|
||||||
"""
|
"""
|
||||||
This returns a datetime local to the UTC timezone. By default it
|
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
|
:meth:`~wuttjamaican.app.AppHandler.make_utc()` method on the app
|
||||||
handler.
|
handler.
|
||||||
|
|
||||||
|
See also :func:`localtime()` which is sort of the inverse.
|
||||||
|
|
||||||
:param dt: Optional :class:`python:datetime.datetime` instance.
|
:param dt: Optional :class:`python:datetime.datetime` instance.
|
||||||
If not specified, the current time will be used.
|
If not specified, the current time will be used.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -426,6 +426,11 @@ app_title = WuttaTest
|
||||||
name = self.app.make_full_name("Fred", "", "Flintstone", "")
|
name = self.app.make_full_name("Fred", "", "Flintstone", "")
|
||||||
self.assertEqual(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):
|
def test_make_utc(self):
|
||||||
dt = self.app.make_utc()
|
dt = self.app.make_utc()
|
||||||
self.assertIsInstance(dt, datetime.datetime)
|
self.assertIsInstance(dt, datetime.datetime)
|
||||||
|
|
@ -516,6 +521,11 @@ app_title = WuttaTest
|
||||||
dt = datetime.datetime(2024, 12, 11, 8, 30, tzinfo=datetime.timezone.utc)
|
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")
|
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):
|
def test_render_error(self):
|
||||||
|
|
||||||
# with description
|
# with description
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,51 @@ class TestLoadObject(TestCase):
|
||||||
self.assertIs(result, 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):
|
class TestMakeUTC(TestCase):
|
||||||
|
|
||||||
def test_current_time(self):
|
def test_current_time(self):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue