-
Notifications
You must be signed in to change notification settings - Fork 0
/
durations.py
63 lines (53 loc) · 1.44 KB
/
durations.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
'''
A handy shortcut wrapper for python datetimes and relativedeltas.
e.g.
>>> from durations import *
>>> days
Duration(days=+1)
>>> days.ago
Lazy<mul on Duration(days=+1)>
>>> 2*days.ago
datetime.datetime(2018, 3, 20, 2, 51, 49, 206979, tzinfo=<UTC>)
>>> 2*days.ago + 3*hours
datetime.datetime(2018, 3, 20, 5, 51, 57, 230161, tzinfo=<UTC>)
'''
import operator
from datetime import datetime
from pytz import utc
from dateutil.relativedelta import relativedelta
def now():
return datetime.utcnow().replace(tzinfo=utc)
def compose_defer(opname, deferred, obj):
class lazy(object):
def __repr__(self):
return 'Lazy<{op} on {obj}>'.format(
op = opname,
obj = obj,
)
def resolve(self, other):
op = getattr(operator, opname)
return deferred(op(other, obj))
for attr in ('__{}__','__r{}__'):
setattr(lazy, attr.format(opname), resolve)
return lazy()
class Duration(relativedelta):
@property
def ago(self):
return compose_defer(
'mul',
lambda delta: now() - delta,
self,
)
@property
def from_now(self):
return compose_defer(
'mul',
lambda delta: now() + delta,
self,
)
seconds = Duration(seconds=1)
minutes = Duration(minutes=1)
hours = Duration(hours=1)
days = Duration(days=1)
weeks = Duration(weeks=1)
months = Duration(months=1)