~bzr/ubuntu/lucid/bzr/beta-ppa

« back to all changes in this revision

Viewing changes to bzrlib/timestamp.py

  • Committer: Martin Pool
  • Date: 2010-07-02 07:29:40 UTC
  • mfrom: (129.1.7 packaging-karmic)
  • Revision ID: mbp@sourcefrog.net-20100702072940-hpzq5elg8wjve8rh
* PPA rebuild.
* PPA rebuild for Karmic.
* PPA rebuild for Jaunty.
* PPA rebuild for Hardy.
* From postinst, actually remove the example bash completion scripts.
  (LP: #249452)
* New upstream release.
* New upstream release.
* New upstream release.
* Revert change to Build-depends: Dapper does not have python-central.
  Should be python-support..
* Target ppa..
* Target ppa..
* Target ppa..
* Target ppa..
* New upstream release.
* Switch to dpkg-source 3.0 (quilt) format.
* Bump standards version to 3.8.4.
* Remove embedded copy of python-configobj. Closes: #555336
* Remove embedded copy of python-elementtree. Closes: #555343
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* debian/control: Fix obsolete-relation-form-in-source
  lintian warning. 
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Split out docs into bzr-doc package.
* New upstream release.
* Added John Francesco Ferlito to Uploaders.
* Fix install path to quick-reference guide
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to doc paths changing
* New upstream release.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to doc paths changing
* New upstream release.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to doc paths changing
* New upstream release.
* Fix FTBFS due to path changes, again, again.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to path changes.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Bump standards version to 3.8.3.
* Remove unused patch system.
* New upstream release.
* New upstream release.
* New upstream release.
* Fix copy and paste tab error in .install file
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
 + Fixes compatibility with Python 2.4. Closes: #537708
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream version.
* Bump standards version to 3.8.2.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Add python-pyrex to build-deps to ensure C extensions are always build.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Split documentation into bzr-doc package. ((LP: #385074)
* Multiple packaging changes to make us more linitan clean.
* New upstream release.
* Split documentation into bzr-doc package. ((LP: #385074)
* Multiple packaging changes to make us more linitan clean.
* New upstream release.
* Split documentation into bzr-doc package. ((LP: #385074)
* Multiple packaging changes to make us more linitan clean.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Fix API compatibility version. (Closes: #526233)
* New upstream release.
  + Fixes default format for upgrade command. (Closes: #464688)
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Add missing dependency on zlib development library. (Closes:
  #523595)
* Add zlib build-depends.
* Add zlib build-depends.
* Add zlib build-depends.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Move to section vcs.
* Bump standards version to 3.8.1.
* New upstream release.
* Remove temporary patch for missing .c files from distribution
* New upstream release.
* Remove temporary patch for missing .c files from distribution
* New upstream release.
* Remove temporary patch for missing .c files from distribution
* Add temporary patch for missing .c files from distribution
* Add temporary patch for missing .c files from distribution
* Add temporary patch for missing .c files from distribution
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Recommend ca-certificates. (Closes: #452024)
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Update watch file. bazaar now uses launchpad to host its sources.
* Remove patch for inventory root revision copy, applied upstream.
* New upstream release.
* New upstream release.
* New upstream release
* Force removal of files installed in error to /etc/bash_completion.d/
  (LP: #249452)
* New upstream release.
* New upstream release
* New upstream release.
* Bump standards version.
* Include patch for inventory root revision copy, required for bzr-svn.
* New upstream release.
* Remove unused lintian overrides.
* Correct the package version not to be native.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Final 1.5 release.
* New upstream release.
* New upstream release.
* New upstream release.
* Add myself as a co-maintainer.
* Add a Dm-Upload-Allowed: yes header.
* New upstream bugfix release.
* New upstream release.
* Final 1.3 release.
* New upstream release.
* First release candidate of the upcoming 1.3 release.
* Rebuild to fix the problem caused by a build with a broken python-central.
* New upstream release.
* Rebuild for dapper PPA.
* Apply Lamont's patches to fix build-dependencies on dapper.
  (See: https://bugs.launchpad.net/bzr/+bug/189915)

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