-
Notifications
You must be signed in to change notification settings - Fork 1
/
HumanTime.py
91 lines (83 loc) · 2.83 KB
/
HumanTime.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import datetime, pytz
import re
import tzlocal
def date2human(when, slack_secs=180):
""" Convert timestamp to human-friendly times, like '3 minutes ago' """
if not when:
return None
now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
diff = now-when
secs = diff.seconds
days = diff.days
if days > 0:
return str(when)
if secs >= 3600:
if (secs<7200):
return '1 hour ago'
else:
return str(secs/3600)+' hours ago'
else:
if (secs <slack_secs):
return 'a moment ago'
else:
return str(secs/60)+' minutes ago'
def human2date(when, past=True):
"""UTC timestamps from human 'encoding' like '2 hours ago'. Human
timestamps are relative to local time zone."""
# This is not millisecond precise...
local_tz = tzlocal.get_localzone()
now = datetime.datetime.now().replace(tzinfo=local_tz)
utcnow = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
if when == 'now':
return utcnow
if when == 'today':
want = now.replace(hour=0, minute=0, second=0, microsecond=0)
if not past:
want += datetime.timedelta(days=1)
newtime = utcnow-(now-want)
return newtime
if when == 'yesterday':
want = now.replace(hour=0, minute=0, second=0, microsecond=0)
newtime = utcnow-(now-want)
return newtime-datetime.timedelta(days=1)
in_past = in_future = False
if when.endswith(' ago'):
in_past = True
if when.startswith('in ') or when.startswith('after '):
in_future = True
if in_past and in_future:
raise TypeError('Time cannot be in the past and in the future')
r = re.compile('(\d+) days?( ago)?')
m = r.match(when)
if m:
td = datetime.timedelta(days=float(m.group(1)))
return utcnow-td
r = re.compile('(\d+) hours?( ago)?')
m = r.match(when)
if m:
td = datetime.timedelta(hours=float(m.group(1)))
return utcnow-td
r = re.compile('(\d+) minutes?( ago)?')
m = r.match(when)
if m:
td = datetime.timedelta(minutes=float(m.group(1)))
return utcnow-td
formats = ['%H:%M']
for fmt in formats:
try:
td = datetime.datetime.strptime(when, fmt).replace(tzinfo=local_tz)
new = now
if '%H' in fmt:
new = new.replace(hour=td.hour)
if '%M' in fmt:
new = new.replace(minute=td.minute)
if '%S' in fmt:
new = new.replace(second=td.second)
else:
new = new.replace(second=0)
if '%d' in fmt:
new = new.replace(day=td.day)
return new
except ValueError:
pass
return datetime.datetime.strptime(when, '%Y-%m-%dT%H:%M:%SZ').replace(tzinfo=pytz.utc)