~ubuntu-branches/ubuntu/vivid/ironic/vivid-updates

« back to all changes in this revision

Viewing changes to ironic/openstack/common/timeutils.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2015-03-30 11:14:57 UTC
  • mfrom: (1.2.6)
  • Revision ID: package-import@ubuntu.com-20150330111457-kr4ju3guf22m4vbz
Tags: 2015.1~b3-0ubuntu1
* New upstream release.
  + d/control: 
    - Align with upstream dependencies.
    - Add dh-python to build-dependencies.
    - Add psmisc as a dependency. (LP: #1358820)
  + d/p/fix-requirements.patch: Rediffed.
  + d/ironic-conductor.init.in: Fixed typos in LSB headers,
    thanks to JJ Asghar. (LP: #1429962)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2011 OpenStack Foundation.
2
 
# All Rights Reserved.
3
 
#
4
 
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
5
 
#    not use this file except in compliance with the License. You may obtain
6
 
#    a copy of the License at
7
 
#
8
 
#         http://www.apache.org/licenses/LICENSE-2.0
9
 
#
10
 
#    Unless required by applicable law or agreed to in writing, software
11
 
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
 
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
 
#    License for the specific language governing permissions and limitations
14
 
#    under the License.
15
 
 
16
 
"""
17
 
Time related utilities and helper functions.
18
 
"""
19
 
 
20
 
import calendar
21
 
import datetime
22
 
import time
23
 
 
24
 
import iso8601
25
 
import six
26
 
 
27
 
 
28
 
# ISO 8601 extended time format with microseconds
29
 
_ISO8601_TIME_FORMAT_SUBSECOND = '%Y-%m-%dT%H:%M:%S.%f'
30
 
_ISO8601_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'
31
 
PERFECT_TIME_FORMAT = _ISO8601_TIME_FORMAT_SUBSECOND
32
 
 
33
 
 
34
 
def isotime(at=None, subsecond=False):
35
 
    """Stringify time in ISO 8601 format."""
36
 
    if not at:
37
 
        at = utcnow()
38
 
    st = at.strftime(_ISO8601_TIME_FORMAT
39
 
                     if not subsecond
40
 
                     else _ISO8601_TIME_FORMAT_SUBSECOND)
41
 
    tz = at.tzinfo.tzname(None) if at.tzinfo else 'UTC'
42
 
    st += ('Z' if tz == 'UTC' else tz)
43
 
    return st
44
 
 
45
 
 
46
 
def parse_isotime(timestr):
47
 
    """Parse time from ISO 8601 format."""
48
 
    try:
49
 
        return iso8601.parse_date(timestr)
50
 
    except iso8601.ParseError as e:
51
 
        raise ValueError(six.text_type(e))
52
 
    except TypeError as e:
53
 
        raise ValueError(six.text_type(e))
54
 
 
55
 
 
56
 
def strtime(at=None, fmt=PERFECT_TIME_FORMAT):
57
 
    """Returns formatted utcnow."""
58
 
    if not at:
59
 
        at = utcnow()
60
 
    return at.strftime(fmt)
61
 
 
62
 
 
63
 
def parse_strtime(timestr, fmt=PERFECT_TIME_FORMAT):
64
 
    """Turn a formatted time back into a datetime."""
65
 
    return datetime.datetime.strptime(timestr, fmt)
66
 
 
67
 
 
68
 
def normalize_time(timestamp):
69
 
    """Normalize time in arbitrary timezone to UTC naive object."""
70
 
    offset = timestamp.utcoffset()
71
 
    if offset is None:
72
 
        return timestamp
73
 
    return timestamp.replace(tzinfo=None) - offset
74
 
 
75
 
 
76
 
def is_older_than(before, seconds):
77
 
    """Return True if before is older than seconds."""
78
 
    if isinstance(before, six.string_types):
79
 
        before = parse_strtime(before).replace(tzinfo=None)
80
 
    else:
81
 
        before = before.replace(tzinfo=None)
82
 
 
83
 
    return utcnow() - before > datetime.timedelta(seconds=seconds)
84
 
 
85
 
 
86
 
def is_newer_than(after, seconds):
87
 
    """Return True if after is newer than seconds."""
88
 
    if isinstance(after, six.string_types):
89
 
        after = parse_strtime(after).replace(tzinfo=None)
90
 
    else:
91
 
        after = after.replace(tzinfo=None)
92
 
 
93
 
    return after - utcnow() > datetime.timedelta(seconds=seconds)
94
 
 
95
 
 
96
 
def utcnow_ts():
97
 
    """Timestamp version of our utcnow function."""
98
 
    if utcnow.override_time is None:
99
 
        # NOTE(kgriffs): This is several times faster
100
 
        # than going through calendar.timegm(...)
101
 
        return int(time.time())
102
 
 
103
 
    return calendar.timegm(utcnow().timetuple())
104
 
 
105
 
 
106
 
def utcnow():
107
 
    """Overridable version of utils.utcnow."""
108
 
    if utcnow.override_time:
109
 
        try:
110
 
            return utcnow.override_time.pop(0)
111
 
        except AttributeError:
112
 
            return utcnow.override_time
113
 
    return datetime.datetime.utcnow()
114
 
 
115
 
 
116
 
def iso8601_from_timestamp(timestamp):
117
 
    """Returns an iso8601 formatted date from timestamp."""
118
 
    return isotime(datetime.datetime.utcfromtimestamp(timestamp))
119
 
 
120
 
 
121
 
utcnow.override_time = None
122
 
 
123
 
 
124
 
def set_time_override(override_time=None):
125
 
    """Overrides utils.utcnow.
126
 
 
127
 
    Make it return a constant time or a list thereof, one at a time.
128
 
 
129
 
    :param override_time: datetime instance or list thereof. If not
130
 
                          given, defaults to the current UTC time.
131
 
    """
132
 
    utcnow.override_time = override_time or datetime.datetime.utcnow()
133
 
 
134
 
 
135
 
def advance_time_delta(timedelta):
136
 
    """Advance overridden time using a datetime.timedelta."""
137
 
    assert utcnow.override_time is not None
138
 
    try:
139
 
        for dt in utcnow.override_time:
140
 
            dt += timedelta
141
 
    except TypeError:
142
 
        utcnow.override_time += timedelta
143
 
 
144
 
 
145
 
def advance_time_seconds(seconds):
146
 
    """Advance overridden time by seconds."""
147
 
    advance_time_delta(datetime.timedelta(0, seconds))
148
 
 
149
 
 
150
 
def clear_time_override():
151
 
    """Remove the overridden time."""
152
 
    utcnow.override_time = None
153
 
 
154
 
 
155
 
def marshall_now(now=None):
156
 
    """Make an rpc-safe datetime with microseconds.
157
 
 
158
 
    Note: tzinfo is stripped, but not required for relative times.
159
 
    """
160
 
    if not now:
161
 
        now = utcnow()
162
 
    return dict(day=now.day, month=now.month, year=now.year, hour=now.hour,
163
 
                minute=now.minute, second=now.second,
164
 
                microsecond=now.microsecond)
165
 
 
166
 
 
167
 
def unmarshall_time(tyme):
168
 
    """Unmarshall a datetime dict."""
169
 
    return datetime.datetime(day=tyme['day'],
170
 
                             month=tyme['month'],
171
 
                             year=tyme['year'],
172
 
                             hour=tyme['hour'],
173
 
                             minute=tyme['minute'],
174
 
                             second=tyme['second'],
175
 
                             microsecond=tyme['microsecond'])
176
 
 
177
 
 
178
 
def delta_seconds(before, after):
179
 
    """Return the difference between two timing objects.
180
 
 
181
 
    Compute the difference in seconds between two date, time, or
182
 
    datetime objects (as a float, to microsecond resolution).
183
 
    """
184
 
    delta = after - before
185
 
    return total_seconds(delta)
186
 
 
187
 
 
188
 
def total_seconds(delta):
189
 
    """Return the total seconds of datetime.timedelta object.
190
 
 
191
 
    Compute total seconds of datetime.timedelta, datetime.timedelta
192
 
    doesn't have method total_seconds in Python2.6, calculate it manually.
193
 
    """
194
 
    try:
195
 
        return delta.total_seconds()
196
 
    except AttributeError:
197
 
        return ((delta.days * 24 * 3600) + delta.seconds +
198
 
                float(delta.microseconds) / (10 ** 6))
199
 
 
200
 
 
201
 
def is_soon(dt, window):
202
 
    """Determines if time is going to happen in the next window seconds.
203
 
 
204
 
    :param dt: the time
205
 
    :param window: minimum seconds to remain to consider the time not soon
206
 
 
207
 
    :return: True if expiration is within the given duration
208
 
    """
209
 
    soon = (utcnow() + datetime.timedelta(seconds=window))
210
 
    return normalize_time(dt) <= soon