2

How to display a datetime object as a string format for printing?

Here is the string I am trying to print:

'Text %s, on date: %d' % (x.name, x.time)

And here is the error I am getting:

%d format: a number is required, not datetime.datetime
pb2q
  • 58,613
  • 19
  • 146
  • 147
user1682273
  • 147
  • 1
  • 4
  • 7
  • If you're writing new code, please consider using the [`format` string method](http://docs.python.org/library/stdtypes.html#str.format) instead, since it *"should be preferred to the `%` formatting (...) in new code"*, according to the linked docs. – Lauritz V. Thaulow Sep 25 '12 at 20:30

2 Answers2

5

Solution

You need to change the type: in template or in argument:

'Text %s, on date: %s' % (x.name, x.time)

But datetime.datetime instance is just an object (it has some kind-of-human-friendly string representation). You can change that to be friendlier this way:

'Text %s, on date: %s' % (x.name, x.time.isoformat())

You can even format it using strftime():

'Text %s, on date: %s' % (x.name, x.time.strftime('%A, %B %d, %Y'))

Test

Lets test it:

>>> import datetime
>>> now = datetime.datetime.now()  # our "now" timestamp
>>> '%d' % now

Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    '%d' % datetime.datetime.now()
TypeError: %d format: a number is required, not datetime.datetime
>>> '%s' % now.isoformat()
'2012-09-25T22:24:30.399000'
>>> now.strftime('%A, %B %d, %Y')
'Tuesday, September 25, 2012'

Alternative - .format()

String formatting operations (%) are one way of formatting string, but there is also another - preferred - way to format strings: .format() method.

The reason for that is a different topic, but I can show you how the above examples would look like using .format() method:

'Text {x.name}, on date: {x.time}'.format(x=x)  # accessing properties
'Text {0}, on date: {1}'.format(x.name, x.time)  # accessing by positions
'Text {}, on date: {}'.format(x.name, x.time)  # in Python >2.7 it can be shorter
'Text {0}, on date: {1}'.format(x.name, x.time.isoformat())  # ISO format
'Text {0}, on date: {1}'.format(x.name, x.time.strftime('%A, %B %d, %Y'))
Community
  • 1
  • 1
Tadeck
  • 132,510
  • 28
  • 152
  • 198
  • +1, but one comment: "But datetime.datetime instance is just an object without human-friendly string representation." That's not true. It does have a string representation, and it's documented; the only problem is that it may not be the one you want. (And it's annoying that it's almost but not quite the same as isoformat: '2012-09-25 14:02:58.806941'.) – abarnert Sep 25 '12 at 21:14
  • @abarnert: Yes, it has string representation. Originally I had representation (`repr()` or `%r`) in mind and it was not really that human-friendly (`datetime.datetime(2012, 9, 25, 22, 26, 28, 393000)` for example). But yes, string representation (`str()`, `datetime.datetime.__str__()`, or `%s` - depending on where you use it) is also part of `datatime.datetime`, so I will include that in my answer. Thanks. – Tadeck Sep 25 '12 at 21:40
  • `datetime` is actually a very friendly class—its `__repr__` is both human-readable and executable to create an equivalent object, and its `__str__` is both nicely-formatted and sortable. So the one little problem, that it's one character away from ISO format, is just that much more glaring… Anyway, your answer packs in so much info in such a readable form that it's just a shame I can't +2 it. – abarnert Sep 25 '12 at 21:44
1
"Text {}, on date: {}".format(x.name, x.time)

If you are using Python 2.6 or above, then format() is the best bet to format your string. It helps you from getting mangled with % format specifier, with which you have to do much more task to format your string in correct format.. Else you can get TypeError

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • @Keith.. Should have quoted that.. Thanks. – Rohit Jain Sep 25 '12 at 20:23
  • note: changing string to `"Text {0}, on date: {1}"` will make it work on python 2.6 and above. – Lauritz V. Thaulow Sep 25 '12 at 20:25
  • @lazyr.. Won't an empty bracket work in 2.6 or above?? As format() was introduced in 2.6 only.. I'm using Python 2.7 so don't have idea.. – Rohit Jain Sep 25 '12 at 20:27
  • @RohitJain: `.format()` method is superior to string formatting operation (`%`), but because of something different than you mentioned. The both are very flexible and you did not even touch the boundaries of string formatting operation, but the basic advantage of `.format()` method is a fact that it... is a method ;) For more in-depth comparison see this: http://stackoverflow.com/a/8396057/548696 – Tadeck Sep 25 '12 at 20:32
  • From [the docs](http://docs.python.org/library/string.html#formatstrings), 7th paragraph down: *"Changed in version 2.7: The positional argument specifiers can be omitted, so `'{} {}'` is equivalent to `'{0} {1}'`"* – Lauritz V. Thaulow Sep 25 '12 at 20:32
  • @lazyr.. Thanks for the comparison link.. and the docs.. The stackoverflow link is awesome.. thanks again.. – Rohit Jain Sep 25 '12 at 20:34
  • You can make it even better: `"Text {x.name}, on date: {x.time}".format(x=x)` – Blender Sep 25 '12 at 20:40