日期时间字符串格式对齐

9
在Python 2.7中,我想使用字符串格式化模板打印日期时间对象。但是不知何故,使用左/右对齐不能正确地打印字符串。
import datetime
dt = datetime.datetime(2013, 6, 26, 9, 0)
l = [dt, dt]
template = "{0:>25} {1:>25}" # right justify
print template.format(*l)  #print items in the list using template

这将导致以下结果:
>25 >25

代替

  2013-06-26 09:00:00       2013-06-26 09:00:00

有没有什么技巧可以使用字符串格式模板打印datetime对象?当我将datetime对象强制转换为str()时,似乎可以工作。
print template.format(str(l[0]), str(l[1]))

但是我不想这样做,因为我正在尝试打印一系列值,其中一些不是字符串。制作字符串模板的整个目的是打印列表中的项目。

我是否对字符串格式有所遗漏,或者这似乎是Python的错误?


解决方案

@mgilson指出了我在文档中错过的解决方案。链接

当前支持两个转换标志:'!s' 调用 str() 函数,'!r' 调用 repr() 函数。

以下是一些示例:

"Harold's a clever {0!s}"        # Calls str() on the argument first
"Bring out the holy {name!r}"    # Calls repr() on the argument first
3个回答

5
这里的问题在于datetime对象有一个__format__方法,它基本上只是datetime.strftime的别名。当你进行格式化时,格式化函数会传递字符串'>25',正如你所见,dt.strftime('>25')只会返回'>25'
解决方法是明确指定该字段应以字符串形式进行格式化,使用!s
import datetime
dt = datetime.datetime(2013, 6, 26, 9, 0)
l = [dt, dt]
template = "{0!s:>25} {1!s:>25} " 
out = template.format(*l)
print out

(在Python 2.6和2.7上测试通过。)

真是太好了,这正是我所需要的。在文档中找到了这一行(我错过了)。链接目前支持两个转换标志:'!s' 调用值上的 str(),'!r' 调用值上的 repr()。 - Marcel Wilson
@MarcelWilson -- 直到我去搜索它,我也不知道这个。 - mgilson

2

datetime.datetime类有一个format方法。你需要将它转换成字符串。

>>> '{:%Y/%m/%d}'.format(dt)
'2013/06/26'
>>> '{:>20}'.format(dt)
'>20'
>>> '{:>20}'.format(str(dt))
' 2013-06-26 09:00:00'

>>> import datetime
>>> dt = datetime.datetime(2013, 6, 26, 9, 0)
>>> l = [dt, dt]
>>> template = "{0:>25} {1:>25}"
>>> print template.format(*l)
>25 >25
>>> print template.format(*map(str, l))
      2013-06-26 09:00:00       2013-06-26 09:00:00

这就是我在阅读@mgilson的解决方案之前所做的解决方法。当调用str()时,感觉很尴尬,因为(afaik)字符串格式化模板本应该执行此操作。 - Marcel Wilson

1

试试这个:

print template.format(*map(str, l))
=>      2013-06-26 09:00:00       2013-06-26 09:00:00

它的工作原理是先将 datetime 对象转换为字符串,然后可以使用 format 方法进行格式化,而不会出现问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接