0

A slight OCD question here - I'm using the {% humanize %} tag in Django which gives me date times returned in the following format:

June 17, 2017 07:24 pm

Now, within my post model in Django I am returning the following:

def published_date(self):
    """Returns a humanized date format for Algolia indexing."""
    humanized_published_date = str(self.publish.strftime("%B %d, %Y %I:%M%p"))
    return humanized_published_date

All works well. HOWEVER, the format returned in the above method is:

June 17, 2017 07:24PM

I've had a previous read of the datetime documentation here (https://docs.python.org/2/library/datetime.html) specifically the section "8.1.7. strftime() and strptime() Behavior". I can see what I may need is the de_DE formatting - which displays a 12 hour clock suffix as pm and not PM.

So, my question is this. How do I re-format date times to give a format as the following: June 17, 2017 07:24 pm.* (As mentioned in the above code - I'm currently using %B %d, %Y %I:%M%p).

*N.B. I'm OCD to the point where I don't want June 17, 2017 07:24PM or even June 17, 2017 07:24pm! i.e., I need that space between the twelve hour clock and the ante meridiem and post meridiem suffixes.

  • According to the docs, the `naturalday` template tag in `humanize` - which is what I guess you are using - defaults to the value of the `DATE_FORMAT` setting if the date is not today/yesterday/tomorrow. Can you show the value of that setting? – Daniel Roseman Jun 21 '17 at 09:09

2 Answers2

0

Add a space and change the meridiem directive to caps:

...strftime("%B %d, %Y %I:%M %P")

The upper %P however is machine dependent; may not work everywhere.

OTOH, you may use the following hack to change the case of the last two characters. The endswith check ensures you're not breaking things in the datetime string and the right characters are replaced, otherwise, no replacement is done; might not satisfy your OCD:

d = datetime.now().strftime("%B %d, %Y %I:%M %p")
if d.endswith(('AM', 'PM')):
    d = d[:-2] + d[-2:].lower()

Final note, why aren't you using humanize directly in your model?

See Django humanize outside of template?

Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
  • Hi Moses. Thank you for your response. For me this just renders a "P" at the end of the formatted date...when you say machine dependent? I'm using Mac... –  Jun 21 '17 at 09:05
  • Would using a brute force method like humanized_published_date + ' am' or humanized_published_date + ' pm' work within some conditional statements? –  Jun 21 '17 at 09:07
  • Awesome - the hack worked. I guess for others the `%P` method may work. Certainly good to have both. One minor thing - I can accept this as an answer one there is a `:` after the `if` –  Jun 21 '17 at 09:14
  • To answer your question regarding humanizing within the model...I'm working with the Algolia search engine tool so I'm returning a format which I know will work with that. –  Jun 21 '17 at 09:21
0

A solution is to manually lowercase the value:

dt = self.publish.strftime("%B %d, %Y %I:%M %p")
humanized_published_date = datetime.now().strftime(dt[:-2] + dt[-2:].lower())

Here there's a complete explanation of this issue. It depends on the C-lib implementation and the locale you are using, that's why there's no standard way of doing this.

But the Django DateFormat library seems to have more options in this regard: https://github.com/django/django/blob/master/django/utils/dateformat.py

This implementation should work as you expect:

from django.utils import dateformat

df = dateformat.DateFormat(self.publish) 
humanized_published_date = df.format("F j, Y H:i a")

print(humanized_published_date)
>>> June 21, 2017 09:19 a.m.
dfranca
  • 5,156
  • 2
  • 32
  • 60
  • I just saw his message about being machine dependent, the other parts we were writing together. – dfranca Jun 21 '17 at 09:12
  • Hi Daniel. Yes - certainly an acceptable answer. I've up-voted it - only reason why I went with Moses' answer is he pipped you to the post. :) Nonetheless, thank you. –  Jun 21 '17 at 09:20