updated connd --status output parser to include log level; mode it pep8 and partially...
[pingcheck] / test / strftimedelta.py
CommitLineData
4c50ece1
CH
1#!/usr/bin/env python3
2
3""" give a nice string representation for a duration
4
5Christian Herdtweck, Intra2net, November 2014
6Licensed under GPL
7"""
8
9from datetime import timedelta
10
11# Version History
12# 24/11/14 Christian Herdtweck: started creation by copying strftimedelta
13
14
15def strftimedelta(delta, max_parts=2, only_up_to_hours=False):
16 """ nice and length-adjustable text representation of a timespan
17
18 will output the most significant non-zero time units, e.g.
19 '2h23m50s' or '3d50s12ms' (skipping 0 minutes), or '3y63d12h'
20 or for max_parts=2: '2h23m' / '3d50s' / '3y63d'
21
22 Assumes that each year has 365 days, every day 24h, every hour 60 mins, ...
23 not accounting for leap years / leap days, changes of timezones, etc
24
25 @delta:timedelta or anything that can be converted to float;
26 if numeric, this is interpreted as number of seconds
27 @param max_parts: precision (i.e., length) of output (default: 2)
28 set to None if always want precision down to microseconds
29 @param only_up_to_hours: set to True to never give number of days/years
30 (e.g. to get '40h' instead of '1d16h')
31 default: False
32
33 returns a string
34 """
35
36 units = '\u00B5s', 'ms', 's', 'm', 'h', 'd', 'y'
37
38 if (max_parts is None) or (max_parts < 1):
39 max_parts = 100
40
41 # get number of seconds and sign
42 if isinstance(delta, timedelta):
43 seconds = delta.total_seconds()
44 else:
45 seconds = float(delta)
46 negative = False
47 if seconds < 0:
48 negative = True
49 seconds = abs(seconds)
50
51 # split sub-second part
52 seconds, second_part = divmod(seconds, 1)
53 milliseconds, milli_part = divmod(second_part*1000, 1)
54 microseconds = int(round(milli_part*1000))
55 seconds = int(seconds) # convert to int here --> all other variables will be int
56 vals = [microseconds, int(milliseconds), ]
57
58 # split longer units
59 minutes = hours = days = years = 0
60 if seconds > 0:
61 minutes, seconds = divmod(seconds, 60)
62 if minutes > 0:
63 hours, minutes = divmod(minutes, 60)
64 if hours > 0 and not only_up_to_hours:
65 days, hours = divmod(hours, 24)
66 if days > 0:
67 years, days = divmod(days, 365)
68 vals.append(seconds)
69 vals.append(minutes)
70 vals.append(hours)
71 vals.append(days)
72 vals.append(years)
73
74 # build string
75 str_parts = []
76 if negative:
77 str_parts.append('-')
78
79 n_used = 0
80 for val,unit in zip( reversed(vals), reversed(units) ):
81 if val == 0:
82 continue
83 str_parts.append(str(val))
84 str_parts.append(unit)
85 n_used += 1
86 if n_used >= max_parts:
87 break
88 return ''.join(str_parts)
89
90#end: strftimedelta
91
92
93
94def main():
95 """ Main function, called when running file as script; currently raises a NotImplementedError
96 """
97 raise NotImplementedError('nothing to run here -- only a lib!')
98#end: function main
99
100
101if __name__ == '__main__':
102 main()
103