feat: add make_utc() function, app method
as prep for dropping timezone from DB columns
This commit is contained in:
parent
1a3756f47c
commit
900937826c
4 changed files with 107 additions and 0 deletions
|
|
@ -39,6 +39,7 @@ from wuttjamaican.util import (
|
||||||
load_object,
|
load_object,
|
||||||
make_title,
|
make_title,
|
||||||
make_full_name,
|
make_full_name,
|
||||||
|
make_utc,
|
||||||
make_uuid,
|
make_uuid,
|
||||||
make_true_uuid,
|
make_true_uuid,
|
||||||
progress_loop,
|
progress_loop,
|
||||||
|
|
@ -526,6 +527,14 @@ class AppHandler: # pylint: disable=too-many-public-methods
|
||||||
"""
|
"""
|
||||||
return make_full_name(*parts)
|
return make_full_name(*parts)
|
||||||
|
|
||||||
|
def make_utc(self, dt=None, tzinfo=False):
|
||||||
|
"""
|
||||||
|
This returns a datetime local to the UTC timezone. It is a
|
||||||
|
convenience wrapper around
|
||||||
|
:func:`~wuttjamaican.util.make_utc()`.
|
||||||
|
"""
|
||||||
|
return make_utc(dt=dt, tzinfo=tzinfo)
|
||||||
|
|
||||||
def make_true_uuid(self):
|
def make_true_uuid(self):
|
||||||
"""
|
"""
|
||||||
Generate a new UUID value.
|
Generate a new UUID value.
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
WuttJamaican - utilities
|
WuttJamaican - utilities
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
import importlib
|
import importlib
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
@ -189,6 +190,50 @@ def make_full_name(*parts):
|
||||||
return " ".join(parts)
|
return " ".join(parts)
|
||||||
|
|
||||||
|
|
||||||
|
def make_utc(dt=None, tzinfo=False):
|
||||||
|
"""
|
||||||
|
This returns a datetime local to the UTC timezone. By default it
|
||||||
|
will be a *naive* datetime; the common use case is to convert as
|
||||||
|
needed for sake of writing to the database.
|
||||||
|
|
||||||
|
See also the shortcut
|
||||||
|
:meth:`~wuttjamaican.app.AppHandler.make_utc()` method on the app
|
||||||
|
handler.
|
||||||
|
|
||||||
|
: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 false by default in which case the return value
|
||||||
|
will be naive.
|
||||||
|
|
||||||
|
:returns: :class:`python:datetime.datetime` instance local to UTC.
|
||||||
|
"""
|
||||||
|
# use current time if none provided
|
||||||
|
if dt is None:
|
||||||
|
now = datetime.datetime.now(datetime.timezone.utc)
|
||||||
|
if tzinfo:
|
||||||
|
return now
|
||||||
|
return now.replace(tzinfo=None)
|
||||||
|
|
||||||
|
# otherwise may need to convert timezone
|
||||||
|
if dt.tzinfo:
|
||||||
|
if dt.tzinfo is not datetime.timezone.utc:
|
||||||
|
dt = dt.astimezone(datetime.timezone.utc)
|
||||||
|
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
|
||||||
|
return dt.replace(tzinfo=datetime.timezone.utc)
|
||||||
|
|
||||||
|
|
||||||
def make_true_uuid():
|
def make_true_uuid():
|
||||||
"""
|
"""
|
||||||
Generate a new v7 UUID value.
|
Generate a new v7 UUID value.
|
||||||
|
|
|
||||||
|
|
@ -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_make_utc(self):
|
||||||
|
dt = self.app.make_utc()
|
||||||
|
self.assertIsInstance(dt, datetime.datetime)
|
||||||
|
self.assertIsNone(dt.tzinfo)
|
||||||
|
|
||||||
def test_make_uuid(self):
|
def test_make_uuid(self):
|
||||||
uuid = self.app.make_uuid()
|
uuid = self.app.make_uuid()
|
||||||
self.assertEqual(len(uuid), 32)
|
self.assertEqual(len(uuid), 32)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- coding: utf-8; -*-
|
# -*- coding: utf-8; -*-
|
||||||
|
|
||||||
|
import datetime
|
||||||
import sys
|
import sys
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from unittest.mock import patch, MagicMock
|
from unittest.mock import patch, MagicMock
|
||||||
|
|
@ -164,6 +165,53 @@ class TestLoadObject(TestCase):
|
||||||
self.assertIs(result, TestCase)
|
self.assertIs(result, TestCase)
|
||||||
|
|
||||||
|
|
||||||
|
class TestMakeUTC(TestCase):
|
||||||
|
|
||||||
|
def test_current_time(self):
|
||||||
|
|
||||||
|
# no tzinfo by default
|
||||||
|
dt = mod.make_utc()
|
||||||
|
self.assertIsInstance(dt, datetime.datetime)
|
||||||
|
self.assertIsNone(dt.tzinfo)
|
||||||
|
now = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
|
||||||
|
self.assertAlmostEqual(int(dt.timestamp()), int(now.timestamp()))
|
||||||
|
|
||||||
|
# with tzinfo
|
||||||
|
dt = mod.make_utc(tzinfo=True)
|
||||||
|
self.assertIsInstance(dt, datetime.datetime)
|
||||||
|
self.assertIs(dt.tzinfo, datetime.timezone.utc)
|
||||||
|
now = datetime.datetime.now(datetime.timezone.utc)
|
||||||
|
self.assertAlmostEqual(int(dt.timestamp()), int(now.timestamp()))
|
||||||
|
|
||||||
|
def test_convert_with_tzinfo(self):
|
||||||
|
sample = datetime.datetime(
|
||||||
|
2024, 9, 15, 8, 30, tzinfo=datetime.timezone(-datetime.timedelta(hours=5))
|
||||||
|
)
|
||||||
|
|
||||||
|
# no tzinfo by default
|
||||||
|
dt = mod.make_utc(sample)
|
||||||
|
self.assertEqual(dt, datetime.datetime(2024, 9, 15, 13, 30, tzinfo=None))
|
||||||
|
|
||||||
|
# with tzinfo
|
||||||
|
dt = mod.make_utc(sample, tzinfo=True)
|
||||||
|
self.assertEqual(
|
||||||
|
dt, datetime.datetime(2024, 9, 15, 13, 30, tzinfo=datetime.timezone.utc)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_convert_without_tzinfo(self):
|
||||||
|
sample = datetime.datetime(2024, 9, 15, 8, 30)
|
||||||
|
|
||||||
|
# no tzinfo by default
|
||||||
|
dt = mod.make_utc(sample)
|
||||||
|
self.assertEqual(dt, datetime.datetime(2024, 9, 15, 8, 30, tzinfo=None))
|
||||||
|
|
||||||
|
# with tzinfo
|
||||||
|
dt = mod.make_utc(sample, tzinfo=True)
|
||||||
|
self.assertEqual(
|
||||||
|
dt, datetime.datetime(2024, 9, 15, 8, 30, tzinfo=datetime.timezone.utc)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestMakeUUID(TestCase):
|
class TestMakeUUID(TestCase):
|
||||||
|
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue