20 from .normalizing
import normalize
21 from .misc
import plural_or_not, roundup
22 from .robottypes
import is_number, is_string
28 _timer_re = re.compile(
r'^([+-])?(\d+:)?(\d+):(\d+)(\.\d+)?$')
32 if epoch_secs
is None:
33 epoch_secs = time.time()
35 timetuple = time.localtime(secs)[:6]
36 return timetuple + (millis,)
40 millis =
roundup((secs - isecs) * 1000)
41 return (isecs, millis)
if millis < 1000
else (isecs+1, 0)
47 for converter
in _number_to_secs, _timer_to_secs, _time_string_to_secs:
48 secs = converter(timestr)
50 return secs
if round_to
is None else roundup(secs, round_to)
51 raise ValueError(
"Invalid time string '%s'." % timestr)
60 match = _timer_re.match(number)
63 prefix, hours, minutes, seconds, millis = match.groups()
64 seconds = float(minutes) * 60 + float(seconds)
66 seconds += float(hours[:-1]) * 60 * 60
68 seconds += float(millis[1:]) / 10**len(millis[1:])
77 millis = secs = mins = hours = days = 0
86 if c ==
'x': millis = float(
''.join(temp)); temp = []
87 elif c ==
's': secs = float(
''.join(temp)); temp = []
88 elif c ==
'm': mins = float(
''.join(temp)); temp = []
89 elif c ==
'h': hours = float(
''.join(temp)); temp = []
90 elif c ==
'd': days = float(
''.join(temp)); temp = []
96 return sign * (millis/1000 + secs + mins*60 + hours*60*60 + days*60*60*24)
100 for specifier, aliases
in [(
'x', [
'millisecond',
'millisec',
'millis',
102 (
's', [
'second',
'sec']),
103 (
'm', [
'minute',
'min']),
106 plural_aliases = [a+
's' for a
in aliases
if not a.endswith(
's')]
107 for alias
in plural_aliases + aliases:
109 timestr = timestr.replace(alias, specifier)
135 self._sign, millis, secs, mins, hours, days \
137 self.
_add_item_add_item(days,
'd',
'day')
138 self.
_add_item_add_item(hours,
'h',
'hour')
139 self.
_add_item_add_item(mins,
'min',
'minute')
140 self.
_add_item_add_item(secs,
's',
'second')
141 self.
_add_item_add_item(millis,
'ms',
'millisecond')
144 if len(self.
_ret_ret) > 0:
145 return self._sign +
' '.join(self.
_ret_ret)
146 return '0s' if self.
_compact_compact
else '0 seconds'
148 def _add_item(self, value, compact_suffix, long_suffix):
152 suffix = compact_suffix
155 self.
_ret_ret.append(
'%d%s' % (value, suffix))
160 float_secs = abs(float_secs)
165 mins = int_secs // 60 % 60
166 hours = int_secs // (60 * 60) % 24
167 days = int_secs // (60 * 60 * 24)
168 return sign, millis, secs, mins, hours, days
182 def format_time(timetuple_or_epochsecs, daysep='', daytimesep=' ', timesep=':
',
187 timetuple = timetuple_or_epochsecs
188 daytimeparts = [
'%02d' % t
for t
in timetuple[:6]]
189 day = daysep.join(daytimeparts[:3])
190 time_ = timesep.join(daytimeparts[3:6])
191 millis = millissep
and '%s%03d' % (millissep, timetuple[6])
or ''
192 return day + daytimesep + time_ + millis
212 time_ =
int(time_
or time.time())
213 format = format.lower()
215 if 'epoch' in format:
217 timetuple = time.localtime(time_)
219 for i, match
in enumerate(
'year month day hour min sec'.split()):
221 parts.append(
'%.2d' % timetuple[i])
226 elif len(parts) == 1:
247 for method
in [_parse_time_epoch,
248 _parse_time_timestamp,
249 _parse_time_now_and_utc]:
250 seconds = method(timestr)
251 if seconds
is not None:
253 raise ValueError(
"Invalid time format '%s'." % timestr)
261 raise ValueError(
"Epoch time must be positive (got %s)." % timestr)
271 timestr = timestr.replace(
' ',
'').
lower()
275 if extra
is not None:
284 zone = time.altzone
if time.localtime().tm_isdst
else time.timezone
291 if extra[0]
not in [
'+',
'-']:
297 return TIMESTAMP_CACHE.get_timestamp(daysep, daytimesep, timesep, millissep)
303 except (ValueError, OverflowError):
304 raise ValueError(
"Invalid timestamp '%s'." % timestamp)
311 seps = (
'',
' ',
':',
'.' if millis
else None)
312 ttuple = time.localtime(secs)[:6]
314 millis = (secs -
int(secs)) * 1000
315 ttuple = ttuple + (
roundup(millis),)
321 if start_time == end_time
or not (start_time
and end_time):
323 if start_time[:-4] == end_time[:-4]:
324 return int(end_time[-3:]) -
int(start_time[-3:])
328 return int(end_millis - start_millis)
339 elapsed = abs(elapsed)
345 secs, millis = divmod(
roundup(elapsed), 1000)
346 mins, secs = divmod(secs, 60)
347 hours, mins = divmod(mins, 60)
348 return '%02d:%02d:%02d.%03d' % (hours, mins, secs, millis)
351 secs =
roundup(elapsed, ndigits=-3) // 1000
352 mins, secs = divmod(secs, 60)
353 hours, mins = divmod(mins, 60)
354 return '%02d:%02d:%02d' % (hours, mins, secs)
361 secs = time.mktime(datetime.datetime(Y, M, D, h, m, s).timetuple())
362 return roundup(1000*secs + millis)
367 ts = ts.replace(sep,
'')
368 ts = ts.ljust(17,
'0')
369 return '%s%s%s %s:%s:%s.%s' % (ts[:4], ts[4:6], ts[6:8], ts[8:10],
370 ts[10:12], ts[12:14], ts[14:17])
373 years =
int(timestamp[:4])
374 mons =
int(timestamp[4:6])
375 days =
int(timestamp[6:8])
376 hours =
int(timestamp[9:11])
377 mins =
int(timestamp[12:14])
378 secs =
int(timestamp[15:17])
379 millis =
int(timestamp[18:21])
380 return years, mons, days, hours, mins, secs, millis
390 def get_timestamp(self, daysep='', daytimesep=' ', timesep=':
', millissep='.
'):
393 if self.
_use_cache_use_cache(secs, daysep, daytimesep, timesep):
395 timestamp =
format_time(epoch, daysep, daytimesep, timesep, millissep)
396 self.
_cache_timestamp_cache_timestamp(secs, timestamp, daysep, daytimesep, timesep, millissep)
def _cached_timestamp(self, millis, millissep)
def _use_cache(self, secs, *separators)
def get_timestamp(self, daysep='', daytimesep=' ', timesep=':', millissep='.')
def _cache_timestamp(self, secs, timestamp, daysep, daytimesep, timesep, millissep)
def _secs_to_components(self, float_secs)
def __init__(self, float_secs, compact)
def _add_item(self, value, compact_suffix, long_suffix)
def roundup(number, ndigits=0, return_type=None)
Rounds number to the given number of digits.
def normalize(string, ignore=(), caseless=True, spaceless=True)
Normalizes given string according to given spec.
def _parse_time_now_and_utc(timestr)
def _number_to_secs(number)
def _time_string_to_secs(timestr)
def _elapsed_time_to_string_without_millis(elapsed)
def _split_timestamp(timestamp)
def _parse_time_epoch(timestr)
def _parse_time_timestamp(timestr)
def secs_to_timestamp(secs, seps=None, millis=False)
def timestamp_to_secs(timestamp, seps=None)
def elapsed_time_to_string(elapsed, include_millis=True)
Converts elapsed time in milliseconds to format 'hh:mm:ss.mil'.
def _timer_to_secs(number)
def get_timestamp(daysep='', daytimesep=' ', timesep=':', millissep='.')
def _parse_time_now_and_utc_base(base)
def get_time(format='timestamp', time_=None)
Return the given or current time in requested format.
def _float_secs_to_secs_and_millis(secs)
def _normalize_timestamp(ts, seps)
def get_elapsed_time(start_time, end_time)
Returns the time between given timestamps in milliseconds.
def _elapsed_time_to_string(elapsed)
def _parse_time_now_and_utc_extra(extra)
def secs_to_timestr(secs, compact=False)
Converts time in seconds to a string representation.
def _normalize_timestr(timestr)
def _get_timetuple(epoch_secs=None)
def format_time(timetuple_or_epochsecs, daysep='', daytimesep=' ', timesep=':', millissep=None)
Returns a timestamp formatted from given time using separators.
def parse_time(timestr)
Parses the time string and returns its value as seconds since epoch.
def _timestamp_to_millis(timestamp, seps=None)
def timestr_to_secs(timestr, round_to=3)
Parses time like '1h 10s', '01:00:10' or '42' and returns seconds.