diff --git a/ckan/lib/formatters.py b/ckan/lib/formatters.py index 6c927a53399..fdebde365e7 100644 --- a/ckan/lib/formatters.py +++ b/ckan/lib/formatters.py @@ -70,15 +70,21 @@ def _month_dec(): _month_sept, _month_oct, _month_nov, _month_dec] -def localised_nice_date(datetime_, show_date=False, with_hours=False): +def localised_nice_date(datetime_, show_date=False, with_hours=False, + with_seconds=False): ''' Returns a friendly localised unicode representation of a datetime. + e.g. '31 minutes ago' + '1 day ago' + 'April 24, 2013' (show_date=True) :param datetime_: The date to format :type datetime_: datetime - :param show_date: Show date not 2 days ago etc + :param show_date: Show 'April 24, 2013' instead of '2 days ago' :type show_date: bool :param with_hours: should the `hours:mins` be shown for dates :type with_hours: bool + :param with_seconds: should the `hours:mins:seconds` be shown for dates + :type with_seconds: bool :rtype: sting ''' @@ -132,6 +138,7 @@ def months_between(date1, date2): # actual date details = { + 'sec': int(datetime_.second), 'min': datetime_.minute, 'hour': datetime_.hour, 'day': datetime_.day, @@ -140,14 +147,19 @@ def months_between(date1, date2): 'timezone': datetime_.tzname(), } - if with_hours: + if with_seconds: return ( - # NOTE: This is for translating dates like `April 24, 2013, 10:45 (Europe/Zurich)` + # Example output: `April 24, 2013, 10:45:21 (Europe/Zurich)` + _('{month} {day}, {year}, {hour:02}:{min:02}:{sec:02} ({timezone})') \ + .format(**details)) + elif with_hours: + return ( + # Example output: `April 24, 2013, 10:45 (Europe/Zurich)` _('{month} {day}, {year}, {hour:02}:{min:02} ({timezone})') \ .format(**details)) else: return ( - # NOTE: This is for translating dates like `April 24, 2013` + # Example output: `April 24, 2013` _('{month} {day}, {year}').format(**details)) diff --git a/ckan/lib/helpers.py b/ckan/lib/helpers.py index 910b31fc827..076c07de844 100644 --- a/ckan/lib/helpers.py +++ b/ckan/lib/helpers.py @@ -1422,7 +1422,8 @@ def get_display_timezone(): @core_helper -def render_datetime(datetime_, date_format=None, with_hours=False): +def render_datetime(datetime_, date_format=None, with_hours=False, + with_seconds=False): '''Render a datetime object or timestamp string as a localised date or in the requested format. If timestamp is badly formatted, then a blank string is returned. @@ -1433,6 +1434,8 @@ def render_datetime(datetime_, date_format=None, with_hours=False): :type date_format: string :param with_hours: should the `hours:mins` be shown :type with_hours: bool + :param with_seconds: should the `hours:mins:seconds` be shown + :type with_seconds: bool :rtype: string ''' @@ -1463,7 +1466,8 @@ def render_datetime(datetime_, date_format=None, with_hours=False): return datetime_.strftime(date_format) # the localised date return formatters.localised_nice_date(datetime_, show_date=True, - with_hours=with_hours) + with_hours=with_hours, + with_seconds=with_seconds) @core_helper diff --git a/ckan/tests/legacy/lib/test_helpers.py b/ckan/tests/legacy/lib/test_helpers.py index f60de863e46..5516c2808b6 100644 --- a/ckan/tests/legacy/lib/test_helpers.py +++ b/ckan/tests/legacy/lib/test_helpers.py @@ -23,36 +23,6 @@ def test_extract_markdown(self): assert "Data exposed" in h.markdown_extract(WITH_HTML) assert "collects information" in h.markdown_extract(WITH_UNICODE) - def test_render_datetime(self): - res = h.render_datetime(datetime.datetime(2008, 4, 13, 20, 40, 20, 123456)) - assert_equal(res, 'April 13, 2008') - - def test_render_datetime_with_hours(self): - res = h.render_datetime(datetime.datetime(2008, 4, 13, 20, 40, 20, 123456), with_hours=True) - assert_equal(res, 'April 13, 2008, 20:40 (UTC)') - - def test_render_datetime_but_from_string(self): - res = h.render_datetime('2008-04-13T20:40:20.123456') - assert_equal(res, 'April 13, 2008') - - def test_render_datetime_blank(self): - res = h.render_datetime(None) - assert_equal(res, '') - - def test_render_datetime_year_before_1900(self): - res = h.render_datetime('1875-04-13T20:40:20.123456', date_format='%Y') - assert_equal(res, '1875') - - res = h.render_datetime('1875-04-13T20:40:20.123456', date_format='%y') - assert_equal(res, '75') - - def test_render_datetime_year_before_1900_escape_percent(self): - res = h.render_datetime('1875-04-13', date_format='%%%y') - assert_equal(res, '%75') - - res = h.render_datetime('1875-04-13', date_format='%%%Y') - assert_equal(res, '%1875') - def test_datetime_to_date_str(self): res = datetime.datetime(2008, 4, 13, 20, 40, 20, 123456).isoformat() assert_equal(res, '2008-04-13T20:40:20.123456') diff --git a/ckan/tests/lib/test_helpers.py b/ckan/tests/lib/test_helpers.py index 6f9966237cf..668368032a0 100644 --- a/ckan/tests/lib/test_helpers.py +++ b/ckan/tests/lib/test_helpers.py @@ -521,6 +521,43 @@ def test_named_timezone(self): eq_(h.get_display_timezone(), pytz.timezone('America/New_York')) +class TestHelpersRenderDatetime(object): + + def test_date(self): + data = datetime.datetime(2008, 4, 13, 20, 40, 59, 123456) + eq_(h.render_datetime(data), 'April 13, 2008') + + def test_with_hours(self): + data = datetime.datetime(2008, 4, 13, 20, 40, 59, 123456) + eq_(h.render_datetime(data, with_hours=True), + 'April 13, 2008, 20:40 (UTC)') + + def test_with_seconds(self): + data = datetime.datetime(2008, 4, 13, 20, 40, 59, 123456) + eq_(h.render_datetime(data, with_seconds=True), + 'April 13, 2008, 20:40:59 (UTC)') + + def test_from_string(self): + data = '2008-04-13T20:40:20.123456' + eq_(h.render_datetime(data), 'April 13, 2008') + + def test_blank(self): + data = None + eq_(h.render_datetime(data), '') + + def test_before_1900(self): + data = '1875-04-13T20:40:20.123456' + eq_(h.render_datetime(data, date_format='%Y'), '1875') + + def test_before_1900_with_2_digit_year(self): + data = '1875-04-13T20:40:20.123456' + eq_(h.render_datetime(data, date_format='%y'), '75') + + def test_escaped_percent(self): + data = '2008-04-13T20:40:20.123456' + eq_(h.render_datetime(data, date_format='%%%Y'), '%2008') + + class TestCleanHtml(object): def test_disallowed_tag(self): eq_(h.clean_html('Hello'),