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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
Date Display
============
We aim for "friendly" display of dates. That means we prefer to express the
date "relative to the present" when it is close to now. Instead of saying
"2007-12-15 06:15 EST" we say "3 minutes ago" or "in 18 seconds".
There are two TALES formatters:
o fmt:approximatedate does the hard work of turning a timestamp into an
relative time description. It should be used for tabular data. For
example:
Product Registered Registrant
======= ========== ==========
foobar *3 minutes ago* James Wilson
bzrness *2005-11-07* Richard Downes
o fmt:displaydate is similar but is better in paragraphs or sentences. So,
for example: "FooBar was registered *on 2005-11-06* and last updated
*4 minutes ago*."
The difference between them is TINY: fmt:displaydate prepends "on " to the
result of fmt:approximatedate IF the time delta is greater than 1 day, and
hence if the display will be the date.
First, let's bring in some dependencies:
>>> from datetime import datetime, timedelta
>>> from canonical.launchpad.ftests import test_tales
>>> import pytz
>>> UTC = pytz.timezone('UTC')
fmt:approximatedate and fmt:displaydate display the difference between
the formatted timestamp and the present. This is a really bad idea
for tests, so we register an alternate formatter that use the same
formatting code, but always display the difference from a known
timestamp.
>>> fixed_time_utc = datetime(2005, 12, 25, 12, 0, 0, tzinfo=UTC)
>>> fixed_time = datetime(2005, 12, 25, 12, 0, 0)
>>> from lp.app.browser.tales import DateTimeFormatterAPI
>>> class TestDateTimeFormatterAPI(DateTimeFormatterAPI):
... def _now(self):
... if self._datetime.tzinfo:
... return fixed_time_utc
... else:
... return fixed_time
>>> from zope.app.testing import ztapi
>>> from zope.traversing.interfaces import IPathAdapter
>>> ztapi.provideAdapter(
... datetime, IPathAdapter, TestDateTimeFormatterAPI, 'testfmt')
A time that is very close to the present will be displayed in seconds:
>>> t = fixed_time + timedelta(0, 5, 0)
>>> test_tales('t/testfmt:approximatedate', t=t)
'in 5 seconds'
>>> print (test_tales('t/testfmt:approximatedate', t=t) ==
... test_tales('t/testfmt:displaydate', t=t))
True
>>> t = fixed_time_utc - timedelta(0, 5, 0)
>>> test_tales('t/testfmt:approximatedate', t=t)
'5 seconds ago'
>>> print (test_tales('t/testfmt:approximatedate', t=t) ==
... test_tales('t/testfmt:displaydate', t=t))
True
Further out we expect minutes. Note that for singular units (e.g. "1
minute"), we present the singular unit:
>>> t = fixed_time_utc + timedelta(0, 185, 0)
>>> test_tales('t/testfmt:approximatedate', t=t)
'in 3 minutes'
>>> print (test_tales('t/testfmt:approximatedate', t=t) ==
... test_tales('t/testfmt:displaydate', t=t))
True
>>> t = fixed_time_utc - timedelta(0, 75, 0)
>>> test_tales('t/testfmt:approximatedate', t=t)
'1 minute ago'
>>> print (test_tales('t/testfmt:approximatedate', t=t) ==
... test_tales('t/testfmt:displaydate', t=t))
True
Further out we expect hours:
>>> t = fixed_time_utc + timedelta(0, 3635, 0)
>>> test_tales('t/testfmt:approximatedate', t=t)
'in 1 hour'
>>> print (test_tales('t/testfmt:approximatedate', t=t) ==
... test_tales('t/testfmt:displaydate', t=t))
True
>>> t = fixed_time_utc - timedelta(0, 3635, 0)
>>> test_tales('t/testfmt:approximatedate', t=t)
'1 hour ago'
>>> print (test_tales('t/testfmt:approximatedate', t=t) ==
... test_tales('t/testfmt:displaydate', t=t))
True
And if the approximate date is more than a day away, we expect the date. We
also expect the fmt:displaydate to change form, and become "on yyyy-mm-dd".
>>> t = datetime(2004, 1, 13, 15, 35)
>>> test_tales('t/testfmt:approximatedate', t=t)
'2004-01-13'
>>> print (test_tales('t/testfmt:approximatedate', t=t) ==
... test_tales('t/testfmt:displaydate', t=t))
False
>>> test_tales('t/testfmt:displaydate', t=t)
'on 2004-01-13'
>>> t = datetime(2015, 1, 13, 15, 35)
>>> test_tales('t/testfmt:approximatedate', t=t)
'2015-01-13'
>>> print (test_tales('t/testfmt:approximatedate', t=t) ==
... test_tales('t/testfmt:displaydate', t=t))
False
>>> test_tales('t/testfmt:displaydate', t=t)
'on 2015-01-13'
|