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?
Advertisement
Answer
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'