1

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?

Community
  • 1
  • 1
Houman
  • 64,245
  • 87
  • 278
  • 460
  • The code you've posted ("This is what I have tried:") shows you turning your 'naive' datetime into a date, but the error is coming from a DatetimeProperty. Does the trace definitely lead to the code you've shown? It looks correct... – Greg Jan 15 '15 at 22:23
  • @Houman: you don't need `.replace(tzinfo=None)` before `.date()`. It returns a `date` object that is always naive. – jfs Jan 16 '15 at 11:56

3 Answers3

2

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.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • May you please explain what `aware_utc` means? Is GMT +1 an `aware_utc` ? – Houman Jan 16 '15 at 12:12
  • @Houman: yes. no. `aware_utc` *always* has **zero** utc offset. GMT+1 implies 1 hour utc offset i.e., `GMT+1` is not `aware_utc`. Just use the formula that I've provided. It always works. – jfs Jan 16 '15 at 12:15
  • ah many thanks for the explanation. So if my datetime always shows in GMT it is safer to convert it like this: `naive_utc = aware.replace(tzinfo=None) - aware.utcoffset()`. Beware I live in UK, during winter time, our UTC/GMT offset is zero, hence looks the same. hence the date I provided above `date_time = (datetime}2015-01-13 18:13:26+00:00` should be GMT +0, It is not UTC. (Unless I am mixing it up and the format shown is actually UTC and GMT is written differently) :) – Houman Jan 16 '15 at 12:22
  • @Houman: yes. if the offset ever may be non-zero then you should use the more general formula. – jfs Jan 16 '15 at 15:00
0

I'm an idiot and it's late here, this time I read the question.

tstmp= date_time.replace(tzinfo=utc).total_seconds()
naive_date = datetime.utcfromtimestamp(tstmp)

First answer will just give you the current naive time

Bogdan
  • 101
  • 5
0

Try this:

dateTime = dateTime.replace(tzinfo=None)
dtUtcAware = pytz.UTC.localize(dateTime)
ChrisC73
  • 1,833
  • 14
  • 14