From 5c9ba685d29f870bf3ce61dbd77a552042510240 Mon Sep 17 00:00:00 2001 From: russellballestrini Date: Wed, 21 Sep 2016 16:31:48 -0400 Subject: [PATCH] version 0.0.9 support for int/float timestamps changed README.rst changed ago.py changed setup.py changed test_ago.py --- README.rst | 44 ++++++++++++++------------------------------ ago.py | 37 ++++++++++++++++++++++++++++--------- setup.py | 4 ++-- test_ago.py | 12 ++++++++++++ 4 files changed, 56 insertions(+), 41 deletions(-) diff --git a/README.rst b/README.rst index de248db..1bde8a3 100644 --- a/README.rst +++ b/README.rst @@ -30,32 +30,32 @@ or specify *ago* under the *setup_requires* list within your How to use ================== -The ago module comes with two functions: +The ago module comes with three functions: #. human #. delta2dict +#. get_delta_from_subject You really only need to worry about *human*. Here are all the available arguments and defaults:: - human(dt, precision=2, past_tense='{} ago', future_tense='in {}', abbreviate=False): + human(subject, precision=2, past_tense='{} ago', future_tense='in {}', abbreviate=False): -dt - either a datetime or timedelta object to become human readable, required +subject + a datetime, timedelta, or timestamp (integer/float) object to become human readable -precision - control how verbose the output should look, optional +precision (default 2): + the desired amount of unit precision -past_tense - format string used when dt is a past datetime, optional +past_tense (default '{} ago'): + the format string used for a past timedelta -future_tense - format string used when dt is a future datetime, optional - -abbreviate - boolean to abbreviate the units, defaults to False +future_tense (default 'in {}'): + the format string used for a future timedelta +abbreviate (default False): + boolean to abbreviate units Here is an example on how to use *human*:: @@ -66,15 +66,7 @@ Here is an example on how to use *human*:: from datetime import timedelta # pretend this was stored in database - db_date = datetime( - year = 2010, - month=5, - day=4, - hour=6, - minute=54, - second=33, - microsecond=4000 - ) + db_date = datetime(year=2010, month=5, day=4, hour=6, minute=54, second=33, microsecond=4000) # to find out how long ago, use the human function print 'Created ' + human( db_date ) @@ -108,14 +100,6 @@ Example past_tense and future_tense keyword arguments:: print output2 # titanic will sink in 2 days, 3 hours from now -Now we will document how to use delta2dict:: - - # subtract two datetime objects for a timedelta object - delta = PRESENT - db_date - - # create a dictionary of units out of the timedelta - print delta2dict( delta ) - Need more examples? ========================== diff --git a/ago.py b/ago.py index b988e2a..433ae30 100644 --- a/ago.py +++ b/ago.py @@ -3,9 +3,23 @@ from datetime import ( timedelta, ) -def delta2dict( delta ): +def get_delta_from_subject(subject): + subject_type = type(subject) + if subject_type is timedelta: + delta = subject + else: + if subject_type is int or subject_type is float: + dt = datetime.fromtimestamp(float(subject)) + else: + # assume subject is a datetime object and strip timezone data. + dt = subject.replace(tzinfo=None) + # finally, create a timedelta from datetime. + delta = datetime.now() - dt + return delta + +def delta2dict(delta): """Accepts a delta, returns a dictionary of units""" - delta = abs( delta ) + delta = abs(delta) return { 'year' : int(delta.days / 365), 'day' : int(delta.days % 365), @@ -15,14 +29,19 @@ def delta2dict( delta ): 'microsecond' : delta.microseconds } -def human(dt, precision=2, past_tense='{} ago', future_tense='in {}', abbreviate=False): - """Accept a datetime or timedelta, return a human readable delta string.""" +def human(subject, precision=2, past_tense='{} ago', future_tense='in {}', abbreviate=False): + """ + Accept a subject, return a human readable timedelta string. - # if dt is a datetime object, get a timedelta object from it. - delta = dt - if type(dt) is not type(timedelta()): - dt_no_tz = dt.replace(tzinfo=None) - delta = datetime.now() - dt_no_tz + :param subject: a datetime, timedelta, or timestamp (integer / float) object + :param precision: the desired amount of unit precision (default: 2) + :param past_tense: the format string used for a past timedelta (default: '{} ago') + :param future_tense: the format string used for a future timedelta (default: 'in {}') + :param abbreviate: boolean to abbreviate units (default: False) + + :returns: Human readable timedelta string (Str) + """ + delta = get_delta_from_subject(subject) # determine if the_tense is past_tense or future_tense. the_tense = past_tense diff --git a/setup.py b/setup.py index fc89e3c..6b984b2 100644 --- a/setup.py +++ b/setup.py @@ -4,9 +4,9 @@ from setuptools import setup setup( name = 'ago', - version = '0.0.8', + version = '0.0.9', description = 'ago: Human readable timedeltas', - keywords = 'ago human readable time deltas timedelta datetime', + keywords = 'ago human readable time deltas timedelta datetime timestamp', long_description = open('README.rst').read(), author = 'Russell Ballestrini', diff --git a/test_ago.py b/test_ago.py index bc37e48..859a409 100644 --- a/test_ago.py +++ b/test_ago.py @@ -61,6 +61,18 @@ def test_abbreviation(): assert '2h, 24m ago' in human( timedelta(.1), abbreviate=True ) assert '1y, 35d ago' in human( timedelta(400), abbreviate=True ) +def test_timestamp_integer(): + result = human(1474485467933/1000, precision=6) + assert('minute' in result) + assert('second' in result) + assert('ago' in result) + +def test_timestamp_float(): + result = human(1474485467933/1000.0, precision=6) + assert('minute' in result) + assert('second' in result) + assert('ago' in result) + def test_past_tense(): output = human( PAST, past_tense = 'titanic sunk {} ago',