155

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'

M--
33.7k12 gold badges74 silver badges115 bronze badges
asked Mar 1, 2012 at 23:41
1

12 Answers 12

277

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"

answered May 1, 2015 at 1:32
Sign up to request clarification or add additional context in comments.

4 Comments

Great answer, but Linux only. Won't work on Windows. stackoverflow.com/questions/10807164/…
Why does this work? I can't find a reference to this in the docs for date.__format__ or time.strftime, docs.python.org/3/library/…, and docs.python.org/3.8/library/time.html#time.strftime respectively
@Amin Shah Gilani, this is a Linux derived alternative, I’ve updated the post to link to this implementation specific feature’s origin.
see below for windows solution
123

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.

answered Mar 2, 2012 at 0:00

8 Comments

It has been around since python 2.6. (It's not that new.)
To spell out the month, for example, you can use the following: "{0.day} {0:%B %Y}".format(d) which would give you '2 August 2013' as the day of this comment :)
This is interesting, but it doesn't actually answer OP, because he wants AM/PM hours. I'm not actually going to downvote it, but the accepted answer is actually right if you are trying to get "American" date/time formatting in python.
Note that this technique uses strftime, which will fail on dates prior to 1900. If you have old dates, you'll regret this.
fak! I just realized where I didn't point d to another object, I just passed it as a positional arg.
|
95

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", " ")
Alan W. Smith
25.6k5 gold badges73 silver badges101 bronze badges
answered Mar 1, 2012 at 23:46

9 Comments

Sven- Because I want to look like Facebook. Thanks!
Very few people use zero-padded hours in North America when writing the time by hand.
Won't this still zero pad the day of the month?
@JudgeMaygarden: That's why the solution does .lstrip("0") to get rid of the leading zero.
Why I want to remove pad zeroes? Because this is wrong by RFC 2822, for example in podcast feed.
|
95

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.

answered Mar 10, 2017 at 3:22

3 Comments

This is correct. Due note however that the # hash trick on Windows is only available to native python executables. In other words, this will not work for cygwin-based python implementations.
Wow this great to know but I'm horrified of the consequence. I'm testing date formatting returned from a Database and I need to pass in the expected formatting for each test and this adds tons of complexity.
Seems to be incorrect in 2024: "-" and "#" both give me a "bad directive" error. Context: tested from a Windows 10 machine with python 3.12.1 and using a virtual environment installed to a local .venv folder in the project via Visual Studio Code. I'm trying to go in the opposite direction: use strptime to convert a string to a datetime.
24

Good answer from Chris Freeman on Linux.

On windows, it's:

mydate.strftime('%#m/%#d/%Y')
wjandrea
34.1k10 gold badges69 silver badges107 bronze badges
answered Nov 1, 2016 at 17:17

Comments

2

another option:

yourdatetime.strftime('%-m/%-d/%Y %-I:%M%p')
answered Apr 3, 2024 at 12:48

Comments

1

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.

answered Mar 10, 2022 at 16:26

1 Comment

This is the best solution. It's the only answer that still lets you use strftime(), and combine padded and non padded elements, instead of either having all of them or none of them.
0

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

Python strftime - date without leading 0?

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

answered Jul 11, 2020 at 23:37

1 Comment

pd.to_datetime(dt['Time'], format= '%l:%M:%S', infer_datetime_format=True) After try %l still not working for me Error:- File "pandas_libs\tslibs\conversion.pyx", line 399, in pandas._libs.tslibs.conversion.convert_datetime_to_tsobject File "pandas_libs\tslibs\np_datetime.pyx", line 117, in pandas._libs.tslibs.np_datetime.check_dts_bounds pandas._libs.tslibs.np_datetime.OutOfBoundsDatetime: Out of bounds nanosecond timestamp: 1-01-01 09:15:59
0

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

answered Dec 2, 2021 at 11:33

1 Comment

Doesn't work properly for hours at midnight and after noon.
0

In the official docs formating section:

  1. When used with the strptime() method, the leading zero is optional for formats %d, %m, %H, %I, %M, %S, %J, %U, %W, and %V. Format %y does require a leading zero.

So, using %d to parse day in number will automatically parse both 07 & 7 for example.

answered Aug 4, 2022 at 2:56

1 Comment

The question is for strftime(), to print the date as string. Not to parse from string using strptime().
0

I just came across this for the first time, since I previously did most development work on linux exclusively. Here is my solution for an easy cross-platform approach on Python 3.8+

from typing import AnyStr
import os
def unistrfmt(fmt: AnyStr) -> AnyStr:
 return fmt.replace(('%#', '%-')[os.name == 'nt'], ('%-', '%#')[os.name == 'nt'])
# Examples:
from datetime import date
date.today().strftime(unistrfmt("%Y.%m.%-d"))
# '2024.02.1'
os.name
#'nt'
unistrfmt("%Y.%m.%-d")
# '%Y.%m.%#d'
unistrfmt("%Y.%m.%#d")
# '%Y.%m.%#d'
answered Feb 1, 2024 at 15:55

Comments

-1

Add a # in front of the format descriptor to remove zero padding:

mydatetime.strftime('%#m/%d/%Y %#I:%M%p')
answered Jan 9, 2025 at 10:46

1 Comment

This is already mentioned in other answers: stackoverflow.com/a/42709606/2745495

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.