1

I seem to be having a weird issue. Maybe it's a bug in Python but I would be surprised if it was.

I'm trying to test converting a naive datetime to UTC by first timezone information to it:

import datetime
from pytz import timezone

naive_datetime = datetime.datetime.now()
local_datetime = naive_datetime.replace(tzinfo=timezone('Europe/London'))
utc_datetime = local_datetime.astimezone(timezone('UTC'))
print("Naive datetime:", naive_datetime)
print("Local datetime:", local_datetime)
print("UTC datetime:  ", utc_datetime)

This is the output:

Naive datetime: 2020-05-14 11:46:44.637956
Local datetime: 2020-05-14 11:46:44.637956-00:01
UTC datetime:   2020-05-14 11:47:44.637956+00:00

Note that adding a "Local timezone" of 'Europe/London' adds -1 minute of offset, not +1 hour as I would expect resulting in a "UTC" time of the original time +1 minute not -1 hour.

Why is it adding a minute offset and how do I get this to do what I expect?

Oliver P
  • 3,029
  • 2
  • 16
  • 12

1 Answers1

3

don't replace() the timezone, localize() the datetime object:

import datetime
from pytz import timezone

# call now() with a tz
local_datetime = datetime.datetime.now(tz=timezone('Europe/London'))

# or localize
naive_datetime = datetime.datetime.now()
tz = timezone('Europe/London')
local_datetime = tz.localize(naive_datetime)
# datetime.datetime(2020, 5, 14, 13, 6, 2, 512100, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)

# now you can use astimezone to change the tz:
utc_datetime = local_datetime.astimezone(timezone('UTC'))
# datetime.datetime(2020, 5, 14, 12, 6, 2, 512100, tzinfo=<UTC>)

Note: you might also have to normalize() if you change between timezones that have DST, see e.g. here.

FObersteiner
  • 22,500
  • 8
  • 42
  • 72
  • Thank you. Also good to know about normalize(). I found a solution to change the replace() line to: ```python local_datetime = naive_datetime.astimezone(timezone('Europe/London')) ``` But I think your localize() solution is clearer as to exactly what the code is doing. – Oliver P May 14 '20 at 11:29
  • @OliverP: glad I could help. Note that calling `astimezone` on a naive datetime object will make Python assume that the datetime object belongs in the timezone of the operating system. – FObersteiner May 14 '20 at 11:45