Python datetime formatting without zero-padding

PythonDatetimeFormattingZero Pad

Python Problem Overview


Is there a format for printing Python datetimes that won't use zero-padding on dates and times?

Format I'm using now:

mydatetime.strftime('%m/%d/%Y %I:%M%p')

Result: 02/29/2012 05:03PM
Desired: 2/29/2012 5:03PM

What format would represent the month as '2' instead of '02', and time as '5:03PM' instead of '05:03PM'

Python Solutions


Solution 1 - Python

The other alternate to avoid the "all or none" leading zero aspect above is to place a minus in front of the field type:

mydatetime.strftime('%-m/%d/%Y %-I:%M%p')

Then this: '4/10/2015 03:00AM'

Becomes: '4/10/2015 3:00AM'

You can optionally place a minus in front of the day if desired.

Edit: The minus feature derives from the GNU C library (“glibc”) as mentioned in the Linux strftime manpage under “Glibc notes”

Solution 2 - Python

The new string formatting system provides an alternative to strftime. It's quite readable -- indeed, it might be preferable to strftime on that account. Not to mention the fact that it doesn't zero-pad:

>>> '{d.month}/{d.day}/{d.year}'.format(d=datetime.datetime.now())
'3/1/2012'

Since you probably want zero padding in the minute field, you could do this:

>>> '{d.month}/{d.day}/{d.year} {d.hour}:{d.minute:02}'.format(d=now)
'3/1/2012 20:00'

If you want "regular" time instead of "military" time, you can still use the standard strftime specifiers as well. Conveniently, for our purposes, strftime does provide a code for the 12-hour time padded with a blank instead of a leading zero:

'{d.month}/{d.day}/{d.year} {d:%l}:{d.minute:02}{d:%p}'.format(d=now)
'4/4/2014  6:00PM'

This becomes somewhat less readable, alas. And as @mlissner points out, strftime will fail on some (all?) platforms for dates before 1900.

Solution 3 - Python

The formatting options available with datetime.strftime() will all zero-pad. You could of course roll you own formatting function, but the easiest solution in this case might be to post-process the result of datetime.strftime():

s = mydatetime.strftime('%m/%d/%Y %I:%M%p').lstrip("0").replace(" 0", " ")

Solution 4 - Python

Accepted answer not a proper solution (IMHO) The proper documented methods:

In Linux "#" is replaced by "-":

%-d, %-H, %-I, %-j, %-m, %-M, %-S, %-U, %-w, %-W, %-y, %-Y

In Windows "-" is replaced by "#":

%#d, %#H, %#I, %#j, %#m, %#M, %#S, %#U, %#w, %#W, %#y, %#Y

#Linux
mydatetime.strftime('%-m/%d/%Y %-I:%M%p')

# Windows
mydatetime.strftime('%#m/%d/%Y %#I:%M%p')

Source: https://msdn.microsoft.com/en-us/library/fe06s4ak.aspx

As stated by Sagneta: The # hash trick on Windows is only available to native python executable. this will not work for cygwin-based python implementations.

Solution 5 - Python

Good answer from Chris Freeman on Linux.

On windows, it's:

mydate.strftime('%#m/%#d/%Y')

Thought that might help.

Solution 6 - Python

"%l" (that's a lower-case L) works for the hour (instead of "%I"). I only know this from another answer here

https://stackoverflow.com/questions/904928/python-strftime-date-without-leading-0

but unfortunately they don't have the code for the other elements of a date/time.

Solution 7 - Python

I use this:

D = str(datetime.now().day)
MM = str(datetime.now().month)
YYYY = str(datetime.now().year)

This, today, will return: 2, 12, 2021

Solution 8 - Python

As mentioned by several others, to ignore leading zero on windows, you must use %#d instead of %-d.

For those who like to write clean cross platform python code, without seeing platform switches in business logic, here is a Python3 helper that enables you to have one format string for both Windows, Linux and Others (tested Linux, Windows and FreeBSD):

import os
from datetime import datetime

def dateToStr(d: datetime, fmt: str) -> str:
    return d.strftime(fmt.replace('%-', '%#') if os.name == 'nt' else fmt)

dateToStr(datetime.now(), '%-m/%-d/%-Y')

On a side note, this is another one of those Whaaaaaaaat? features in Python. I don't understand why they did not create a standard format set for all platforms and add an optional 'use_native' flag to use native platform features. Guess it was an early design decision that must be kept for legacy support.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYarinView Question on Stackoverflow
Solution 1 - PythonChrisFreemanView Answer on Stackoverflow
Solution 2 - PythonsenderleView Answer on Stackoverflow
Solution 3 - PythonSven MarnachView Answer on Stackoverflow
Solution 4 - Pythonuser1719826View Answer on Stackoverflow
Solution 5 - Pythonuser3685285View Answer on Stackoverflow
Solution 6 - PythonRob CranfillView Answer on Stackoverflow
Solution 7 - PythonLorenzo BassettiView Answer on Stackoverflow
Solution 8 - PythonTimothy C. QuinnView Answer on Stackoverflow