diff --git a/demo/moulinrouge/tests.py b/demo/moulinrouge/tests.py index 2c944cc..1a0a997 100644 --- a/demo/moulinrouge/tests.py +++ b/demo/moulinrouge/tests.py @@ -463,6 +463,7 @@ def get_test_routes(app): chart.add(10 * '1b', [(4, 12), (5, 8), (6, 4)], secondary=True) chart.add(10 * '2b', [(3, 24), (0, 17), (12, 9)], secondary=True) chart.add(10 * '2', [(8, 23), (21, 1), (5, 0)]) + chart.value_formatter = lambda x: str(int(x)) + '+' return chart.render_response() @app.route('/test/box') @@ -930,7 +931,7 @@ def get_test_routes(app): (datetime(2013, 1, 12, 8), 412), (datetime(2013, 1, 12, 8, tzinfo=tzn4), 823) ]) - line.x_value_formatter = lambda x: x.isoformat() # strftime("%Y-%m-%d") + # line.x_value_formatter = lambda x: x.isoformat() # strftime("%Y-%m-%d") line.x_label_rotation = 45 return line.render_response() diff --git a/pygal/_compat.py b/pygal/_compat.py index 7d53ab0..997335d 100644 --- a/pygal/_compat.py +++ b/pygal/_compat.py @@ -16,11 +16,12 @@ # # You should have received a copy of the GNU Lesser General Public License # along with pygal. If not, see . +from __future__ import division """Various hacks for transparent python 2 / python 3 support""" import sys from collections import Iterable -import time +from datetime import datetime, timedelta, tzinfo if sys.version_info[0] == 3: @@ -70,16 +71,32 @@ def total_seconds(td): ) / 10 ** 6 return td.total_seconds() +try: + from datetime import timezone + utc = timezone.utc +except ImportError: + class UTC(tzinfo): + def tzname(self, dt): + return 'UTC' + + def utcoffset(self, dt): + return timedelta(0) + + def dst(self, dt): + return None + utc = UTC() + def timestamp(x): """Get a timestamp from a date in python 3 and python 2""" + if x.tzinfo is None: + # Naive dates to utc + x = x.replace(tzinfo=utc) + if hasattr(x, 'timestamp'): - from datetime import timezone - if x.tzinfo is None: - return x.replace(tzinfo=timezone.utc).timestamp() return x.timestamp() else: - return time.mktime(x.utctimetuple()) + return total_seconds(x - datetime(1970, 1, 1, tzinfo=utc)) try: from urllib import quote_plus diff --git a/pygal/test/test_date.py b/pygal/test/test_date.py index d1a4858..5950700 100644 --- a/pygal/test/test_date.py +++ b/pygal/test/test_date.py @@ -20,6 +20,7 @@ """Date related charts tests""" from pygal import DateLine, TimeLine, DateTimeLine, TimeDeltaLine +from pygal._compat import timestamp, utc from pygal.test.utils import texts from datetime import datetime, date, time, timedelta @@ -158,3 +159,17 @@ def test_date_labels(): '2013-01-01', '2013-02-01', '2013-03-01'] + + +def test_utc_timestamping(): + assert timestamp( + datetime(2017, 7, 14, 2, 40).replace(tzinfo=utc) + ) == 1500000000 + + for d in ( + datetime.now(), + datetime.utcnow(), + datetime(1999, 12, 31, 23, 59, 59), + datetime(2000, 1, 1, 0, 0, 0) + ): + assert datetime.utcfromtimestamp(timestamp(d)) == d diff --git a/tox.ini b/tox.ini index 4e7dfb5..969c033 100644 --- a/tox.ini +++ b/tox.ini @@ -14,5 +14,5 @@ setenv = COVERAGE_FILE=.cov-{envname} commands = - coverage run --source=pygal {envbindir}/py.test pygal/test --junitxml=junit-{envname}.xml --flake8 + coverage run --source=pygal {envbindir}/py.test {posargs:pygal/test} --junitxml=junit-{envname}.xml --flake8 coverage xml -o coverage-{envname}.xml