Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two slightly different iso 8601 datetime serialization #4255

5 of 6 tasks
sebdiem opened this issue Jul 11, 2016 · 3 comments
5 of 6 tasks

Two slightly different iso 8601 datetime serialization #4255

sebdiem opened this issue Jul 11, 2016 · 3 comments


Copy link

sebdiem commented Jul 11, 2016


  • I have verified that that issue exists against the master branch of Django REST framework.
  • I have searched for similar issues in both open and closed tickets and cannot find a duplicate.
  • This is not a usage question. (Those should be directed to the discussion group instead.)
  • This cannot be dealt with as a third party library. (We prefer new functionality to be in the form of third party libraries where possible.)
  • I have reduced the issue to the simplest possible case.
  • I have included a failing test as a pull request. (If you are unable to do so we can still accept the issue.)

Steps to reproduce

The implementation of datetime serialization in ISO-8601 format is not consistent in the codebase.
In microseconds are included in the serialized value
In only milliseconds are

Expected behavior

I would expect a consistent implementation.

Actual behavior


Copy link

georgejlee commented Jul 21, 2016

Currently some clients of my API require dates with millisecond precision and cannot handle microseconds. I achieved this by setting 'DATETIME_FORMAT' to None in the settings for DRF 3.3. Upgrading to 3.4 breaks this behavior. Is there an easy way to get the previous behavior? I can't figure out how to specify a datetime format string that gives me the ECMA-262 format. Thanks.

Copy link

ephes commented Jul 22, 2016

@georgejlee I use a custom renderer to work around this:

import datetime

from rest_framework.renderers import JSONRenderer
from rest_framework.utils.encoders import JSONEncoder

class MilliSecondEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            representation = obj.isoformat()
            if obj.microsecond:
                representation = representation[:23] + representation[26:]
            if representation.endswith('+00:00'):
                representation = representation[:-6] + 'Z'
            return representation
            return super().default(obj)

class JSONRenderer(JSONRenderer):
    encoder_class = MilliSecondEncoder

Hmm, changing DEFAULT_RENDERER_CLASSES to custom renderer did not affect the rendering of my viewsets. Had to set renderer_class explicitly, strange.

Copy link

saschwarz commented Jan 24, 2021

In case anyone else stumbles across this while trying to configure DRF to use a custom encoder via encoder_class for datetime. The issue that kept the solution in #4255 (comment) from working for me was DRF will use its built-in encoder unless either the field's DateTimeField has its format kwarg set to None OR, if you don't specify DateTimeField serializers, then you need to set REST_FRAMEWORK's config for DEFAULT_FORMAT: None in your Only then will the custom encoder be used.

The reason is, the serializer field(s) (or default field renderer) will be used to format the Response before the custom Renderer is used to render the datetime. So the datetime field will already be a string and the default JSONEncoder won't invoke the custom encoder, since the default Python types are handled by the encoder so the custom encoder's default method won't be called.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet

No branches or pull requests

5 participants