如何检查日期时间对象是否使用 pytz 本地化?

我想存储一个带有本地化 UTC 时区的日期时间对象。可以为存储 datetime 对象的方法提供一个非本地化的 datetime (初始)对象或一个已经本地化的对象。如何确定是否需要本地化?

缺少条件的代码:

class MyClass:
def set_date(self, d):
# what do i check here?
# if(d.tzinfo):
self.date = d.astimezone(pytz.utc)
# else:
self.date = pytz.utc.localize(d)
59002 次浏览

if you want to check if a datetime object 'd' is localized, check the d.tzinfo, if it is None, no localization.

How do I determine if localization is needed?

From datetime docs:

  • a datetime object d is aware iff:

    d.tzinfo is not None and d.tzinfo.utcoffset(d) is not None
    
  • d is naive iff:

    d.tzinfo is None or d.tzinfo.utcoffset(d) is None
    

Though if d is a datetime object representing time in UTC timezone then you could use in both cases:

self.date = d.replace(tzinfo=pytz.utc)

It works regardless d is timezone-aware or naive.

Note: don't use datetime.replace() method with a timezone with a non-fixed utc offset (it is ok to use it with UTC timezone but otherwise you should use tz.localize() method).

Here's a more complete function to convert or coerce a timestamp obj to utc. If it reaches the exception this means the timestamp is not localized. Since it's good practice to always work in UTC within the code, this function is very useful at the entry level from persistence.

def convert_or_coerce_timestamp_to_utc(timeobj):
out = timeobj
try:
out = timeobj.astimezone(pytz.utc) # aware object can be in any timezone
except (ValueError,TypeError) as exc: # naive
out = timeobj.replace(tzinfo=pytz.utc)
return out

The small addition from the 'try catch' in the answer by J.F. Sebastian is the additional catch condition, without which not all naive cases will be caught by the function.

Here is a function wrapping up the top answer.

def tz_aware(dt):
return dt.tzinfo is not None and dt.tzinfo.utcoffset(dt) is not None