Search code examples
pythongoogle-app-enginedatetimepytzpython-dateutil

How to remove the tzinfo completely from the time after converting to UTC in Python?


I came across this exact issue, and I can't figure out how to achieve the solution in my case.

Guido says

The solution is to remove the tzinfo completely from the time after converting to UTC.

This is what I have tried:

        date_time = parser.parse(i.pubDate.text)
        news.publication_date = date_time.replace(tzinfo=None).date()

And I get the same error:

NotImplementedError: DatetimeProperty publication_date_time can only support UTC. Please derive a new Property to support alternative timezones.

So it seems I have to convert the date to UTC first. And here my research has failed me.

I came across this solution:

The solution suggested is this:

def date_time_to_utc(date_time):
        tz = pytz.timezone('???')
        return tz.normalize(tz.localize(date_time)).astimezone(pytz.utc)

But I don't have the timezone. I am scraping the date from a html source. So the timezone could really be from anywhere in the world. Is there no easy and reliable way to convert a date time to UTC? I could use both dateutil and pytz to achieve this. Many Thanks.

UPDATE It has been a really long day. I have misread the stack trace. However the question remains valid.

date_time = (datetime}2015-01-13 18:13:26+00:00
news.publication_date_time = date_time

This caused the crash. And it seems by doing this, I pass the unit test:

news.publication_date_time = date_time.replace(tzinfo=None)

Is this the correct way converting a GMT 0 datetime to UTC datetime? Or in fact any timezone to UTC?


Solution

  • Is this the correct way converting a GMT 0 datetime to UTC datetime? Or in fact any timezone to UTC?

    If aware datetime object is already in UTC (+0000) then your formula works:

    naive_utc = aware_utc.replace(tzinfo=None)
    

    where aware_utc is a timezone-aware datetime object that represents time in UTC.

    But if aware datetime object is not in UTC; it fails. You should take into account a (possibly) non-zero UTC offset in the general case:

    assert aware.tzinfo is not None and aware.utcoffset() is not None
    # local time = utc time + utc offset (by definition)
    # -> utc = local - offset
    naive_utc = aware.replace(tzinfo=None) - aware.utcoffset()
    

    where aware is a timezone-aware datetime object in an arbitrary timezone.


    But I don't have the timezone. I am scraping the date from a html source. So the timezone could really be from anywhere in the world. Is there no easy and reliable way to convert a date time to UTC? I could use both dateutil and pytz to achieve this. Many Thanks.

    No. dateutil, pytz won't help you unless the date string itself contains the timezone (or at least its utc offset).

    Remember: It is always noon somewhere on Earth i.e., if you collect date/time strings from different places on Earth then you can't compare them unless you attach the corresponding timezones. You can't convert it to UTC, you can't get a valid POSIX timestamp if you don't know the source timezone for the date.