Skip to content

Commit

Permalink
Merge pull request #35527 from dimagi/mjr/extract-datetime-logic
Browse files Browse the repository at this point in the history
Extract DateTime logic
  • Loading branch information
mjriley authored Dec 20, 2024
2 parents d555313 + 3d489ca commit 349a0d3
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 12 deletions.
4 changes: 2 additions & 2 deletions corehq/apps/reports/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

from dimagi.utils.dates import DateSpan
from dimagi.utils.logging import notify_exception
from dimagi.utils.parsing import ISO_DATETIME_FORMAT
from dimagi.ext.jsonobject import DateTimeProperty

from celery.schedules import crontab

Expand Down Expand Up @@ -880,6 +880,6 @@ def get_commcare_version_and_date_from_last_usage(last_submission=None, last_dev
version_in_use = format_commcare_version(version) if formatted else version

if date_of_use:
date_of_use = datetime.strptime(date_of_use, ISO_DATETIME_FORMAT)
date_of_use = DateTimeProperty.deserialize(date_of_use)

return version_in_use, date_of_use
17 changes: 11 additions & 6 deletions corehq/ex-submodules/dimagi/ext/jsonobject.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import datetime
import decimal
from jsonobject.base_properties import AbstractDateProperty
from jsonobject import *
from jsonobject import * # noqa: F401 unnamed jsonobject imports are imported from here by other modules
from jsonobject import DateTimeProperty, JsonObject
import re
from jsonobject.api import re_date, re_time, re_decimal
from dimagi.utils.dates import safe_strftime
Expand Down Expand Up @@ -41,6 +42,15 @@ class DateTimeProperty(AbstractDateProperty):
_type = datetime.datetime

def _wrap(self, value):
return self.deserialize(value)

def _unwrap(self, value):
_assert(value.tzinfo is None,
"Can't set a USecDateTimeProperty to an offset-aware datetime")
return value, safe_strftime(value, ISO_DATETIME_FORMAT)

@classmethod
def deserialize(cls, value):
if '.' in value:
fmt = ISO_DATETIME_FORMAT
if len(value.split('.')[-1]) != 7:
Expand All @@ -62,11 +72,6 @@ def _wrap(self, value):
"USecDateTimeProperty shouldn't ever return offset-aware!")
return result

def _unwrap(self, value):
_assert(value.tzinfo is None,
"Can't set a USecDateTimeProperty to an offset-aware datetime")
return value, safe_strftime(value, '%Y-%m-%dT%H:%M:%S.%fZ')


re_trans_datetime = re.compile(r"""
^
Expand Down
24 changes: 20 additions & 4 deletions corehq/ex-submodules/dimagi/ext/tests/test_jsonobject.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import datetime
from datetime import datetime
from django.test import SimpleTestCase
import jsonobject
from jsonobject.exceptions import BadValueError
Expand All @@ -12,13 +12,12 @@ class Foo(jsonobject.JsonObject):
class TransitionalExactDateTimePropertyTest(SimpleTestCase):
def test_wrap_old(self):
foo = Foo.wrap({'bar': '2015-01-01T12:00:00Z'})
self.assertEqual(foo.bar, datetime.datetime(2015, 1, 1, 12, 0, 0, 0))
self.assertEqual(foo.bar, datetime(2015, 1, 1, 12, 0, 0, 0))
self.assertEqual(foo.to_json()['bar'], '2015-01-01T12:00:00.000000Z')

def test_wrap_new(self):
foo = Foo.wrap({'bar': '2015-01-01T12:00:00.120054Z'})
self.assertEqual(foo.bar, datetime.datetime(2015, 1, 1, 12, 0, 0,
120054))
self.assertEqual(foo.bar, datetime(2015, 1, 1, 12, 0, 0, 120054))
self.assertEqual(foo.to_json()['bar'], '2015-01-01T12:00:00.120054Z')

def test_wrap_milliseconds_only(self):
Expand Down Expand Up @@ -48,3 +47,20 @@ def test_strict_match(self):
]
for candidate, expected in cases:
self.assertEqual(bool(re_trans_datetime.match(candidate)), expected, candidate)


class DateTimePropertyTests(SimpleTestCase):
def test_wrap(self):
prop = DateTimeProperty()
result = prop.wrap('2015-01-01T12:00:00.120054Z')
self.assertEqual(result, datetime(year=2015, month=1, day=1, hour=12, microsecond=120054))

def test_unwrap(self):
prop = DateTimeProperty()
(value, unwrapped) = prop.unwrap(datetime(year=2015, month=1, day=1, hour=12, microsecond=120054))
self.assertEqual(value, datetime(year=2015, month=1, day=1, hour=12, microsecond=120054))
self.assertEqual(unwrapped, '2015-01-01T12:00:00.120054Z')

def test_deserialize(self):
result = DateTimeProperty.deserialize('2015-01-01T12:00:00.120054Z')
self.assertEqual(result, datetime(year=2015, month=1, day=1, hour=12, microsecond=120054))

0 comments on commit 349a0d3

Please sign in to comment.