jpayne@69
|
1 ##############################################################################
|
jpayne@69
|
2 #
|
jpayne@69
|
3 # Copyright (c) 2005 Zope Foundation and Contributors.
|
jpayne@69
|
4 #
|
jpayne@69
|
5 # This software is subject to the provisions of the Zope Public License,
|
jpayne@69
|
6 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
jpayne@69
|
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
jpayne@69
|
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
jpayne@69
|
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
jpayne@69
|
10 # FOR A PARTICULAR PURPOSE
|
jpayne@69
|
11 #
|
jpayne@69
|
12 ##############################################################################
|
jpayne@69
|
13 from zope.interface import Interface
|
jpayne@69
|
14
|
jpayne@69
|
15
|
jpayne@69
|
16 class DateTimeError(Exception):
|
jpayne@69
|
17 pass
|
jpayne@69
|
18
|
jpayne@69
|
19
|
jpayne@69
|
20 class SyntaxError(DateTimeError):
|
jpayne@69
|
21 pass
|
jpayne@69
|
22
|
jpayne@69
|
23
|
jpayne@69
|
24 class DateError(DateTimeError):
|
jpayne@69
|
25 pass
|
jpayne@69
|
26
|
jpayne@69
|
27
|
jpayne@69
|
28 class TimeError(DateTimeError):
|
jpayne@69
|
29 pass
|
jpayne@69
|
30
|
jpayne@69
|
31
|
jpayne@69
|
32 class IDateTime(Interface):
|
jpayne@69
|
33 # Conversion and comparison methods
|
jpayne@69
|
34
|
jpayne@69
|
35 def localZone(ltm=None):
|
jpayne@69
|
36 """Returns the time zone on the given date. The time zone
|
jpayne@69
|
37 can change according to daylight savings."""
|
jpayne@69
|
38
|
jpayne@69
|
39 def timeTime():
|
jpayne@69
|
40 """Return the date/time as a floating-point number in UTC, in
|
jpayne@69
|
41 the format used by the Python time module. Note that it is
|
jpayne@69
|
42 possible to create date/time values with DateTime that have no
|
jpayne@69
|
43 meaningful value to the time module."""
|
jpayne@69
|
44
|
jpayne@69
|
45 def toZone(z):
|
jpayne@69
|
46 """Return a DateTime with the value as the current object,
|
jpayne@69
|
47 represented in the indicated timezone."""
|
jpayne@69
|
48
|
jpayne@69
|
49 def isFuture():
|
jpayne@69
|
50 """Return true if this object represents a date/time later
|
jpayne@69
|
51 than the time of the call"""
|
jpayne@69
|
52
|
jpayne@69
|
53 def isPast():
|
jpayne@69
|
54 """Return true if this object represents a date/time earlier
|
jpayne@69
|
55 than the time of the call"""
|
jpayne@69
|
56
|
jpayne@69
|
57 def isCurrentYear():
|
jpayne@69
|
58 """Return true if this object represents a date/time that
|
jpayne@69
|
59 falls within the current year, in the context of this
|
jpayne@69
|
60 object's timezone representation"""
|
jpayne@69
|
61
|
jpayne@69
|
62 def isCurrentMonth():
|
jpayne@69
|
63 """Return true if this object represents a date/time that
|
jpayne@69
|
64 falls within the current month, in the context of this
|
jpayne@69
|
65 object's timezone representation"""
|
jpayne@69
|
66
|
jpayne@69
|
67 def isCurrentDay():
|
jpayne@69
|
68 """Return true if this object represents a date/time that
|
jpayne@69
|
69 falls within the current day, in the context of this object's
|
jpayne@69
|
70 timezone representation"""
|
jpayne@69
|
71
|
jpayne@69
|
72 def isCurrentHour():
|
jpayne@69
|
73 """Return true if this object represents a date/time that
|
jpayne@69
|
74 falls within the current hour, in the context of this object's
|
jpayne@69
|
75 timezone representation"""
|
jpayne@69
|
76
|
jpayne@69
|
77 def isCurrentMinute():
|
jpayne@69
|
78 """Return true if this object represents a date/time that
|
jpayne@69
|
79 falls within the current minute, in the context of this
|
jpayne@69
|
80 object's timezone representation"""
|
jpayne@69
|
81
|
jpayne@69
|
82 def isLeapYear():
|
jpayne@69
|
83 """Return true if the current year (in the context of the
|
jpayne@69
|
84 object's timezone) is a leap year"""
|
jpayne@69
|
85
|
jpayne@69
|
86 def earliestTime():
|
jpayne@69
|
87 """Return a new DateTime object that represents the earliest
|
jpayne@69
|
88 possible time (in whole seconds) that still falls within the
|
jpayne@69
|
89 current object's day, in the object's timezone context"""
|
jpayne@69
|
90
|
jpayne@69
|
91 def latestTime():
|
jpayne@69
|
92 """Return a new DateTime object that represents the latest
|
jpayne@69
|
93 possible time (in whole seconds) that still falls within the
|
jpayne@69
|
94 current object's day, in the object's timezone context"""
|
jpayne@69
|
95
|
jpayne@69
|
96 def greaterThan(t):
|
jpayne@69
|
97 """Compare this DateTime object to another DateTime object OR
|
jpayne@69
|
98 a floating point number such as that which is returned by the
|
jpayne@69
|
99 Python time module. Returns true if the object represents a
|
jpayne@69
|
100 date/time greater than the specified DateTime or time module
|
jpayne@69
|
101 style time. Revised to give more correct results through
|
jpayne@69
|
102 comparison of long integer milliseconds."""
|
jpayne@69
|
103
|
jpayne@69
|
104 __gt__ = greaterThan
|
jpayne@69
|
105
|
jpayne@69
|
106 def greaterThanEqualTo(t):
|
jpayne@69
|
107 """Compare this DateTime object to another DateTime object OR
|
jpayne@69
|
108 a floating point number such as that which is returned by the
|
jpayne@69
|
109 Python time module. Returns true if the object represents a
|
jpayne@69
|
110 date/time greater than or equal to the specified DateTime or
|
jpayne@69
|
111 time module style time. Revised to give more correct results
|
jpayne@69
|
112 through comparison of long integer milliseconds."""
|
jpayne@69
|
113
|
jpayne@69
|
114 __ge__ = greaterThanEqualTo
|
jpayne@69
|
115
|
jpayne@69
|
116 def equalTo(t):
|
jpayne@69
|
117 """Compare this DateTime object to another DateTime object OR
|
jpayne@69
|
118 a floating point number such as that which is returned by the
|
jpayne@69
|
119 Python time module. Returns true if the object represents a
|
jpayne@69
|
120 date/time equal to the specified DateTime or time module style
|
jpayne@69
|
121 time. Revised to give more correct results through comparison
|
jpayne@69
|
122 of long integer milliseconds."""
|
jpayne@69
|
123
|
jpayne@69
|
124 __eq__ = equalTo
|
jpayne@69
|
125
|
jpayne@69
|
126 def notEqualTo(t):
|
jpayne@69
|
127 """Compare this DateTime object to another DateTime object OR
|
jpayne@69
|
128 a floating point number such as that which is returned by the
|
jpayne@69
|
129 Python time module. Returns true if the object represents a
|
jpayne@69
|
130 date/time not equal to the specified DateTime or time module
|
jpayne@69
|
131 style time. Revised to give more correct results through
|
jpayne@69
|
132 comparison of long integer milliseconds."""
|
jpayne@69
|
133
|
jpayne@69
|
134 __ne__ = notEqualTo
|
jpayne@69
|
135
|
jpayne@69
|
136 def lessThan(t):
|
jpayne@69
|
137 """Compare this DateTime object to another DateTime object OR
|
jpayne@69
|
138 a floating point number such as that which is returned by the
|
jpayne@69
|
139 Python time module. Returns true if the object represents a
|
jpayne@69
|
140 date/time less than the specified DateTime or time module
|
jpayne@69
|
141 style time. Revised to give more correct results through
|
jpayne@69
|
142 comparison of long integer milliseconds."""
|
jpayne@69
|
143
|
jpayne@69
|
144 __lt__ = lessThan
|
jpayne@69
|
145
|
jpayne@69
|
146 def lessThanEqualTo(t):
|
jpayne@69
|
147 """Compare this DateTime object to another DateTime object OR
|
jpayne@69
|
148 a floating point number such as that which is returned by the
|
jpayne@69
|
149 Python time module. Returns true if the object represents a
|
jpayne@69
|
150 date/time less than or equal to the specified DateTime or time
|
jpayne@69
|
151 module style time. Revised to give more correct results
|
jpayne@69
|
152 through comparison of long integer milliseconds."""
|
jpayne@69
|
153
|
jpayne@69
|
154 __le__ = lessThanEqualTo
|
jpayne@69
|
155
|
jpayne@69
|
156 # Component access
|
jpayne@69
|
157
|
jpayne@69
|
158 def parts():
|
jpayne@69
|
159 """Return a tuple containing the calendar year, month, day,
|
jpayne@69
|
160 hour, minute second and timezone of the object"""
|
jpayne@69
|
161
|
jpayne@69
|
162 def timezone():
|
jpayne@69
|
163 """Return the timezone in which the object is represented."""
|
jpayne@69
|
164
|
jpayne@69
|
165 def tzoffset():
|
jpayne@69
|
166 """Return the timezone offset for the objects timezone."""
|
jpayne@69
|
167
|
jpayne@69
|
168 def year():
|
jpayne@69
|
169 """Return the calendar year of the object"""
|
jpayne@69
|
170
|
jpayne@69
|
171 def month():
|
jpayne@69
|
172 """Return the month of the object as an integer"""
|
jpayne@69
|
173
|
jpayne@69
|
174 def Month():
|
jpayne@69
|
175 """Return the full month name"""
|
jpayne@69
|
176
|
jpayne@69
|
177 def aMonth():
|
jpayne@69
|
178 """Return the abbreviated month name."""
|
jpayne@69
|
179
|
jpayne@69
|
180 def Mon():
|
jpayne@69
|
181 """Compatibility: see aMonth"""
|
jpayne@69
|
182
|
jpayne@69
|
183 def pMonth():
|
jpayne@69
|
184 """Return the abbreviated (with period) month name."""
|
jpayne@69
|
185
|
jpayne@69
|
186 def Mon_():
|
jpayne@69
|
187 """Compatibility: see pMonth"""
|
jpayne@69
|
188
|
jpayne@69
|
189 def day():
|
jpayne@69
|
190 """Return the integer day"""
|
jpayne@69
|
191
|
jpayne@69
|
192 def Day():
|
jpayne@69
|
193 """Return the full name of the day of the week"""
|
jpayne@69
|
194
|
jpayne@69
|
195 def DayOfWeek():
|
jpayne@69
|
196 """Compatibility: see Day"""
|
jpayne@69
|
197
|
jpayne@69
|
198 def dayOfYear():
|
jpayne@69
|
199 """Return the day of the year, in context of the timezone
|
jpayne@69
|
200 representation of the object"""
|
jpayne@69
|
201
|
jpayne@69
|
202 def aDay():
|
jpayne@69
|
203 """Return the abbreviated name of the day of the week"""
|
jpayne@69
|
204
|
jpayne@69
|
205 def pDay():
|
jpayne@69
|
206 """Return the abbreviated (with period) name of the day of the
|
jpayne@69
|
207 week"""
|
jpayne@69
|
208
|
jpayne@69
|
209 def Day_():
|
jpayne@69
|
210 """Compatibility: see pDay"""
|
jpayne@69
|
211
|
jpayne@69
|
212 def dow():
|
jpayne@69
|
213 """Return the integer day of the week, where sunday is 0"""
|
jpayne@69
|
214
|
jpayne@69
|
215 def dow_1():
|
jpayne@69
|
216 """Return the integer day of the week, where sunday is 1"""
|
jpayne@69
|
217
|
jpayne@69
|
218 def h_12():
|
jpayne@69
|
219 """Return the 12-hour clock representation of the hour"""
|
jpayne@69
|
220
|
jpayne@69
|
221 def h_24():
|
jpayne@69
|
222 """Return the 24-hour clock representation of the hour"""
|
jpayne@69
|
223
|
jpayne@69
|
224 def ampm():
|
jpayne@69
|
225 """Return the appropriate time modifier (am or pm)"""
|
jpayne@69
|
226
|
jpayne@69
|
227 def hour():
|
jpayne@69
|
228 """Return the 24-hour clock representation of the hour"""
|
jpayne@69
|
229
|
jpayne@69
|
230 def minute():
|
jpayne@69
|
231 """Return the minute"""
|
jpayne@69
|
232
|
jpayne@69
|
233 def second():
|
jpayne@69
|
234 """Return the second"""
|
jpayne@69
|
235
|
jpayne@69
|
236 def millis():
|
jpayne@69
|
237 """Return the millisecond since the epoch in GMT."""
|
jpayne@69
|
238
|
jpayne@69
|
239 def strftime(format):
|
jpayne@69
|
240 """Format the date/time using the *current timezone representation*."""
|
jpayne@69
|
241
|
jpayne@69
|
242 # General formats from previous DateTime
|
jpayne@69
|
243
|
jpayne@69
|
244 def Date():
|
jpayne@69
|
245 """Return the date string for the object."""
|
jpayne@69
|
246
|
jpayne@69
|
247 def Time():
|
jpayne@69
|
248 """Return the time string for an object to the nearest second."""
|
jpayne@69
|
249
|
jpayne@69
|
250 def TimeMinutes():
|
jpayne@69
|
251 """Return the time string for an object not showing seconds."""
|
jpayne@69
|
252
|
jpayne@69
|
253 def AMPM():
|
jpayne@69
|
254 """Return the time string for an object to the nearest second."""
|
jpayne@69
|
255
|
jpayne@69
|
256 def AMPMMinutes():
|
jpayne@69
|
257 """Return the time string for an object not showing seconds."""
|
jpayne@69
|
258
|
jpayne@69
|
259 def PreciseTime():
|
jpayne@69
|
260 """Return the time string for the object."""
|
jpayne@69
|
261
|
jpayne@69
|
262 def PreciseAMPM():
|
jpayne@69
|
263 """Return the time string for the object."""
|
jpayne@69
|
264
|
jpayne@69
|
265 def yy():
|
jpayne@69
|
266 """Return calendar year as a 2 digit string"""
|
jpayne@69
|
267
|
jpayne@69
|
268 def mm():
|
jpayne@69
|
269 """Return month as a 2 digit string"""
|
jpayne@69
|
270
|
jpayne@69
|
271 def dd():
|
jpayne@69
|
272 """Return day as a 2 digit string"""
|
jpayne@69
|
273
|
jpayne@69
|
274 def rfc822():
|
jpayne@69
|
275 """Return the date in RFC 822 format"""
|
jpayne@69
|
276
|
jpayne@69
|
277 # New formats
|
jpayne@69
|
278
|
jpayne@69
|
279 def fCommon():
|
jpayne@69
|
280 """Return a string representing the object's value in the
|
jpayne@69
|
281 format: March 1, 1997 1:45 pm"""
|
jpayne@69
|
282
|
jpayne@69
|
283 def fCommonZ():
|
jpayne@69
|
284 """Return a string representing the object's value in the
|
jpayne@69
|
285 format: March 1, 1997 1:45 pm US/Eastern"""
|
jpayne@69
|
286
|
jpayne@69
|
287 def aCommon():
|
jpayne@69
|
288 """Return a string representing the object's value in the
|
jpayne@69
|
289 format: Mar 1, 1997 1:45 pm"""
|
jpayne@69
|
290
|
jpayne@69
|
291 def aCommonZ():
|
jpayne@69
|
292 """Return a string representing the object's value in the
|
jpayne@69
|
293 format: Mar 1, 1997 1:45 pm US/Eastern"""
|
jpayne@69
|
294
|
jpayne@69
|
295 def pCommon():
|
jpayne@69
|
296 """Return a string representing the object's value in the
|
jpayne@69
|
297 format: Mar. 1, 1997 1:45 pm"""
|
jpayne@69
|
298
|
jpayne@69
|
299 def pCommonZ():
|
jpayne@69
|
300 """Return a string representing the object's value
|
jpayne@69
|
301 in the format: Mar. 1, 1997 1:45 pm US/Eastern"""
|
jpayne@69
|
302
|
jpayne@69
|
303 def ISO():
|
jpayne@69
|
304 """Return the object in ISO standard format. Note: this is
|
jpayne@69
|
305 *not* ISO 8601-format! See the ISO8601 and HTML4 methods below
|
jpayne@69
|
306 for ISO 8601-compliant output
|
jpayne@69
|
307
|
jpayne@69
|
308 Dates are output as: YYYY-MM-DD HH:MM:SS
|
jpayne@69
|
309 """
|
jpayne@69
|
310
|
jpayne@69
|
311 def ISO8601():
|
jpayne@69
|
312 """Return the object in ISO 8601-compatible format containing
|
jpayne@69
|
313 the date, time with seconds-precision and the time zone
|
jpayne@69
|
314 identifier - see http://www.w3.org/TR/NOTE-datetime
|
jpayne@69
|
315
|
jpayne@69
|
316 Dates are output as: YYYY-MM-DDTHH:MM:SSTZD
|
jpayne@69
|
317 T is a literal character.
|
jpayne@69
|
318 TZD is Time Zone Designator, format +HH:MM or -HH:MM
|
jpayne@69
|
319
|
jpayne@69
|
320 The HTML4 method below offers the same formatting, but
|
jpayne@69
|
321 converts to UTC before returning the value and sets the TZD"Z"
|
jpayne@69
|
322 """
|
jpayne@69
|
323
|
jpayne@69
|
324 def HTML4():
|
jpayne@69
|
325 """Return the object in the format used in the HTML4.0
|
jpayne@69
|
326 specification, one of the standard forms in ISO8601. See
|
jpayne@69
|
327 http://www.w3.org/TR/NOTE-datetime
|
jpayne@69
|
328
|
jpayne@69
|
329 Dates are output as: YYYY-MM-DDTHH:MM:SSZ
|
jpayne@69
|
330 T, Z are literal characters.
|
jpayne@69
|
331 The time is in UTC.
|
jpayne@69
|
332 """
|
jpayne@69
|
333
|
jpayne@69
|
334 def JulianDay():
|
jpayne@69
|
335 """Return the Julian day according to
|
jpayne@69
|
336 https://www.tondering.dk/claus/cal/julperiod.php#formula
|
jpayne@69
|
337 """
|
jpayne@69
|
338
|
jpayne@69
|
339 def week():
|
jpayne@69
|
340 """Return the week number according to ISO.
|
jpayne@69
|
341
|
jpayne@69
|
342 See https://www.tondering.dk/claus/cal/week.php#weekno
|
jpayne@69
|
343 """
|
jpayne@69
|
344
|
jpayne@69
|
345 # Python operator and conversion API
|
jpayne@69
|
346
|
jpayne@69
|
347 def __add__(other):
|
jpayne@69
|
348 """A DateTime may be added to a number and a number may be
|
jpayne@69
|
349 added to a DateTime; two DateTimes cannot be added."""
|
jpayne@69
|
350
|
jpayne@69
|
351 __radd__ = __add__
|
jpayne@69
|
352
|
jpayne@69
|
353 def __sub__(other):
|
jpayne@69
|
354 """Either a DateTime or a number may be subtracted from a
|
jpayne@69
|
355 DateTime, however, a DateTime may not be subtracted from a
|
jpayne@69
|
356 number."""
|
jpayne@69
|
357
|
jpayne@69
|
358 def __repr__():
|
jpayne@69
|
359 """Convert a DateTime to a string that looks like a Python
|
jpayne@69
|
360 expression."""
|
jpayne@69
|
361
|
jpayne@69
|
362 def __str__():
|
jpayne@69
|
363 """Convert a DateTime to a string."""
|
jpayne@69
|
364
|
jpayne@69
|
365 def __hash__():
|
jpayne@69
|
366 """Compute a hash value for a DateTime"""
|
jpayne@69
|
367
|
jpayne@69
|
368 def __int__():
|
jpayne@69
|
369 """Convert to an integer number of seconds since the epoch (gmt)"""
|
jpayne@69
|
370
|
jpayne@69
|
371 def __long__():
|
jpayne@69
|
372 """Convert to a long-int number of seconds since the epoch (gmt)"""
|
jpayne@69
|
373
|
jpayne@69
|
374 def __float__():
|
jpayne@69
|
375 """Convert to floating-point number of seconds since the epoch (gmt)"""
|