|
86
|
1 # Copyright (C) 2008 Canonical Ltd |
|
|
2 # |
|
|
3 # This program is free software; you can redistribute it and/or modify |
|
|
4 # it under the terms of the GNU General Public License as published by |
|
|
5 # the Free Software Foundation; either version 2 of the License, or |
|
|
6 # (at your option) any later version. |
|
|
7 # |
|
|
8 # This program is distributed in the hope that it will be useful, |
|
|
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
|
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
11 # GNU General Public License for more details. |
|
|
12 # |
|
|
13 # You should have received a copy of the GNU General Public License |
|
|
14 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
15 |
|
|
16 """Date parsing routines. |
|
|
17 |
|
|
18 Each routine represents a date format that can be specified in a |
|
|
19 stream using the date-format feature. The return value is |
|
|
20 timestamp,timezone where |
|
|
21 |
|
|
22 * timestamp is seconds since epoch |
|
|
23 * timezone is the offset from UTC in seconds. |
|
|
24 """ |
|
|
25 import time |
|
|
26 |
|
|
27 from fastimport import errors |
|
|
28 |
|
|
29 |
|
|
30 def parse_raw(s, lineno=0): |
|
|
31 """Parse a date from a raw string. |
|
|
32 |
|
|
33 The format must be exactly "seconds-since-epoch offset-utc". |
|
|
34 See the spec for details. |
|
|
35 """ |
|
|
36 timestamp_str, timezone_str = s.split(b' ', 1) |
|
|
37 timestamp = float(timestamp_str) |
|
|
38 try: |
|
|
39 timezone = parse_tz(timezone_str) |
|
|
40 except ValueError: |
|
|
41 raise errors.InvalidTimezone(lineno, timezone_str) |
|
|
42 return timestamp, timezone |
|
|
43 |
|
|
44 |
|
|
45 def parse_tz(tz): |
|
|
46 """Parse a timezone specification in the [+|-]HHMM format. |
|
|
47 |
|
|
48 :return: the timezone offset in seconds. |
|
|
49 """ |
|
|
50 # from git_repository.py in bzr-git |
|
|
51 sign_byte = tz[0:1] |
|
|
52 # in python 3 b'+006'[0] would return an integer, |
|
|
53 # but b'+006'[0:1] return a new bytes string. |
|
|
54 if sign_byte not in (b'+', b'-'): |
|
|
55 raise ValueError(tz) |
|
|
56 |
|
|
57 sign = {b'+': +1, b'-': -1}[sign_byte] |
|
|
58 hours = int(tz[1:-2]) |
|
|
59 minutes = int(tz[-2:]) |
|
|
60 |
|
|
61 return sign * 60 * (60 * hours + minutes) |
|
|
62 |
|
|
63 |
|
|
64 def parse_rfc2822(s, lineno=0): |
|
|
65 """Parse a date from a rfc2822 string. |
|
|
66 |
|
|
67 See the spec for details. |
|
|
68 """ |
|
|
69 raise NotImplementedError(parse_rfc2822) |
|
|
70 |
|
|
71 |
|
|
72 def parse_now(s, lineno=0): |
|
|
73 """Parse a date from a string. |
|
|
74 |
|
|
75 The format must be exactly "now". |
|
|
76 See the spec for details. |
|
|
77 """ |
|
|
78 return time.time(), 0 |
|
|
79 |
|
|
80 |
|
|
81 # Lookup tabel of date parsing routines |
|
|
82 DATE_PARSERS_BY_NAME = { |
|
|
83 u'raw': parse_raw, |
|
|
84 u'rfc2822': parse_rfc2822, |
|
|
85 u'now': parse_now, |
|
|
86 } |