I'm trying to convert a timestamp with a specific timezone(Europe/Paris) to a datetime format in UTC. From my laptop it works with the solution below but when I'm executing my code in a remote server(AWS- Lambda function in Ireland), I've a shift of 1 hour because the local timezone of the server is different from mine. How can I have a code who can work on my laptop and at the same time in a remote server(dynamically handle local timezone)?
import pytz
import datetime
def convert_timestamp_in_datetime_utc(timestamp_received):
utc = pytz.timezone('UTC')
now_in_utc = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(pytz.UTC)
fr = pytz.timezone('Europe/Paris')
new_date = datetime.datetime.fromtimestamp(timestamp_received)
return fr.localize(new_date, is_dst=None).astimezone(pytz.UTC)
Thanks
I am not sure what timestamp_received
is, but I think what you want is utcfromtimestamp()
import pytz
from datetime import datetime
def convert_timestamp_in_datetime_utc(timestamp_received):
dt_naive_utc = datetime.utcfromtimestamp(timestamp_received)
return dt_naive_utc.replace(tzinfo=pytz.utc)
For completeness, here is another way to accomplish the same thing by referencing python-dateutil
's tzlocal
time zone:
from dateutil import tz
from datetime import datetime
def convert_timestamp_in_datetime_utc(timestamp_received):
dt_local = datetime.fromtimestamp(timestamp_received, tz.tzlocal())
if tz.datetime_ambiguous(dt_local):
raise AmbiguousTimeError
if tz.datetime_imaginary(dt_local):
raise ImaginaryTimeError
return dt_local.astimezone(tz.tzutc())
class AmbiguousTimeError(ValueError):
pass
class ImaginaryTimeError(ValueError):
pass
(I added in the AmbiguousTimeError
and ImaginaryTimeError
conditions to mimic the pytz
interface.) Note that I'm including this just in case you have a similar problem that needs to make reference to the local time zone for some reason - if you have something that will give you the right answer in UTC, it's best to use that and then use astimezone
to get it into whatever local zone you want it in.
How it works
Since you expressed that you were still a bit confused about how this works in the comments, I thought I would clarify why this works. There are two functions that convert timestamps to datetime.datetime
objects, datetime.datetime.fromtimestamp(timestamp, tz=None)
and datetime.datetime.utcfromtimestamp(timestamp)
:
utcfromtimestamp(timestamp)
will give you a naive datetime
that represents the time in UTC. You can then do dt.replace(tzinfo=pytz.utc)
(or any other utc
implementation - datetime.timezone.utc
, dateutil.tz.tzutc()
, etc) to get an aware datetime and convert it to whatever time zone you want.
fromtimestamp(timestamp, tz=None)
, when tz
is not None
, will give you an aware datetime
equivalent to utcfromtimestamp(timestamp).replace(tzinfo=timezone.utc).astimezone(tz)
. If tz
is None
, instead of converting too the specified time zone, it converts to your local time (equivalent to dateutil.tz.tzlocal()
), and then returns a naive datetime
.
Starting in Python 3.6, you can use datetime.datetime.astimezone(tz=None)
on naive datetimes, and the time zone will be assumed to be system local time. So if you're developing a Python >= 3.6 application or library, you can use datetime.fromtimestamp(timestamp).astimezone(whatever_timezone)
or datetime.utcfromtimestamp(timestamp).replace(tzinfo=timezone.utc).astimezone(whatever_timezone)
as equivalents.