Opened 7 months ago

Closed 7 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 (5)

comment:1 Changed 7 months ago by Nick Pope

Has patch: set

comment:2 Changed 7 months ago by Carlton Gibson

Triage Stage: UnreviewedAccepted

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

comment:3 Changed 7 months ago by Carlton Gibson <carlton.gibson@…>

In 44accb0:

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

Unused since c72dde41e603093ab0bb12fa24fa69cfda0d35f9.

comment:4 Changed 7 months ago by Carlton Gibson <carlton.gibson@…>

In 46346f8:

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

comment:5 Changed 7 months ago by Carlton Gibson <carlton.gibson@…>

Resolution: fixed
Status: assignedclosed

In 29e4ccb1:

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

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