Opened 3 years ago

Closed 3 years ago

Last modified 15 months ago

#32738 closed Cleanup/optimization (fixed)

Deprecate django.utils.datetime_safe, use alternate method to ensure four-digit year with strftime.

Reported by: Nick Pope Owned by: Nick Pope
Component: Utilities Version: dev
Severity: Normal Keywords: datetime_safe, datetime
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

While working on #32366, I came across django.utils.datetime_safe. It exists to ensure that %Y for datetime.datetime.strftime() produces a correct zero-padded 4-digit year. It is only used in three places in Django:

The module refers to https://bugs.python.org/issue13305. On reading further, I understand the following:

For years < 1000 specifiers %C, %F, %G, and %Y don't work as expected for strftime provided by glibc on Linux as they don't pad the year or century with leading zeros. Support for specifying the padding explicitly is available, however, which can be used to fix this issue, e.g. %04Y.

FreeBSD, macOS, and Windows do not support explicitly specifying the padding, but return four digit years (with leading zeros) as expected.

It seems to me that the current approach is quite complex and that we could simply implement a check whether %Y produces the expected value and, if not, make the following substitutions:

  • %C%02C
  • %F%010F
  • %G%04G
  • %Y%04Y

This changes from wrapping date/datetime objects in subclasses with overridden .strftime() to a simple function call to check whether we need to fix the format and rewrite the format if so. (This can be cached.) We also gain the benefit of fixing other specifiers that are also affected, rather than just %Y.

There has been some precedence for cleaning up datetime_safe in #29600. Also, Aymeric doesn't really like it... :D

Change History (6)

comment:1 by Nick Pope, 3 years ago

Has patch: set

comment:2 by Carlton Gibson, 3 years ago

Triage Stage: UnreviewedAccepted

OK, I like this: the single documented function is clearer for me that the subclass approach.

comment:3 by Carlton Gibson <carlton.gibson@…>, 3 years ago

In 44accb0:

Refs #32738, Refs #29600, Refs #29595 -- Removed unused django.utils.datetime_safe.time().

Unused since c72dde41e603093ab0bb12fa24fa69cfda0d35f9.

comment:4 by Carlton Gibson <carlton.gibson@…>, 3 years ago

In 46346f8:

Refs #32738 -- Added sanitize_strftime_format() to replace datetime_safe.

comment:5 by Carlton Gibson <carlton.gibson@…>, 3 years ago

Resolution: fixed
Status: assignedclosed

In 29e4ccb1:

Fixed #32738 -- Deprecated django.utils.datetime_safe module.

comment:6 by Mariusz Felisiak <felisiak.mariusz@…>, 15 months ago

In 4aa06890:

Refs #32738 -- Removed django.utils.datetime_safe module per deprecation timeline.

Note: See TracTickets for help on using tickets.
Back to Top