Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python convert timestamps with specific timezone to datetime in UTC

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

like image 626
Matt Avatar asked Jan 12 '17 12:01

Matt


People also ask

How do you convert timezone to UTC in Python?

Use the pytz module, which comes with a full list of time zones + UTC. Figure out what the local timezone is, construct a timezone object from it, and manipulate and attach it to the naive datetime. Finally, use datetime. astimezone() method to convert the datetime to UTC.

How do I convert datetime to UTC?

To convert the time in a non-local time zone to UTC, use the TimeZoneInfo. ConvertTimeToUtc(DateTime, TimeZoneInfo) method. To convert a time whose offset from UTC is known, use the ToUniversalTime method. If the date and time instance value is an ambiguous time, this method assumes that it is a standard time.

How do I convert datetime from one time zone to another in Python?

Get the current time using the datetime. now() function and pass the above second−time zone i.e 'US/Eastern' time zone as an argument to it(Here it converts the current date and time to the 'US/Eastern' timezone). Use the strftime() function to format the above datetime object and print it.

Are timestamps in UTC?

Timestamps should certainly be stored in UTC. How the date is formatted is dependent on the requirements for that timezone. Timestamps are generally stored in UTC so the conversion for display to other timezones is easier and possible.


1 Answers

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):

  1. 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.

  2. 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.

like image 105
Paul Avatar answered Sep 22 '22 13:09

Paul