如何用零替换datetime strftime的缺失部分?

How to replace missing parts of datetime strftime with zeroes?

我收到日期对象,需要根据以下格式将其转换为字符串:

1
"%a %b %d %H:%M:%S %z %Y"

为了实现这一点,我使用了python的datetime.strftime方法。问题是,有时这些日期对象不具有所有这些数据,例如,我可以同时具有以下两种数据:

1
2
a = datetime.date(1999, 1, 2)
b = datetime.datetime(2015, 10, 1, 9, 38, 50, 920000, tzinfo=datetime.timezone.utc)

尝试使用字符串格式方法:

1
"{:%a %b %d %H:%M:%S %z %Y}".format(a)

但如果未设置时区,则会将其删除,因此:

1
2
"{:%a %b %d %H:%M:%S %z %Y}".format(b)
'Thu Oct 01 09:38:50 +0000 2015'

但是

1
2
"{:%a %b %d %H:%M:%S %z %Y}".format(a)
'Sat Jan 02 00:00:00  1999'

而对于一个来说,它应该是:

1
'Sat Jan 02 00:00:00 +0000 1999'

是否可以用零填充时区?


正如您可能从strftime文档中注意到的那样,如果datetime对象是幼稚的,即没有时区集,则%z和%z将生成一个空字符串。

如果你总是希望它发出+0000,即使你不知道时区,你想要的是把它当作UTC。

所以设置一个默认值。如果时区没有传递给您,请像您那样使用时区信息,即tzinfo = datetime.timezone.utc。在这种情况下,你总会得到一个+0000。

更新,回应评论:

你要意识到,当你在开始的时候,你已经承诺了。在这一点上,您的日期时间已经是幼稚的或有意识的,并且它很好地定义了strftime在这两种情况下的行为方式。设置默认值时,您可能不应该在格式化点进行设置,而应该在构建日期时间点进行设置。

如果没有看到更多的代码,我就无法提供更具体的帮助,但显然您有一些东西可以区分A和B的数据,因此您必须知道是否有可用的TZINFO。我准备举一个例子,这样我就可以告诉你把默认值放在哪里了:

1
2
3
4
5
6
7
8
9
10
for it in magic_iterator:
   (year, month, day, hour, minute, second, microsecond, timezone) = it.get_data()
   # note, some of these can be None.  Set defaults:
   hour = hour or 0
   minute = minute or 0
   second = second or 0
   timezone = timezone or datetime.tzinfo.utc

   foo = datetime(year, month, day, hour, minute, second, microsecond, timezone)
   # do something with foo

使用or的这个构造将查看这些值是否是假的(即假、0或空字符串),如果是,则适当地设置它们。注意,在小时、分钟和秒的情况下,如果实际值为0,则执行条款的or部分,因为0是虚假的。这通常是一个逻辑错误(通过执行hour = hour if hour is not None else 0之类的操作来解决),但在本例中,您将把已经是0的值设置为0,所以没关系。

想想看,你可以把它当作一个附在format上的一行程序,但它很难看:

1
"{:%a %b %d %H:%M:%S %z %Y}".format(a if a.tzinfo else datetime(a.year, a.month, a.day, a.hour, a.minute, a.second, a.microsecond, datetime.tzinfo.utc))

我更愿意将缺省值放在datetime的构造中,而不是放在格式化行中。