/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/timestamp.py

  • Committer: Martin Pool
  • Date: 2005-06-28 03:02:31 UTC
  • Revision ID: mbp@sourcefrog.net-20050628030231-d311e4ebcd467ef4
Merge John's import-speedup branch:

                                                                                         
  777 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 22:20:32 -0500
      revision-id: john@arbash-meinel.com-20050627032031-e82a50db3863b18e
      bzr selftest was not using the correct bzr

  776 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 22:20:22 -0500
      revision-id: john@arbash-meinel.com-20050627032021-c9f21fde989ddaee
      Add was using an old mutter

  775 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 22:02:33 -0500
      revision-id: john@arbash-meinel.com-20050627030233-9165cfe98fc63298
      Cleaned up to be less different

  774 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 21:54:53 -0500
      revision-id: john@arbash-meinel.com-20050627025452-4260d0e744edef43
      Allow BZR_PLUGIN_PATH='' to negate plugin loading.

  773 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 21:49:34 -0500
      revision-id: john@arbash-meinel.com-20050627024933-b7158f67b7b9eae5
      Finished the previous cleanup (allowing load_plugins to be called twice)

  772 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 21:45:08 -0500
      revision-id: john@arbash-meinel.com-20050627024508-723b1df510d196fc
      Work on making the tests pass. versioning.py is calling run_cmd directly, but plugins have been loaded.

  771 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 21:32:29 -0500
      revision-id: john@arbash-meinel.com-20050627023228-79972744d7c53e15
      Got it down a little bit more by removing import of tree and inventory.

  770 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 21:26:05 -0500
      revision-id: john@arbash-meinel.com-20050627022604-350b9773ef622f95
      Reducing the number of import from bzrlib/__init__.py and bzrlib/branch.py

  769 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 20:32:25 -0500
      revision-id: john@arbash-meinel.com-20050627013225-32dd044f10d23948
      Updated revision.py and xml.py to include SubElement.

  768 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 20:03:56 -0500
      revision-id: john@arbash-meinel.com-20050627010356-ee66919e1c377faf
      Minor typo

  767 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 20:03:13 -0500
      revision-id: john@arbash-meinel.com-20050627010312-40d024007eb85051
      Caching the import

  766 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 19:51:47 -0500
      revision-id: john@arbash-meinel.com-20050627005147-5281c99e48ed1834
      Created wrapper functions for lazy import of ElementTree

  765 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 19:46:37 -0500
      revision-id: john@arbash-meinel.com-20050627004636-bf432902004a94c5
      Removed all of the test imports of cElementTree

  764 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 19:43:59 -0500
      revision-id: john@arbash-meinel.com-20050627004358-d137fbe9570dd71b
      Trying to make bzr startup faster.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 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, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
import calendar
18
 
import time
19
 
 
20
 
from bzrlib import osutils
21
 
 
22
 
 
23
 
def format_highres_date(t, offset=0):
24
 
    """Format a date, such that it includes higher precision in the
25
 
    seconds field.
26
 
 
27
 
    :param t:   The local time in fractional seconds since the epoch
28
 
    :type t: float
29
 
    :param offset:  The timezone offset in integer seconds
30
 
    :type offset: int
31
 
 
32
 
    Example: format_highres_date(time.time(), -time.timezone)
33
 
    this will return a date stamp for right now,
34
 
    formatted for the local timezone.
35
 
 
36
 
    >>> from bzrlib.osutils import format_date
37
 
    >>> format_date(1120153132.350850105, 0)
38
 
    'Thu 2005-06-30 17:38:52 +0000'
39
 
    >>> format_highres_date(1120153132.350850105, 0)
40
 
    'Thu 2005-06-30 17:38:52.350850105 +0000'
41
 
    >>> format_date(1120153132.350850105, -5*3600)
42
 
    'Thu 2005-06-30 12:38:52 -0500'
43
 
    >>> format_highres_date(1120153132.350850105, -5*3600)
44
 
    'Thu 2005-06-30 12:38:52.350850105 -0500'
45
 
    >>> format_highres_date(1120153132.350850105, 7200)
46
 
    'Thu 2005-06-30 19:38:52.350850105 +0200'
47
 
    >>> format_highres_date(1152428738.867522, 19800)
48
 
    'Sun 2006-07-09 12:35:38.867522001 +0530'
49
 
    """
50
 
    if not isinstance(t, float):
51
 
        raise ValueError(t)
52
 
 
53
 
    # This has to be formatted for "original" date, so that the
54
 
    # revision XML entry will be reproduced faithfully.
55
 
    if offset is None:
56
 
        offset = 0
57
 
    tt = time.gmtime(t + offset)
58
 
 
59
 
    return (osutils.weekdays[tt[6]] +
60
 
            time.strftime(" %Y-%m-%d %H:%M:%S", tt)
61
 
            # Get the high-res seconds, but ignore the 0
62
 
            + ('%.9f' % (t - int(t)))[1:]
63
 
            + ' %+03d%02d' % (offset / 3600, (offset / 60) % 60))
64
 
 
65
 
 
66
 
