#!/usr/bin/env python3 """ give a nice string representation for a duration Christian Herdtweck, Intra2net, November 2014 Licensed under GPL """ from datetime import timedelta # Version History # 24/11/14 Christian Herdtweck: started creation by copying strftimedelta def strftimedelta(delta, max_parts=2, only_up_to_hours=False): """ nice and length-adjustable text representation of a timespan will output the most significant non-zero time units, e.g. '2h23m50s' or '3d50s12ms' (skipping 0 minutes), or '3y63d12h' or for max_parts=2: '2h23m' / '3d50s' / '3y63d' Assumes that each year has 365 days, every day 24h, every hour 60 mins, ... not accounting for leap years / leap days, changes of timezones, etc @delta:timedelta or anything that can be converted to float; if numeric, this is interpreted as number of seconds @param max_parts: precision (i.e., length) of output (default: 2) set to None if always want precision down to microseconds @param only_up_to_hours: set to True to never give number of days/years (e.g. to get '40h' instead of '1d16h') default: False returns a string """ units = '\u00B5s', 'ms', 's', 'm', 'h', 'd', 'y' if (max_parts is None) or (max_parts < 1): max_parts = 100 # get number of seconds and sign if isinstance(delta, timedelta): seconds = delta.total_seconds() else: seconds = float(delta) negative = False if seconds < 0: negative = True seconds = abs(seconds) # split sub-second part seconds, second_part = divmod(seconds, 1) milliseconds, milli_part = divmod(second_part*1000, 1) microseconds = int(round(milli_part*1000)) seconds = int(seconds) # convert to int here --> all other variables will be int vals = [microseconds, int(milliseconds), ] # split longer units minutes = hours = days = years = 0 if seconds > 0: minutes, seconds = divmod(seconds, 60) if minutes > 0: hours, minutes = divmod(minutes, 60) if hours > 0 and not only_up_to_hours: days, hours = divmod(hours, 24) if days > 0: years, days = divmod(days, 365) vals.append(seconds) vals.append(minutes) vals.append(hours) vals.append(days) vals.append(years) # build string str_parts = [] if negative: str_parts.append('-') n_used = 0 for val,unit in zip( reversed(vals), reversed(units) ): if val == 0: continue str_parts.append(str(val)) str_parts.append(unit) n_used += 1 if n_used >= max_parts: break return ''.join(str_parts) #end: strftimedelta def main(): """ Main function, called when running file as script; currently raises a NotImplementedError """ raise NotImplementedError('nothing to run here -- only a lib!') #end: function main if __name__ == '__main__': main() # (created using vim -- the world's best text editor)