1 ### -*- coding: utf-8 -*- #################################################### |
|
2 ############################################################################## |
|
3 # |
|
4 # Copyright (c) 2008 Thierry Florac <tflorac AT ulthar.net> |
|
5 # All Rights Reserved. |
|
6 # |
|
7 # This software is subject to the provisions of the Zope Public License, |
|
8 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. |
|
9 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
|
10 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
11 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
|
12 # FOR A PARTICULAR PURPOSE. |
|
13 # |
|
14 ############################################################################## |
|
15 |
|
16 |
|
17 # import standard packages |
|
18 from datetime import datetime |
|
19 |
|
20 # import Zope3 interfaces |
|
21 |
|
22 # import local interfaces |
|
23 |
|
24 # import Zope3 packages |
|
25 from zope.datetime import parseDatetimetz |
|
26 from zope.i18n import translate |
|
27 |
|
28 # import local packages |
|
29 from timezone import gmtime |
|
30 |
|
31 from ztfy.utils import _ |
|
32 |
|
33 |
|
34 def unidate(value): |
|
35 """Get specified date converted to unicode ISO format |
|
36 |
|
37 Dates are always assumed to be stored in GMT timezone |
|
38 |
|
39 @param value: input date to convert to unicode |
|
40 @type value: date or datetime |
|
41 @return: input date converted to unicode |
|
42 @rtype: unicode |
|
43 """ |
|
44 if value is not None: |
|
45 value = gmtime(value) |
|
46 return unicode(value.isoformat('T'), 'ascii') |
|
47 return None |
|
48 |
|
49 |
|
50 def parsedate(value): |
|
51 """Get date specified in unicode ISO format to Python datetime object |
|
52 |
|
53 Dates are always assumed to be stored in GMT timezone |
|
54 |
|
55 @param value: unicode date to be parsed |
|
56 @type value: unicode |
|
57 @return: the specified value, converted to datetime |
|
58 @rtype: datetime |
|
59 """ |
|
60 if value is not None: |
|
61 return gmtime(parseDatetimetz(value)) |
|
62 return None |
|
63 |
|
64 |
|
65 def datetodatetime(value): |
|
66 """Get datetime value converted from a date or datetime object |
|
67 |
|
68 @param value: a date or datetime value to convert |
|
69 @type value: date or datetime |
|
70 @return: input value converted to datetime |
|
71 @rtype: datetime |
|
72 """ |
|
73 if type(value) is datetime: |
|
74 return value |
|
75 return datetime(value.year, value.month, value.day) |
|
76 |
|
77 |
|
78 def getAge(value): |
|
79 """Get age of a given datetime (including timezone) compared to current datetime (in UTC) |
|
80 |
|
81 @param value: a datetime value, including timezone |
|
82 @type value: datetime |
|
83 @return: string representing value age |
|
84 @rtype: gettext translated string |
|
85 """ |
|
86 now = gmtime(datetime.utcnow()) |
|
87 delta = now - value |
|
88 if delta.days > 60: |
|
89 return translate(_("%d months ago")) % int(round(delta.days * 1.0 / 30)) |
|
90 elif delta.days > 10: |
|
91 return translate(_("%d weeks ago")) % int(round(delta.days * 1.0 / 7)) |
|
92 elif delta.days > 2: |
|
93 return translate(_("%d days ago")) % delta.days |
|
94 elif delta.days == 2: |
|
95 return translate(_("the day before yesterday")) |
|
96 elif delta.days == 1: |
|
97 return translate(_("yesterday")) |
|
98 else: |
|
99 hours = int(round(delta.seconds * 1.0 / 3600)) |
|
100 if hours > 1: |
|
101 return translate(_("%d hours ago")) % hours |
|
102 elif delta.seconds > 300: |
|
103 return translate(_("%d minutes ago")) % int(round(delta.seconds * 1.0 / 60)) |
|
104 else: |
|
105 return translate(_("less than 5 minutes ago")) |
|
106 |
|
107 |
|
108 def getDuration(v1, v2=None): |
|
109 """Get delta between two dates""" |
|
110 if v2 is None: |
|
111 v2 = datetime.utcnow() |
|
112 assert isinstance(v1, datetime) and isinstance(v2, datetime) |
|
113 v1, v2 = min(v1, v2), max(v1, v2) |
|
114 delta = v2 - v1 |
|
115 if delta.days > 60: |
|
116 return translate(_("%d months")) % int(round(delta.days * 1.0 / 30)) |
|
117 elif delta.days > 10: |
|
118 return translate(_("%d weeks")) % int(round(delta.days * 1.0 / 7)) |
|
119 elif delta.days >= 2: |
|
120 return translate(_("%d days")) % delta.days |
|
121 else: |
|
122 hours = int(round(delta.seconds * 1.0 / 3600)) |
|
123 if delta.days == 1: |
|
124 return translate(_("%d day and %d hours")) % (delta.days, hours) |
|
125 else: |
|
126 if hours > 2: |
|
127 return translate(_("%d hours")) % hours |
|
128 else: |
|
129 minutes = int(round(delta.seconds * 1.0 / 60)) |
|
130 if minutes > 2: |
|
131 return translate(_("%d minutes")) % minutes |
|
132 else: |
|
133 return translate(_("%d seconds")) % delta.seconds |
|