def unpack_highres_date(date):
67
 
    """This takes the high-resolution date stamp, and
68
 
    converts it back into the tuple (timestamp, timezone)
69
 
    Where timestamp is in real UTC since epoch seconds, and timezone is an
70
 
    integer number of seconds offset.
71
 
 
72
 
    :param date: A date formated by format_highres_date
73
 
    :type date: string
74
 
 
75
 
    >>> import time, random
76
 
    >>> unpack_highres_date('Thu 2005-06-30 12:38:52.350850105 -0500')
77
 
    (1120153132.3508501, -18000)
78
 
    >>> unpack_highres_date('Thu 2005-06-30 17:38:52.350850105 +0000')
79
 
    (1120153132.3508501, 0)
80
 
    >>> unpack_highres_date('Thu 2005-06-30 19:38:52.350850105 +0200')
81
 
    (1120153132.3508501, 7200)
82
 
    >>> unpack_highres_date('Sun 2006-07-09 12:35:38.867522001 +0530')
83
 
    (1152428738.867522, 19800)
84
 
    >>> from bzrlib.osutils import local_time_offset
85
 
    >>> t = time.time()
86
 
    >>> o = local_time_offset()
87
 
    >>> t2, o2 = unpack_highres_date(format_highres_date(t, o))
88
 
    >>> t == t2
89
 
    True
90
 
    >>> o == o2
91
 
    True
92
 
    >>> t -= 24*3600*365*2 # Start 2 years ago
93
 
    >>> o = -12*3600
94
 
    >>> for count in xrange(500):
95
 
    ...   t += random.random()*24*3600*30
96
 
    ...   o = ((o/3600 + 13) % 25 - 12)*3600 # Add 1 wrap around from [-12, 12]
97
 
    ...   date = format_highres_date(t, o)
98
 
    ...   t2, o2 = unpack_highres_date(date)
99
 
    ...   if t != t2 or o != o2:
100
 
    ...      print 'Failed on date %r, %s,%s diff:%s' % (date, t, o, t2-t)
101
 
    ...      break
102
 
 
103
 
    """
104
 
    # Weekday parsing is locale sensitive, so drop the weekday
105
 
    space_loc = date.find(' ')
106
 
    if space_loc == -1 or date[:space_loc] not in osutils.weekdays:
107
 
        raise ValueError(
108
 
            'Date string does not contain a day of week: %r' % date)
109
 
    # Up until the first period is a datestamp that is generated
110
 
    # as normal from time.strftime, so use time.strptime to
111
 
    # parse it
112
 
    dot_loc = date.find('.')
113
 
    if dot_loc == -1:
114
 
        raise ValueError(
115
 
            'Date string does not contain high-precision seconds: %r' % date)
116
 
    base_time = time.strptime(date[space_loc:dot_loc], " %Y-%m-%d %H:%M:%S")
117
 
    fract_seconds, offset = date[dot_loc:].split()
118
 
    fract_seconds = float(fract_seconds)
119
 
 
120
 
    offset = int(offset)
121
 
 
122
 
    hours = int(offset / 100)
123
 
    minutes = (offset % 100)
124
 
    seconds_offset = (hours * 3600) + (minutes * 60)
125
 
 
126
 
    # time.mktime returns localtime, but calendar.timegm returns UTC time
127
 
    timestamp = calendar.timegm(base_time)
128
 
    timestamp -= seconds_offset
129
 
    # Add back in the fractional seconds
130
 
    timestamp += fract_seconds
131
 
    return (timestamp, seconds_offset)
132
 
 
133
 
 
134
 
def format_patch_date(secs, offset=0):
135
 
    """Format a POSIX timestamp and optional offset as a patch-style date.
136
 
 
137
 
    Inverse of parse_patch_date.
138
 
    """
139
 
    if offset % 60 != 0:
140
 
        raise ValueError(
141
 
        "can't represent timezone %s offset by fractional minutes" % offset)
142
 
    # so that we don't need to do calculations on pre-epoch times,
143
 
    # which doesn't work with win32 python gmtime, we always
144
 
    # give the epoch in utc
145
 
    if secs == 0:
146
 
        offset = 0
147
 
    if secs + offset < 0:
148
 
        from warnings import warn
149
 
        warn("gmtime of negative time (%s, %s) may not work on Windows" %
150
 
                (secs, offset))
151
 
    return osutils.format_date(secs, offset=offset,
152
 
            date_fmt='%Y-%m-%d %H:%M:%S')
153
 
 
154
 
 
155
 
def parse_patch_date(date_str):
156
 
    """Parse a patch-style date into a POSIX timestamp and offset.
157
 
 
158
 
    Inverse of format_patch_date.
159
 
    """
160
 
    secs_str = date_str[:-6]
161
 
    offset_str = date_str[-5:]
162
 
    if len(offset_str) != 5:
163
 
        raise ValueError(
164
 
            "invalid timezone %r" % offset_str)
165
 
    offset_hours, offset_mins = offset_str[:3], offset_str[3:]
166
 
    offset = int(offset_hours) * 3600 + int(offset_mins) * 60
167
 
    tm_time = time.strptime(secs_str, '%Y-%m-%d %H:%M:%S')
168
 
    # adjust seconds according to offset before converting to POSIX
169
 
    # timestamp, to avoid edge problems
170
 
    tm_time = tm_time[:5] + (tm_time[5] - offset,) + tm_time[6:]
171
 
    secs = calendar.timegm(tm_time)
172
 
    return secs, offset