~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bundle/serializer/__init__.py

Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
import bzrlib.errors as errors
25
25
from bzrlib.diff import internal_diff
26
26
from bzrlib.revision import NULL_REVISION
 
27
# For backwards-compatibility
 
28
from bzrlib.timestamp import unpack_highres_date, format_highres_date
 
29
 
27
30
 
28
31
# New bundles should try to use this header format
29
32
BUNDLE_HEADER = '# Bazaar revision bundle v'
126
129
    return revision_ids
127
130
 
128
131
 
129
 
def format_highres_date(t, offset=0):
130
 
    """Format a date, such that it includes higher precision in the
131
 
    seconds field.
132
 
 
133
 
    :param t:   The local time in fractional seconds since the epoch
134
 
    :type t: float
135
 
    :param offset:  The timezone offset in integer seconds
136
 
    :type offset: int
137
 
 
138
 
    Example: format_highres_date(time.time(), -time.timezone)
139
 
    this will return a date stamp for right now,
140
 
    formatted for the local timezone.
141
 
 
142
 
    >>> from bzrlib.osutils import format_date
143
 
    >>> format_date(1120153132.350850105, 0)
144
 
    'Thu 2005-06-30 17:38:52 +0000'
145
 
    >>> format_highres_date(1120153132.350850105, 0)
146
 
    'Thu 2005-06-30 17:38:52.350850105 +0000'
147
 
    >>> format_date(1120153132.350850105, -5*3600)
148
 
    'Thu 2005-06-30 12:38:52 -0500'
149
 
    >>> format_highres_date(1120153132.350850105, -5*3600)
150
 
    'Thu 2005-06-30 12:38:52.350850105 -0500'
151
 
    >>> format_highres_date(1120153132.350850105, 7200)
152
 
    'Thu 2005-06-30 19:38:52.350850105 +0200'
153
 
    >>> format_highres_date(1152428738.867522, 19800)
154
 
    'Sun 2006-07-09 12:35:38.867522001 +0530'
155
 
    """
156
 
    import time
157
 
    assert isinstance(t, float)
158
 
    
159
 
    # This has to be formatted for "original" date, so that the
160
 
    # revision XML entry will be reproduced faithfully.
161
 
    if offset is None:
162
 
        offset = 0
163
 
    tt = time.gmtime(t + offset)
164
 
 
165
 
    return (time.strftime("%a %Y-%m-%d %H:%M:%S", tt)
166
 
            + ('%.9f' % (t - int(t)))[1:] # Get the high-res seconds, but ignore the 0
167
 
            + ' %+03d%02d' % (offset / 3600, (offset / 60) % 60))
168
 
 
169
 
 
170
 
def unpack_highres_date(date):
171
 
    """This takes the high-resolution date stamp, and
172
 
    converts it back into the tuple (timestamp, timezone)
173
 
    Where timestamp is in real UTC since epoch seconds, and timezone is an integer
174
 
    number of seconds offset.
175
 
 
176
 
    :param date: A date formated by format_highres_date
177
 
    :type date: string
178
 
 
179
 
    >>> import time, random
180
 
    >>> unpack_highres_date('Thu 2005-06-30 12:38:52.350850105 -0500')
181
 
    (1120153132.3508501, -18000)
182
 
    >>> unpack_highres_date('Thu 2005-06-30 17:38:52.350850105 +0000')
183
 
    (1120153132.3508501, 0)
184
 
    >>> unpack_highres_date('Thu 2005-06-30 19:38:52.350850105 +0200')
185
 
    (1120153132.3508501, 7200)
186
 
    >>> unpack_highres_date('Sun 2006-07-09 12:35:38.867522001 +0530')
187
 
    (1152428738.867522, 19800)
188
 
    >>> from bzrlib.osutils import local_time_offset
189
 
    >>> t = time.time()
190
 
    >>> o = local_time_offset()
191
 
    >>> t2, o2 = unpack_highres_date(format_highres_date(t, o))
192
 
    >>> t == t2
193
 
    True
194
 
    >>> o == o2
195
 
    True
196
 
    >>> t -= 24*3600*365*2 # Start 2 years ago
197
 
    >>> o = -12*3600
198
 
    >>> for count in xrange(500):
199
 
    ...   t += random.random()*24*3600*30
200
 
    ...   o = ((o/3600 + 13) % 25 - 12)*3600 # Add 1 wrap around from [-12, 12]
201
 
    ...   date = format_highres_date(t, o)
202
 
    ...   t2, o2 = unpack_highres_date(date)
203
 
    ...   if t != t2 or o != o2:
204
 
    ...      print 'Failed on date %r, %s,%s diff:%s' % (date, t, o, t2-t)
205
 
    ...      break
206
 
 
207
 
    """
208
 
    import time, calendar
209
 
    # Up until the first period is a datestamp that is generated
210
 
    # as normal from time.strftime, so use time.strptime to
211
 
    # parse it
212
 
    dot_loc = date.find('.')
213
 
    if dot_loc == -1:
214
 
        raise ValueError(
215
 
            'Date string does not contain high-precision seconds: %r' % date)
216
 
    base_time = time.strptime(date[:dot_loc], "%a %Y-%m-%d %H:%M:%S")
217
 
    fract_seconds, offset = date[dot_loc:].split()
218
 
    fract_seconds = float(fract_seconds)
219
 
 
220
 
    offset = int(offset)
221
 
 
222
 
    hours = int(offset / 100)
223
 
    minutes = (offset % 100)
224
 
    seconds_offset = (hours * 3600) + (minutes * 60)
225
 
    
226
 
    # time.mktime returns localtime, but calendar.timegm returns UTC time
227
 
    timestamp = calendar.timegm(base_time)
228
 
    timestamp -= seconds_offset
229
 
    # Add back in the fractional seconds
230
 
    timestamp += fract_seconds
231
 
    return (timestamp, seconds_offset)
232
 
 
233
 
 
234
132
class BundleSerializer(object):
235
133
    """The base class for Serializers.
236
134
 
298
196
 
299
197
register_lazy('0.8', 'bzrlib.bundle.serializer.v08', 'BundleSerializerV08')
300
198
register_lazy('0.9', 'bzrlib.bundle.serializer.v09', 'BundleSerializerV09')
301
 
register_lazy(None, 'bzrlib.bundle.serializer.v08', 'BundleSerializerV08')
 
199
register_lazy(None, 'bzrlib.bundle.serializer.v09', 'BundleSerializerV09')
302
200