如何从Python日期/时间获取"2:35pm"而不是"02:35PM"?
我对Python还不太熟悉,所以除了文档里明显的内容,我还没搞明白这个问题。
我之前用过Django,在那里他们通过模板标签提供了一些日期时间格式化的选项,但在普通的Python代码中,我该如何获取没有前导零的12小时制的小时呢?
有没有简单的方法可以做到这一点?我查看了2.5和2.6版本的文档,发现“strftime()”似乎没有这个格式化选项。
我是不是应该用其他的方法呢?
如果有其他不明显的时间格式化技巧,也欢迎分享哦。=)
8 个回答
虽然我个人比较喜欢Mike DeSimone的回答,但为了投票的目的,我觉得这可能是个有价值的补充……
Django项目里有一个“兼容PHP”的日期格式化类,位置在django/utils/dateformat.py (trunk)。使用方法如下(这是一个示例):
>>> import datetime
>>> from django.utils.dateformat import DateFormat
>>> d = datetime.datetime.now()
>>> df = DateFormat(d)
>>> df.format('g:ia') # Format for Hour-no-leading-0, minutes, lowercase 'AM/PM'
u'9:10a.m.'
这个类满足了这里的需求,可能值得在你的项目中使用。不过,我建议你先确认一下许可证是否允许这样使用……欢迎任何评论来进一步说明。
这个问题已经有人回答过了,但从技术上讲,你可以直接通过Python的日期时间功能获取“2:35pm”。在使用glibc的Linux系统上,可以用.strftime("%-I:%M%P")
来实现,因为Python的strftime()
是基于C语言库的strftime()
。
>>> import datetime
>>> now = datetime.datetime.now()
datetime.datetime(2012, 9, 18, 15, 0, 30, 385186)
>>> now.strftime("%-I:%M%P")
'3:00pm'
>>> datetime.time(14, 35).strftime("%-I:%M%P")
'2:35pm'
你可以查看glibc中关于“-”的strftime说明。
在datetime
里没有现成的功能可以做到这一点。你需要用一些其他的方法,比如:
datetime.time(1).strftime('%I:%M%p').lstrip('0')
补充说明
正如@naktinis提到的,这个方法是针对特定的strftime
参数设计的。不幸的是,如果strftime
参数的内容是未知的或没有指定的(比如来自外部的参数),就没有通用的解决方案,因为这会变成一个“我想要的和我说的可能不一样”的问题。
因此,既然你必须知道你的strftime
参数里有什么,在更复杂的情况下,你可以把这个问题拆分成几个部分来解决:
tval = datetime.time(1)
tval_str = (tval.strftime('%A, %B ') + tval.strftime('%d').lstrip('0')
+ tval.strftime(' %Y, ') + tval.strftime('%I:%M').lstrip('0')
+ tval.strftime('%p').lower())
或者使用re
模块:
tval = datetime.time(1)
tval_str = re.sub(r"^0|(?<=\s)0", "",
re.sub(r"(?<=[0-9])[AP]M", lambda m: m.group().lower(),
tval.strftime('%A, %B %d %Y, %I:%M%p')))
需要注意的是,如果"%p"
这个部分返回的是大写字母,可能是因为用户设置了他们的地区偏好,而你如果改变了字母的大小写,就会覆盖用户的设置,这有时会导致错误报告。此外,用户可能希望得到的不是“am”或“pm”,而是“a.m.”和“p.m.”。还要注意,不同地区的表示方式是不同的(例如,en_US
地区会给出AM
或PM
,而de_DE
地区则给出am
或pm
),而且你可能得到的字符编码也和你想象的不一样。
因为格式依赖于当前的地区设置,所以在假设输出值时要小心。字段的顺序会有所不同(例如,“月/日/年”与“日/月/年”),输出可能包含使用地区默认编码的Unicode字符(例如,如果当前地区是
js_JP
,默认编码可能是eucJP
、SJIS
或utf-8
;可以使用locale.getlocale()
来确定当前地区的编码)。
所以,总的来说,如果你觉得需要覆盖地区设置,一定要有充分的理由,这样你就不会无意中引入新的错误。