diff --git a/rhodecode/lib/compat.py b/rhodecode/lib/compat.py --- a/rhodecode/lib/compat.py +++ b/rhodecode/lib/compat.py @@ -27,6 +27,7 @@ import os import datetime import functools +import decimal from rhodecode import __platform__, PLATFORM_WIN #============================================================================== @@ -34,20 +35,47 @@ from rhodecode import __platform__, PLAT #============================================================================== +def _is_aware(value): + """ + Determines if a given datetime.time is aware. + + The logic is described in Python's docs: + http://docs.python.org/library/datetime.html#datetime.tzinfo + """ + return (value.tzinfo is not None + and value.tzinfo.utcoffset(value) is not None) + + def _obj_dump(obj): """ - Custom function for dumping objects to JSON + Custom function for dumping objects to JSON, if obj has __json__ attribute + or method defined it will be used for serialization :param obj: """ - DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S" - DATE_FORMAT = "%Y-%m-%d" + if isinstance(obj, complex): return [obj.real, obj.imag] + # See "Date Time String Format" in the ECMA-262 specification. + # some code borrowed from django 1.4 elif isinstance(obj, datetime.datetime): - return obj.strftime(DATETIME_FORMAT) + r = obj.isoformat() + if obj.microsecond: + r = r[:23] + r[26:] + if r.endswith('+00:00'): + r = r[:-6] + 'Z' + return r elif isinstance(obj, datetime.date): - return obj.strftime(DATE_FORMAT) + return obj.isoformat() + elif isinstance(obj, decimal.Decimal): + return str(obj) + elif isinstance(obj, datetime.time): + if _is_aware(obj): + raise ValueError("JSON can't represent timezone-aware times.") + r = obj.isoformat() + if obj.microsecond: + r = r[:12] + return r elif isinstance(obj, set): return list(obj) elif isinstance(obj, OrderedDict):