Skip to content

Commit cf7cba9

Browse files
committed
Implement (and document) timezone offsets
1 parent 626999b commit cf7cba9

File tree

1 file changed

+71
-13
lines changed

1 file changed

+71
-13
lines changed

roundup/date.py

Lines changed: 71 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@
3838
|(?P<a>\d\d?)[/-](?P<b>\d\d?))? # or mm-dd
3939
(?P<n>\.)? # .
4040
(((?P<H>\d?\d):(?P<M>\d\d))?(:(?P<S>\d\d?(\.\d+)?))?)? # hh:mm:ss
41-
(?P<o>[\d\smywd\-+]+)? # offset
42-
(?P<tz>[+-]\d{4})? # time-zone offset
41+
(?:(?P<tz>\s?[+-]\d{4})|(?P<o>[\d\smywd\-+]+))? # time-zone offset, offset
4342
$''', re.VERBOSE)
4443
serialised_date_re = re.compile(r'''
4544
(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d?(\.\d+)?)
@@ -190,18 +189,46 @@ class Date:
190189
care of these conversions. In the following examples, suppose that yyyy
191190
is the current year, mm is the current month, and dd is the current day
192191
of the month; and suppose that the user is on Eastern Standard Time.
192+
193+
Note that Date conversion from user inputs will use the local
194+
timezone, either from the database user (some database schemas have
195+
a timezone property for a user) or from a default in the roundup
196+
configuration. Roundup will store all times in UTC in the database
197+
but display the time to the user in their local timezone as
198+
configured. In the following examples the timezone correction for
199+
Eastern Standard Time (GMT-5, no DST) will be applied explicitly via
200+
an offset, but times are given in UTC in the output.
201+
193202
Examples::
194203
195-
"2000-04-17" means <Date 2000-04-17.00:00:00>
196-
"01-25" means <Date yyyy-01-25.00:00:00>
197-
"2000-04-17.03:45" means <Date 2000-04-17.08:45:00>
198-
"08-13.22:13" means <Date yyyy-08-14.03:13:00>
199-
"11-07.09:32:43" means <Date yyyy-11-07.14:32:43>
200-
"14:25" means <Date yyyy-mm-dd.19:25:00>
201-
"8:47:11" means <Date yyyy-mm-dd.13:47:11>
202-
"2003" means <Date 2003-01-01.00:00:00>
203-
"2003-06" means <Date 2003-06-01.00:00:00>
204-
"." means "right now"
204+
205+
make doctest think it's always 2000-06-26.00:34:02:
206+
>>> u = test_ini('2000-06-26.00:34:02.0')
207+
208+
>>> Date("2000-04-17-0500")
209+
<Date 2000-04-17.05:00:00.000>
210+
>>> Date("01-25-0500")
211+
<Date 2000-01-25.05:00:00.000>
212+
>>> Date("2000-04-17.03:45-0500")
213+
<Date 2000-04-17.08:45:00.000>
214+
>>> Date("08-13.22:13-0500")
215+
<Date 2000-08-14.03:13:00.000>
216+
>>> Date("11-07.09:32:43-0500")
217+
<Date 2000-11-07.14:32:43.000>
218+
>>> Date("14:25-0500")
219+
<Date 2000-06-26.19:25:00.000>
220+
>>> Date("8:47:11-0500")
221+
<Date 2000-06-26.13:47:11.000>
222+
>>> Date("2003 -0500")
223+
<Date 2003-01-01.05:00:00.000>
224+
>>> Date("2003-06 -0500")
225+
<Date 2003-06-01.05:00:00.000>
226+
227+
"." means "right now":
228+
>>> Date(".")
229+
<Date 2000-06-26.00:34:02.000>
230+
231+
>>> test_fin(u)
205232
206233
The Date class should understand simple date expressions of the form
207234
stamp + interval and stamp - interval. When adding or subtracting
@@ -233,7 +260,29 @@ class Date:
233260
minute, second) is the serialisation format returned by the serialise()
234261
method, and is accepted as an argument on instatiation.
235262
236-
The date class handles basic arithmetic::
263+
In addition, a timezone specifier can be appended to the date format.
264+
The timezone specifier is a sign ("+" or "-") followed by a 4-digit
265+
number as in the RFC 2822 date format.
266+
The first two digits indicate the number of hours, while the last two
267+
digits indicate the number of minutes the time is offset from
268+
Coordinated Universal Time (UTC). The "+" or "-" sign indicate whether
269+
the time is ahead of (east of) or behind (west of) UTC. Note that a
270+
given timezone specifier *overrides* an offset given to the Date
271+
constructor. Examples::
272+
273+
>>> Date ("2000-08-14+0200")
274+
<Date 2000-08-13.22:00:00.000>
275+
>>> Date ("08-15.22:00+0200")
276+
<Date 2000-08-15.20:00:00.000>
277+
>>> Date ("08-15.22:47+0200")
278+
<Date 2000-08-15.20:47:00.000>
279+
>>> Date ("08-15.22:47+0200", offset = 5)
280+
<Date 2000-08-15.20:47:00.000>
281+
>>> Date ("08-15.22:47", offset = 5)
282+
<Date 2000-08-15.17:47:00.000>
283+
284+
The date class handles basic arithmetic, but note that arithmetic
285+
cannot be combined with timezone offsets (see last example)::
237286
238287
>>> x=test_ini('2004-04-06.22:04:20.766830')
239288
>>> d1=Date('.')
@@ -380,6 +429,8 @@ def set(self, spec, offset=0, date_re=date_re,
380429
S = float(info['S'])
381430
adjust = True
382431

432+
if info.get('tz', None):
433+
offset = 0
383434

384435
# now handle the adjustment of hour
385436
frac = S - int(S)
@@ -400,6 +451,13 @@ def set(self, spec, offset=0, date_re=date_re,
400451
'"yyyy-mm-dd", "mm-dd", "HH:MM", "HH:MM:SS" or '
401452
'"yyyy-mm-dd.HH:MM:SS.SSS"')%(spec,)
402453

454+
if info.get('tz', None):
455+
tz = info ['tz'].strip ()
456+
sign = [-1,1][tz[0] == '-']
457+
minute = int (tz[3:], 10)
458+
hour = int (tz[1:3], 10)
459+
self.applyInterval(Interval((0, 0, 0, hour, minute, 0), sign=sign))
460+
403461
# adjust by added granularity
404462
if add_granularity:
405463
self.applyInterval(add_granularity)

0 commit comments

Comments
 (0)