viam0Zah
viam0Zah

Reputation: 26312

How to render timestamp according to the timezone in Python

I have two datetime objects, they represent the same datetime value in different timezones. I would like to convert them to POSIX timestamp. However appearently calling datetime.timestamp() returns a value regardless of the timezone.

from datetime import datetime
import pytz

dt = datetime(2020, 7, 26, 6, 0) 
utc_dt = pytz.utc.localize(dt) # datetime.datetime(2020, 7, 26, 6, 0, tzinfo=<UTC>)
bp = pytz.timezone("Europe/Budapest")
bp_dt = utc_dt.astimezone(bp)  # datetime.datetime(2020, 7, 26, 8, 0, tzinfo=<DstTzInfo 'Europe/Budapest' CEST+2:00:00 DST>)
utc_dt.timestamp() # 1595743200.0
bp_dt.timestamp()  # 1595743200.0

The documentation of datetime.timestamp() says the following:

For aware datetime instances, the return value is computed as:

(dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()

Running utc_dt - bp_dt returns datetime.timedelta(0). So it seems it calculates with the UTC value of the datetime objects.

I use Python in a web stack. I want the backend to deal with the timezone handling and the client to recieve the precalculated datetime values in the user's timezone in the API responses.

What is the Pythonic way to get timezone aware timestamps?

Upvotes: 0

Views: 437

Answers (1)

FObersteiner
FObersteiner

Reputation: 25544

In short, I would not recommend doing this because you can create a total mess, see my comment.


Technically, you could do it by simply replacing the tzinfo property of the datetime object with UTC. Note that I'm using dateutil.tz here so I can set the initial timezone directly (no localize()).

from datetime import datetime, timezone
from dateutil import tz

dt = datetime(2020, 7, 26, 6, 0, tzinfo=tz.gettz("Europe/Budapest"))
# dt.utcoffset()
# >>> datetime.timedelta(seconds=7200)

# POSIX timestamp that references to 1970-01-01 UTC:
ts_posix = dt.timestamp()

# timestamp that includes the UTC offset:
ts = dt.replace(tzinfo=timezone.utc).timestamp()

# ts-ts_posix
# >>> 7200.0

Upvotes: 1

Related Questions