/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5557.1.7 by John Arbash Meinel
Merge in the bzr.dev 5582
1
# Copyright (C) 2007, 2008, 2009, 2011 Canonical Ltd
1551.12.28 by Aaron Bentley
Move bundle timestamp code to timestamp
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, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1551.12.28 by Aaron Bentley
Move bundle timestamp code to timestamp
16
6379.6.3 by Jelmer Vernooij
Use absolute_import.
17
from __future__ import absolute_import
18
1551.12.28 by Aaron Bentley
Move bundle timestamp code to timestamp
19
import calendar
20
import time
6280.2.1 by Matt Giuca
bzrlib.timestamp: More robust handling of time stamp string. (LP: #892657)
21
import re
1551.12.28 by Aaron Bentley
Move bundle timestamp code to timestamp
22
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
23
from . import osutils
2425.6.2 by Martin Pool
Make timestamps use existing format_date; document that function more
24
1551.12.29 by Aaron Bentley
Copy and extend patch date formatting code, add patch-date parsing
25
1551.12.28 by Aaron Bentley
Move bundle timestamp code to timestamp
26
def format_highres_date(t, offset=0):
27
    """Format a date, such that it includes higher precision in the
28
    seconds field.
29
30
    :param t:   The local time in fractional seconds since the epoch
31
    :type t: float
32
    :param offset:  The timezone offset in integer seconds
33
    :type offset: int
34
35
    Example: format_highres_date(time.time(), -time.timezone)
36
    this will return a date stamp for right now,
37
    formatted for the local timezone.
38
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
39
    >>> from breezy.osutils import format_date
1551.12.28 by Aaron Bentley
Move bundle timestamp code to timestamp
40
    >>> format_date(1120153132.350850105, 0)
41
    'Thu 2005-06-30 17:38:52 +0000'
42
    >>> format_highres_date(1120153132.350850105, 0)
43
    'Thu 2005-06-30 17:38:52.350850105 +0000'
44
    >>> format_date(1120153132.350850105, -5*3600)
45
    'Thu 2005-06-30 12:38:52 -0500'
46
    >>> format_highres_date(1120153132.350850105, -5*3600)
47
    'Thu 2005-06-30 12:38:52.350850105 -0500'
48
    >>> format_highres_date(1120153132.350850105, 7200)
49
    'Thu 2005-06-30 19:38:52.350850105 +0200'
50
    >>> format_highres_date(1152428738.867522, 19800)
51
    'Sun 2006-07-09 12:35:38.867522001 +0530'
52
    """
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
53
    if not isinstance(t, float):
54
        raise ValueError(t)
1551.12.28 by Aaron Bentley
Move bundle timestamp code to timestamp
55
56
    # This has to be formatted for "original" date, so that the
57
    # revision XML entry will be reproduced faithfully.
58
    if offset is None:
59
        offset = 0
6840.1.1 by Jelmer Vernooij
Revert custom gmtime implementation without tests.
60
    tt = time.gmtime(t + offset)
1551.12.28 by Aaron Bentley
Move bundle timestamp code to timestamp
61
7143.15.2 by Jelmer Vernooij
Run autopep8.
62
    return (osutils.weekdays[tt[6]] + time.strftime(" %Y-%m-%d %H:%M:%S", tt) +
1551.12.28 by Aaron Bentley
Move bundle timestamp code to timestamp
63
            # Get the high-res seconds, but ignore the 0
7143.15.2 by Jelmer Vernooij
Run autopep8.
64
            ('%.9f' % (t - int(t)))[1:] +
65
            ' %+03d%02d' % (offset / 3600, (offset / 60) % 60))
1551.12.28 by Aaron Bentley
Move bundle timestamp code to timestamp
66
67
68
def unpack_highres_date(date):
69
    """This takes the high-resolution date stamp, and
70
    converts it back into the tuple (timestamp, timezone)
71
    Where timestamp is in real UTC since epoch seconds, and timezone is an
72
    integer number of seconds offset.
73
74
    :param date: A date formated by format_highres_date
75
    :type date: string
76
77
    """
3512.3.1 by Martin von Gagern
Hand-selected minimalistic set of changes from my setlocale branch.
78
    # Weekday parsing is locale sensitive, so drop the weekday
79
    space_loc = date.find(' ')
80
    if space_loc == -1 or date[:space_loc] not in osutils.weekdays:
81
        raise ValueError(
82
            'Date string does not contain a day of week: %r' % date)
1551.12.28 by Aaron Bentley
Move bundle timestamp code to timestamp
83
    # Up until the first period is a datestamp that is generated
84
    # as normal from time.strftime, so use time.strptime to
85
    # parse it
86
    dot_loc = date.find('.')
87
    if dot_loc == -1:
88
        raise ValueError(
89
            'Date string does not contain high-precision seconds: %r' % date)
3512.3.1 by Martin von Gagern
Hand-selected minimalistic set of changes from my setlocale branch.
90
    base_time = time.strptime(date[space_loc:dot_loc], " %Y-%m-%d %H:%M:%S")
1551.12.28 by Aaron Bentley
Move bundle timestamp code to timestamp
91
    fract_seconds, offset = date[dot_loc:].split()
92
    fract_seconds = float(fract_seconds)
93
94
    offset = int(offset)
95
96
    hours = int(offset / 100)
97
    minutes = (offset % 100)
98
    seconds_offset = (hours * 3600) + (minutes * 60)
99
100
    # time.mktime returns localtime, but calendar.timegm returns UTC time
101
    timestamp = calendar.timegm(base_time)
102
    timestamp -= seconds_offset
103
    # Add back in the fractional seconds
104
    timestamp += fract_seconds
105
    return (timestamp, seconds_offset)
1551.12.29 by Aaron Bentley
Copy and extend patch date formatting code, add patch-date parsing
106
107
108
def format_patch_date(secs, offset=0):
109
    """Format a POSIX timestamp and optional offset as a patch-style date.
110
111
    Inverse of parse_patch_date.
112
    """
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
113
    if offset % 60 != 0:
114
        raise ValueError(
7143.15.2 by Jelmer Vernooij
Run autopep8.
115
            "can't represent timezone %s offset by fractional minutes" % offset)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
116
    # so that we don't need to do calculations on pre-epoch times,
2425.6.1 by Martin Pool
Fix formatting of timezones in bundles and merge directives.
117
    # which doesn't work with win32 python gmtime, we always
118
    # give the epoch in utc
119
    if secs == 0:
120
        offset = 0
6840.1.1 by Jelmer Vernooij
Revert custom gmtime implementation without tests.
121
    if secs + offset < 0:
122
        from warnings import warn
123
        warn("gmtime of negative time (%s, %s) may not work on Windows" %
7143.15.2 by Jelmer Vernooij
Run autopep8.
124
             (secs, offset))
2425.6.2 by Martin Pool
Make timestamps use existing format_date; document that function more
125
    return osutils.format_date(secs, offset=offset,
7143.15.2 by Jelmer Vernooij
Run autopep8.
126
                               date_fmt='%Y-%m-%d %H:%M:%S')
1551.12.29 by Aaron Bentley
Copy and extend patch date formatting code, add patch-date parsing
127
128
6280.2.1 by Matt Giuca
bzrlib.timestamp: More robust handling of time stamp string. (LP: #892657)
129
# Format for patch dates: %Y-%m-%d %H:%M:%S [+-]%H%M
130
# Groups: 1 = %Y-%m-%d %H:%M:%S; 2 = [+-]%H; 3 = %M
7143.15.2 by Jelmer Vernooij
Run autopep8.
131
RE_PATCHDATE = re.compile(
132
    "(\\d+-\\d+-\\d+\\s+\\d+:\\d+:\\d+)\\s*([+-]\\d\\d)(\\d\\d)$")
6798.1.1 by Jelmer Vernooij
Properly escape backslashes.
133
RE_PATCHDATE_NOOFFSET = re.compile("\\d+-\\d+-\\d+\\s+\\d+:\\d+:\\d+$")
6280.2.1 by Matt Giuca
bzrlib.timestamp: More robust handling of time stamp string. (LP: #892657)
134
7143.15.2 by Jelmer Vernooij
Run autopep8.
135
1551.12.29 by Aaron Bentley
Copy and extend patch date formatting code, add patch-date parsing
136
def parse_patch_date(date_str):
137
    """Parse a patch-style date into a POSIX timestamp and offset.
138
139
    Inverse of format_patch_date.
140
    """
6280.2.1 by Matt Giuca
bzrlib.timestamp: More robust handling of time stamp string. (LP: #892657)
141
    match = RE_PATCHDATE.match(date_str)
142
    if match is None:
6280.2.3 by Matt Giuca
bzrlib.timestamp: Better error message if the string is missing a timezone offset.
143
        if RE_PATCHDATE_NOOFFSET.match(date_str) is not None:
144
            raise ValueError("time data %r is missing a timezone offset"
7143.15.2 by Jelmer Vernooij
Run autopep8.
145
                             % date_str)
6280.2.3 by Matt Giuca
bzrlib.timestamp: Better error message if the string is missing a timezone offset.
146
        else:
7143.15.2 by Jelmer Vernooij
Run autopep8.
147
            raise ValueError("time data %r does not match format " % date_str +
148
                             "'%Y-%m-%d %H:%M:%S %z'")
6280.2.1 by Matt Giuca
bzrlib.timestamp: More robust handling of time stamp string. (LP: #892657)
149
    secs_str = match.group(1)
6280.2.2 by Matt Giuca
bzrlib.timestamp: Now checks offset hour and minute to ensure they are within correct range.
150
    offset_hours, offset_mins = int(match.group(2)), int(match.group(3))
151
    if abs(offset_hours) >= 24 or offset_mins >= 60:
152
        raise ValueError("invalid timezone %r" %
7143.15.2 by Jelmer Vernooij
Run autopep8.
153
                         (match.group(2) + match.group(3)))
6280.2.2 by Matt Giuca
bzrlib.timestamp: Now checks offset hour and minute to ensure they are within correct range.
154
    offset = offset_hours * 3600 + offset_mins * 60
1551.12.29 by Aaron Bentley
Copy and extend patch date formatting code, add patch-date parsing
155
    tm_time = time.strptime(secs_str, '%Y-%m-%d %H:%M:%S')
156
    # adjust seconds according to offset before converting to POSIX
157
    # timestamp, to avoid edge problems
158
    tm_time = tm_time[:5] + (tm_time[5] - offset,) + tm_time[6:]
159
    secs = calendar.timegm(tm_time)
160
    return secs, offset