Formatting appears to work differently if the object you're formatting is a date.
today = "aaa"
print(f'{today:>10}')
returns
aaa
i.e. it has the padding.
If I now do this:
today = datetime.date.today()
print(f'{today:>10}')
then the response is
>10
Which is obviously not what I want. I've tried various other combinations where I put in the date format as well, but all it does is draw the date out and then also add in '>10' also.
How do I format a date with padding?
CodePudding user response:
Python's scheme for formatting via f-strings (and the .format
method of strings) allows the inserted data to override how the format specification works, using the __format__
magic method:
>>> class Example:
... def __format__(self, template):
... return f'{template} formatting of {self.__class__.__name__} instance'
...
>>> f'{Example():test}'
'test formatting of Example instance'
datetime.date
does this, so that time.strftime
is used to do the formatting (after some manipulation, e.g. inserting a proxy time for dates and vice-versa):
>>> help(today.__format__)
Help on built-in function __format__:
__format__(...) method of datetime.date instance
Formats self with strftime.
This means that codes like %Y
etc. can be used, but field width specifiers (like >10
) are not supported. The format string >10
doesn't contain any placeholders for any components of the date (or time), so you just get a literal >10
back.
Fortunately, it is trivial to work around this. Simply coerce the date to string, and pad the string:
>>> f'{str(today):>20}'
' 2022-06-13'
Or better yet, use the built-in syntax for such coercion:
>>> f'{today!s:>20}' # !s for str(), !r for repr()
' 2022-06-13'
If you want to use the strftime formatting as well, do the formatting in two steps:
>>> formatted = f'{today:%B %d, %Y}'
>>> f'{formatted:>20}'
' June 13, 2022'
Note that it does not work to nest format specifiers:
>>> # the {{ is interpreted as an escaped literal {
>>> f'{{today:%B %d, %Y}:>20}'
File "<stdin>", line 1
SyntaxError: f-string: single '}' is not allowed
>>> # the inner {} looks like a dict, but %B isn't an identifier
>>> f'{ {today:%B %d, %Y}:>20}'
File "<fstring>", line 1
( {today:%B %d, %Y})
^
SyntaxError: invalid syntax
However, f-strings themselves can be nested (this is obviously not very elegant and will not scale well):
>>> # instead of trying to format the result from another placeholder,
>>> # we reformat an entire separately-formatted string:
>>> f'{f"{today:%B %d, %Y}":>20}'
' June 13, 2022'
CodePudding user response:
Something like this could work:
from datetime import datetime, date
today = date.today()
formatted_today = datetime.strftime(today, "%d %B, %Y")
print(f'{str(formatted_today):>10}')
Output:
2022-06-13