Skip to content

Commit c1c1919

Browse files
author
Roy Smith
committed
Initial commit of TimedeltaField, with some really basic tests.
1 parent b58d74b commit c1c1919

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

fields/fields.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from datetime import timedelta
2+
from mongoengine.base import BaseField
3+
4+
class TimedeltaField(BaseField):
5+
"""A timedelta field.
6+
7+
Looks to the outside world like a datatime.timedelta, but stores
8+
in the database as an integer (or float) number of seconds.
9+
10+
"""
11+
def validate(self, value):
12+
if not isinstance(value, (timedelta, int, float)):
13+
self.error(u'cannot parse timedelta "%r"' % value)
14+
15+
def to_mongo(self, value):
16+
return self.prepare_query_value(None, value)
17+
18+
def to_python(self, value):
19+
return timedelta(seconds=value)
20+
21+
def prepare_query_value(self, op, value):
22+
if value is None:
23+
return value
24+
if isinstance(value, timedelta):
25+
return self.total_seconds(value)
26+
if isinstance(value, (int, float)):
27+
return value
28+
29+
@staticmethod
30+
def total_seconds(value):
31+
"""Implements Python 2.7's datetime.timedelta.total_seconds()
32+
for backwards compatibility with Python 2.5 and 2.6.
33+
34+
"""
35+
try:
36+
return value.total_seconds()
37+
except AttributeError:
38+
return (value.days * 24 * 3600) + \
39+
(value.seconds) + \
40+
(value.microseconds / 1000000.0)

fields/test_fields.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import unittest2 as unittest
2+
from datetime import timedelta
3+
from fields import TimedeltaField
4+
5+
class OldStyleTimedelta(timedelta):
6+
"Used for backwards compatibility testing"
7+
def total_seconds(self):
8+
raise AttributeError
9+
10+
class TimedeltaFieldTestCase(unittest.TestCase):
11+
def setUp(self):
12+
self.field = TimedeltaField()
13+
14+
def test_construct(self):
15+
self.assertIsInstance(self.field, TimedeltaField)
16+
17+
def test_total_seconds(self):
18+
value = timedelta(minutes=1, seconds=10)
19+
self.assertEqual(self.field.total_seconds(value), 70)
20+
21+
def test_total_seconds_26(self):
22+
value = OldStyleTimedelta(minutes=1, seconds=10)
23+
self.assertEqual(self.field.total_seconds(value), 70)
24+
25+
if __name__ == '__main__':
26+
unittest.main()

0 commit comments

Comments
 (0)