Question

I'm coding a Python 3 script that receives a full date with offset and I want to be able to compare it to another date without offset. The main problem I'm facing is that Python doesn't seem to like different offset datetime objects as it complains when you try to do any operation with those:

>>> date_string
'Wed, 8 May 2013 15:33:29 +0200'
>>> new_date = datetime.strptime(date_string, '%a, %d %b %Y %H:%M:%S %z')
>>> new_date
datetime.datetime(2013, 5, 8, 15, 33, 29, tzinfo=datetime.timezone(datetime.timedelta(0, 7200)))
>>> new_date - datetime.today()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't subtract offset-naive and offset-aware datetimes

As a workaround I've stripped date_string into two strings, once with the date and one with the offset, creating two objects: one date and one delta, them sum them up:

>>> date_string
'Wed, 8 May 2013 15:33:29 +0200'
>>> match = re.match(r'(.*)(\s\+\d{4})',date_string)
>>> match.group(1)
'Wed, 8 May 2013 15:33:29'
>>> match.group(2)
' +0200'
>>> parsed_date = datetime.strptime(match.group(1), '%a, %d %b %Y %H:%M:%S')
>>> match_delta = re.match(r'\s\+(\d{2})(\d{2})',match.group(2))
>>> parsed_date_delta = timedelta(minutes=int(match_delta.group(2)),hours=int(match_delta.group(1)))
>>> parsed_date_complete = parsed_date + parsed_date_delta
>>> parsed_date_complete
datetime.datetime(2013, 5, 8, 17, 33, 29)

With this I'm able to get a final hour with the correct offset applied, so any comparision with another normal datetime object wouldn't raise an error.

The thing I'm wondering is if there's an easier or more efficient way of achieving this. The idea is to receive a string like this one: Wed, 8 May 2013 15:33:29 +0200 and be able to convert it in a datetime object without offset, so I can work with UTC times.

EDIT: To explain a little more the issue, new_date has an offset value of +0200 while datetime.today() and datetime.utcnow() doesn't have that offset, so trying to compare it or do any operation gives the following error in Python: TypeError: can't subtract offset-naive and offset-aware datetimes.

If date is Wed, 8 May 2013 15:33:29 +0200, what I want is a way to calculate date like this: Wed, 8 May 2013 17:33:29, without the offset value but with the right time (offset applied to time). That way, since I don't have the offset, I can freely do stuff with datetime.today() and datetime.utcnow()

Was it helpful?

Solution

I am no python guru, but according to these docs:

classmethod datetime.today()

Return the current local datetime, with tzinfo None. ...

There is no time zone associated with the return value. It's not at UTC, the offset is just unspecified. It therefore makes sense that it wouldn't allow you to compare the two. The result would be meaningless.

In other words, what would you expect the result of this to be?

10 May 2013 13:00 +0200  >  10 May 2013 12:00
  • It could be true, because 13:00 is a greater value than 12:00.
  • It could be false, because maybe the local time zone offset is -0100, so you are comparing the moments 11:00Z > 13:00Z. But who knows if we even meant to use the local offset since we didn't specify.

Since we are referring to an exact moment on the left side, but an ambiguous one on the right, the operation gives an error.

It's good that Python gives an error when you try to do this. Other frameworks such as .Net make some assumptions and return results that might not be what you were expecting. (Read here if you are interested.)

So going back to your question, you said:

The idea is to receive a string like this one: Wed, 8 May 2013 15:33:29 +0200 and be able to convert it in a datetime object without offset, so I can work with UTC times.

The string you have is already reflecting its offset from UTC. The way you are parsing it is just fine. You just need to compare it to something that is more meaningful, such as datetime.now(timezone.utc)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top