#NEWLINE# def distance_of_time_in_words( from_time , to_time = 0 , granularity = 'second' , round = False ) : #NEWLINE# #INDENT# "\n    Return the absolute time-distance string for two datetime objects,\n    ints or any combination you can dream of.\n    \n    If times are integers, they are interpreted as seconds from now.\n    \n    ``granularity`` dictates where the string calculation is stopped.\n    If set to seconds (default) you will receive the full string. If\n    another accuracy is supplied you will receive an approximation.\n    Available granularities are:\n    'century', 'decade', 'year', 'month', 'day', 'hour', 'minute',\n    'second'\n    \n    Setting ``round`` to true will increase the result by 1 if the fractional\n    value is greater than 50% of the granularity unit.\n    " #NEWLINE# granularities = [ 'century' , 'decade' , 'year' , 'month' , 'day' , 'hour' , 'minute' , 'second' ] #NEWLINE# granularity_size = { #NEWLINE# #INDENT# 'century' : 10 , #NEWLINE# 'decade' : 10 , #NEWLINE# 'year' : 10 , #NEWLINE# 'month' : 12 , #NEWLINE# 'day' : 15 , #NEWLINE# 'hour' : 24 , #NEWLINE# 'minute' : 60 , #NEWLINE# 'second' : 60 , #NEWLINE# #UNINDENT# } #NEWLINE# if ( granularity not in granularities ) : #NEWLINE# #INDENT# raise ValueError ( ( 'Please provide a valid granularity: %s' % granularities ) ) #NEWLINE# #UNINDENT# if isinstance ( from_time , int ) : #NEWLINE# #INDENT# from_time = datetime . fromtimestamp ( ( time . time ( ) + from_time ) ) #NEWLINE# #UNINDENT# if isinstance ( to_time , int ) : #NEWLINE# #INDENT# to_time = datetime . fromtimestamp ( ( time . time ( ) + to_time ) ) #NEWLINE# #UNINDENT# if ( from_time > to_time ) : #NEWLINE# #INDENT# s = from_time #NEWLINE# from_time = to_time #NEWLINE# to_time = s #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( from_time == to_time ) : #NEWLINE# #INDENT# return ( '0 ' + _pluralize_granularity ( granularity ) ) #NEWLINE# #UNINDENT# #UNINDENT# deltas = { #NEWLINE# #INDENT# 'century' : 0 , #NEWLINE# 'decade' : 0 , #NEWLINE# 'year' : 0 , #NEWLINE# 'month' : 0 , #NEWLINE# 'day' : 0 , #NEWLINE# 'hour' : 0 , #NEWLINE# 'minute' : 0 , #NEWLINE# 'second' : 0 , #NEWLINE# #UNINDENT# } #NEWLINE# for field in [ 'month' , 'hour' , 'day' , 'minute' , 'second' ] : #NEWLINE# #INDENT# deltas [ field ] = ( getattr ( to_time , field ) - getattr ( from_time , field ) ) #NEWLINE# #UNINDENT# delta_year = ( to_time . year - from_time . year ) #NEWLINE# if ( delta_year >= 100 ) : #NEWLINE# #INDENT# deltas [ 'century' ] = ( delta_year // 100 ) #NEWLINE# #UNINDENT# if ( ( delta_year % 100 ) >= 10 ) : #NEWLINE# #INDENT# deltas [ 'decade' ] = ( ( delta_year // 10 ) - ( deltas [ 'century' ] * 10 ) ) #NEWLINE# #UNINDENT# if ( delta_year % 10 ) : #NEWLINE# #INDENT# deltas [ 'year' ] = ( delta_year % 10 ) #NEWLINE# #UNINDENT# carry_over = [ ( 'second' , 'minute' , granularity_size [ 'second' ] ) , ( 'minute' , 'hour' , granularity_size [ 'minute' ] ) , ( 'hour' , 'day' , granularity_size [ 'hour' ] ) ] #NEWLINE# _process_carryover ( deltas , carry_over ) #NEWLINE# month_carry = [ None , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ] #NEWLINE# if ( deltas [ 'day' ] < 0 ) : #NEWLINE# #INDENT# deltas [ 'month' ] -= 1 #NEWLINE# if ( ( from_time . month == 2 ) and _is_leap_year ( from_time . year ) ) : #NEWLINE# #INDENT# deltas [ 'day' ] += 29 #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# deltas [ 'day' ] += month_carry [ from_time . month ] #NEWLINE# #UNINDENT# #UNINDENT# carry_over = [ ( 'month' , 'year' , granularity_size [ 'month' ] ) , ( 'year' , 'decade' , granularity_size [ 'year' ] ) , ( 'decade' , 'century' , granularity_size [ 'decade' ] ) ] #NEWLINE# _process_carryover ( deltas , carry_over ) #NEWLINE# return_strings = [ ] #NEWLINE# for g in granularities : #NEWLINE# #INDENT# delta = deltas [ g ] #NEWLINE# if ( g == granularity ) : #NEWLINE# #INDENT# if ( round and ( g != 'second' ) ) : #NEWLINE# #INDENT# i = granularities . index ( g ) #NEWLINE# g_p = granularities [ ( i + 1 ) ] #NEWLINE# delta_p = deltas [ g_p ] #NEWLINE# if ( delta_p > ( granularity_size [ g_p ] / 2 ) ) : #NEWLINE# #INDENT# delta += 1 #NEWLINE# #UNINDENT# if ( delta != 0 ) : #NEWLINE# #INDENT# return_strings . append ( _delta_string ( delta , g ) ) #NEWLINE# #UNINDENT# if ( not return_strings ) : #NEWLINE# #INDENT# return ( 'less than 1 ' + granularity ) #NEWLINE# #UNINDENT# break #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( delta != 0 ) : #NEWLINE# #INDENT# return_strings . append ( _delta_string ( delta , g ) ) #NEWLINE# #UNINDENT# if ( not return_strings ) : #NEWLINE# #INDENT# return ( 'less than 1 ' + granularity ) #NEWLINE# #UNINDENT# break #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( delta != 0 ) : #NEWLINE# #INDENT# return_strings . append ( _delta_string ( delta , g ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# if ( len ( return_strings ) == 1 ) : #NEWLINE# #INDENT# return return_strings [ 0 ] #NEWLINE# #UNINDENT# return ( ( ', ' . join ( return_strings [ : ( - 1 ) ] ) + ' and ' ) + return_strings [ ( - 1 ) ] )