0

I can't figure out how to show a timezone-aware datetime without the trailing offset.

My class has a property "date_created", which saves the datetime, and I am working with Python 3.7. I could not find a built-in function that suited my needs, or I'm too blind to find it in the docs. However, here is what I am trying to do:

Current simplified code:

print(f'Creation Date (UTC): {self.date_created}')
print(f'Creation Date (local): {self.date_created.astimezone()}')

Results (as expected):

>>> Creation Date (UTC): 2021-08-03 10:37:12
>>> Creation Date (local): 2021-08-03 10:37:12+02:00

What I am trying to achieve is:

>>> Creation Date (UTC): 2021-08-03 10:37:12
>>> Creation Date (local): 2021-08-03 12:37:12

Is there a built-in method to do this or do I really have to write something that will "recalculate" my local datetime?

Wouter
  • 534
  • 3
  • 14
  • 22

2 Answers2

0

If you're starting with a naïve datetime object, then you must first attach an explicit timezone to it, before being able to convert it to some other timezone. I'll assume your initial datetime is supposed to be in UTC; then you must explicitly set that:

from datetime import timezone
self.date_created.astimezone(timezone.utc)

Now it makes sense to convert that into another timezone:

self.date_created.astimezone(timezone.utc).astimezone()

And if you don't want to print the timezone offset as part of the output, format it explicitly:

self.date_created.astimezone(timezone.utc).astimezone().strftime('%Y-%m-%d %H:%M:%S')
deceze
  • 510,633
  • 85
  • 743
  • 889
  • i followed your steps, but that does not work. The original `{self.date_created}` and also the new `{self.date_created.astimezone(timezone.utc).astimezone().strftime("%Y-%m-%d %H:%M:%S")}` now both result in the same datetime `Creation Date (UTC): 2021-08-03 10:37:12` and `Creation Date (local): 2021-08-03 10:37:12`. Indeed, without offset, but not what i wanted :) . Maybe its worth to mention that date_created is set via SQLAlchemy with `date_created = db.Column(db.DateTime(timezone=True), default=func.now())` which should represent UTC. – Marcel Holl Aug 03 '21 at 16:46
  • Then I’m not sure what that means, whether the original date is aware or not, and what value it really is. – deceze Aug 03 '21 at 19:15
0

After some more digging in the related posts, i came across the solution as described here by David Foster (thanks for that).

a short method does the trick:

from datetime import datetime, timezone
import time

def utc2local(utc):
    epoch = time.mktime(utc.timetuple())
    offset = datetime.fromtimestamp(epoch) - datetime.utcfromtimestamp(epoch)
    return utc + offset

this converts the UTC-datetime nicely to the local-version.

print(f'(UTC): {self.date_created}')              >>>> (UTC): 2021-08-03 10:37:12
print(f'(local): {utc2local(self.date_created)}') >>>> (local): 2021-08-03 12:37:12

I guess, there is no other method then calculating the local-version with the help of the offset. But thats fine :)