# HG changeset patch # User Ralf Schlatterbeck # Date 1429630386 -7200 # Node ID fe140bc0eaa91dd4b13cc8b12def7dd48703fdf4 # Parent 07c59221f363cbcf0aa796d83a9910aa9f39b3e0 Implement (and document) timezone offsets diff -r 07c59221f363 -r fe140bc0eaa9 roundup/date.py --- a/roundup/date.py Tue Apr 21 15:49:41 2015 +0200 +++ b/roundup/date.py Tue Apr 21 17:33:06 2015 +0200 @@ -38,8 +38,7 @@ |(?P\d\d?)[/-](?P\d\d?))? # or mm-dd (?P\.)? # . (((?P\d?\d):(?P\d\d))?(:(?P\d\d?(\.\d+)?))?)? # hh:mm:ss - (?P[\d\smywd\-+]+)? # offset - (?P[+-]\d{4})? # time-zone offset + (?:(?P\s?[+-]\d{4})|(?P[\d\smywd\-+]+))? # time-zone offset, offset $''', re.VERBOSE) serialised_date_re = re.compile(r''' (\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d?(\.\d+)?) @@ -190,18 +189,46 @@ care of these conversions. In the following examples, suppose that yyyy is the current year, mm is the current month, and dd is the current day of the month; and suppose that the user is on Eastern Standard Time. + + Note that Date conversion from user inputs will use the local + timezone, either from the database user (some database schemas have + a timezone property for a user) or from a default in the roundup + configuration. Roundup will store all times in UTC in the database + but display the time to the user in their local timezone as + configured. In the following examples the timezone correction for + Eastern Standard Time (GMT-5, no DST) will be applied explicitly via + an offset, but times are given in UTC in the output. + Examples:: - "2000-04-17" means - "01-25" means - "2000-04-17.03:45" means - "08-13.22:13" means - "11-07.09:32:43" means - "14:25" means - "8:47:11" means - "2003" means - "2003-06" means - "." means "right now" + + make doctest think it's always 2000-06-26.00:34:02: + >>> u = test_ini('2000-06-26.00:34:02.0') + + >>> Date("2000-04-17-0500") + + >>> Date("01-25-0500") + + >>> Date("2000-04-17.03:45-0500") + + >>> Date("08-13.22:13-0500") + + >>> Date("11-07.09:32:43-0500") + + >>> Date("14:25-0500") + + >>> Date("8:47:11-0500") + + >>> Date("2003 -0500") + + >>> Date("2003-06 -0500") + + + "." means "right now": + >>> Date(".") + + + >>> test_fin(u) The Date class should understand simple date expressions of the form stamp + interval and stamp - interval. When adding or subtracting @@ -233,7 +260,29 @@ minute, second) is the serialisation format returned by the serialise() method, and is accepted as an argument on instatiation. - The date class handles basic arithmetic:: + In addition, a timezone specifier can be appended to the date format. + The timezone specifier is a sign ("+" or "-") followed by a 4-digit + number as in the RFC 2822 date format. + The first two digits indicate the number of hours, while the last two + digits indicate the number of minutes the time is offset from + Coordinated Universal Time (UTC). The "+" or "-" sign indicate whether + the time is ahead of (east of) or behind (west of) UTC. Note that a + given timezone specifier *overrides* an offset given to the Date + constructor. Examples:: + + >>> Date ("2000-08-14+0200") + + >>> Date ("08-15.22:00+0200") + + >>> Date ("08-15.22:47+0200") + + >>> Date ("08-15.22:47+0200", offset = 5) + + >>> Date ("08-15.22:47", offset = 5) + + + The date class handles basic arithmetic, but note that arithmetic + cannot be combined with timezone offsets (see last example):: >>> x=test_ini('2004-04-06.22:04:20.766830') >>> d1=Date('.') @@ -380,6 +429,8 @@ S = float(info['S']) adjust = True + if info.get('tz', None): + offset = 0 # now handle the adjustment of hour frac = S - int(S) @@ -400,6 +451,13 @@ '"yyyy-mm-dd", "mm-dd", "HH:MM", "HH:MM:SS" or ' '"yyyy-mm-dd.HH:MM:SS.SSS"')%(spec,) + if info.get('tz', None): + tz = info ['tz'].strip () + sign = [-1,1][tz[0] == '-'] + minute = int (tz[3:], 10) + hour = int (tz[1:3], 10) + self.applyInterval(Interval((0, 0, 0, hour, minute, 0), sign=sign)) + # adjust by added granularity if add_granularity: self.applyInterval(add_granularity)