convert given time from a given timezone to UTC - python

I have two inputs time 00:00 and timezone 'Asia/Kolkata'
I want to convert this to UTC time like '18.30'
I don't want to add or subtract offsets because it may affect the day light saving
what i did is
local = pytz.timezone ("UTC")
nativetime = datetime.strptime (setTime,frmt)
local_dt = local.localize(nativetime, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)
but this doesn't change anything, the time is not converted to UTC
Please help

Something like this, assuming you're on py3:
>>> import datetime
>>> import pytz
>>> tz = pytz.timezone('Asia/Kolkata')
>>> dt = datetime.datetime(2020, 8, 4, 0, 0, tzinfo=tz)
>>> dt.astimezone(pytz.utc)
datetime.datetime(2020, 8, 3, 18, 7, tzinfo=<UTC>)
>>>

Since you say you're new to Python, it might be good to skip pytz since it's going to be deprecated with Python 3.9. You can use dateutil instead, which can be replaced more easily with zoneinfo in Python 3.9.
from datetime import datetime, timezone
from dateutil.tz import gettz
# assuming you have something like
dt_naive = datetime.strptime('2020-08-05', '%Y-%m-%d')
# dt_naive has no time zone info, so set it:
dt_aware = dt_naive.replace(tzinfo=gettz('Asia/Kolkata'))
# now you can convert to another timezone using .astimezone:
dt_aware_utc = dt_aware.astimezone(timezone.utc)
# datetime.datetime(2020, 8, 4, 18, 30, tzinfo=datetime.timezone.utc)
# -> 5:30 hours behind, which matches dt_aware.utcoffset()

#thebjorn gave me the answer
here is what i did
def utc_to_local(utc_dt,local_tz):
local_dt = utc_dt.replace(tzinfo=pytz.utc).astimezone(local_tz)
return local_tz.normalize(local_dt)
setTime='00:00:00'
setZone='Asia/Kolkata'
datePart = str(datetime.utcnow()).split(' ')[0]
dateTimeUtcStr = datePart+' '+str(setTime)
tz = pytz.timezone('Asia/Kolkata')
tz_utc = pytz.timezone('UTC')
dateTimeRef = datetime.strptime(dateTimeUtcStr, '%Y-%m-%d %H:%M:%S')
#local to utc
tzUtc = pytz.timezone('UTC')
local_dt = tz.localize(dateTimeRef, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)
print(utc_dt)
#utc to local
altTime = utc_to_local(utc_dt,tz)
print(altTime)

Related

Python time zone conversion from UTC to EST

I have the below list in python.
[['File_1','2021-09-09 07:05:10'],['File_2','2021-09-08 08:05:11']]
The above timestamp is a string in UTC timezone. I would like to convert this to EST timezone.
I tried using pytz package using
datetime.strptime(timestamp,'%Y-%m-%d %H:%M:%S').astimezone(pytz.timezone('US/Eastern'))
but it gives me result like
['File_1',datetime.datetime(2021,09,03,4,20,5)].
The format of date time is not as expected.
you need to set UTC first, then convert to the desired tz:
from datetime import datetime, timezone
from zoneinfo import ZoneInfo # Python 3.9+ standard lib
l = [['File_1','2021-09-09 07:05:10'],['File_2','2021-09-08 08:05:11']]
out = [[i[0], datetime.fromisoformat(i[1]) # Python 3.7+
.replace(tzinfo=timezone.utc)
.astimezone(ZoneInfo("America/New_York"))] for i in l]
print(out)
# [['File_1', datetime.datetime(2021, 9, 9, 3, 5, 10, tzinfo=zoneinfo.ZoneInfo(key='America/New_York'))], ['File_2', datetime.datetime(2021, 9, 8, 4, 5, 11, tzinfo=zoneinfo.ZoneInfo(key='America/New_York'))]]
# with pytz:
import pytz
outp = [[i[0], datetime.fromisoformat(i[1]) # Python 3.7+
.replace(tzinfo=timezone.utc)
.astimezone(pytz.timezone("America/New_York"))] for i in l]
print(outp)
# [['File_1', datetime.datetime(2021, 9, 9, 3, 5, 10, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)], ['File_2', datetime.datetime(2021, 9, 8, 4, 5, 11, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)]]
If you want a string instead of datetime object, use strftime or even simpler: .isoformat().
You can use the below snippet to get your output in the same format as your input
from datetime import datetime
import pytz
from pytz import timezone
timestamp = '2021-09-09 07:05:10'
datetime.strptime(timestamp,'%Y-%m-%d %H:%M:%S').astimezone(pytz.timezone('US/Eastern')).strftime("%Y-%m-%d %H:%M:%S")
# Output
'2021-09-09 03:05:10'
If you wish to display the timezone in the format, you can use
datetime.strptime(timestamp,'%Y-%m-%d %H:%M:%S').astimezone(pytz.timezone('US/Eastern')).strftime("%Y-%m-%d %H:%M:%S %Z%z")
# Output
'2021-09-09 03:05:10 EDT-0400'
Here's one way to convert it to EST
1st. Declare the list, and identify the date you want to convert as string
list = [['File_1','2021-09-09 07:05:10'],['File_2','2021-09-08 08:05:11']]
date_to_convert = list[1][1]
2nd. Import the needed libraries
import pytz
from datetime import datetime,timezone
3rd. Convert the string to date time
d = datetime.fromisoformat(date_to_convert)
4th. Declare datetime timezone as utc.
d = date_to_string.replace(tzinfo=timezone.utc)
print(d.isoformat())
# the output for the above: '2021-09-08T08:05:11+00:00'
5th. Set the format and convert to EST
fmt = '%Y-%m-%d %H:%M:%S'
est_date = d.astimezone(pytz.timezone('US/Eastern')).strftime(fmt)
print(est_date)
# the output for the above: '2021-09-08 04:05:11'
USE THIS WAY REMBER UPERCASE AND LOWERCASE ALSO MATTER
import time
timer = time.strftime("%Y-%m-%d -- %H:%M:%S %p")
print(timer)

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?
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

How do I get New York City time?

I travel frequently but live in NYC and am trying to display NYC time no matter where I am. How do I do that in Python? I have the following, which doesn't work, giving me the error:
`'module' object is not callable`
Also, I'm not sure if my method below will correctly update with daylight savings time or not:
import pytz
utc = pytz.utc
utc_dt = datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
eastern = pytz.timezone('US/Eastern')
loc_dt = utc_dt.astimezone(eastern)
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
loc_dt.strftime(fmt)
Instead of datetime, write datetime.datetime:
import datetime
import pytz
utc = pytz.utc
utc_dt = datetime.datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
eastern = pytz.timezone('US/Eastern')
loc_dt = utc_dt.astimezone(eastern)
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
loc_dt.strftime(fmt)
That's because the module datetime contains a class datetime.datetime.
You can get a datetime object of the current time in a specific timezone using the now() method in the following fashion:
import datetime, pytz
nyc_datetime = datetime.datetime.now(pytz.timezone('US/Eastern'))
It's cleaner to write your import like this:
from datetime import datetime
import pytz
now = datetime.now(tz=pytz.timezone('US/Eastern'))
This allows re-use of datetime further down your code, without having to datetime.datetime every single time. Also avoids importing the entire datetime module unnecessarily.
Also note that according to IANA, 'US/Eastern' has been deprecated. Perhaps consider 'America/New_York'
i will do this instead:
import datetime
import pytz
now = datetime.datetime.now(tz=pytz.timezone('US/Eastern'))
print("now time is: ", now)
current_hour = now.hour
current_minute = now.minute
current_second = now.second
current_weekday = now.weekday()
New in Python 3.9, you may choose zoneinfo instead of third party library
from zoneinfo import ZoneInfo
from datetime import datetime
dt = datetime(2022, 11, 16, 1, tzinfo=ZoneInfo("US/Eastern"))
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
dt.strftime(fmt)

Python Timezone conversion

How do I convert a time to another timezone in Python?
I have found that the best approach is to convert the "moment" of interest to a utc-timezone-aware datetime object (in python, the timezone component is not required for datetime objects).
Then you can use astimezone to convert to the timezone of interest (reference).
from datetime import datetime
import pytz
utcmoment_naive = datetime.utcnow()
utcmoment = utcmoment_naive.replace(tzinfo=pytz.utc)
# print "utcmoment_naive: {0}".format(utcmoment_naive) # python 2
print("utcmoment_naive: {0}".format(utcmoment_naive))
print("utcmoment: {0}".format(utcmoment))
localFormat = "%Y-%m-%d %H:%M:%S"
timezones = ['America/Los_Angeles', 'Europe/Madrid', 'America/Puerto_Rico']
for tz in timezones:
localDatetime = utcmoment.astimezone(pytz.timezone(tz))
print(localDatetime.strftime(localFormat))
# utcmoment_naive: 2017-05-11 17:43:30.802644
# utcmoment: 2017-05-11 17:43:30.802644+00:00
# 2017-05-11 10:43:30
# 2017-05-11 19:43:30
# 2017-05-11 13:43:30
So, with the moment of interest in the local timezone (a time that exists), you convert it to utc like this (reference).
localmoment_naive = datetime.strptime('2013-09-06 14:05:10', localFormat)
localtimezone = pytz.timezone('Australia/Adelaide')
try:
localmoment = localtimezone.localize(localmoment_naive, is_dst=None)
print("Time exists")
utcmoment = localmoment.astimezone(pytz.utc)
except pytz.exceptions.NonExistentTimeError as e:
print("NonExistentTimeError")
Using pytz
from datetime import datetime
from pytz import timezone
fmt = "%Y-%m-%d %H:%M:%S %Z%z"
timezonelist = ['UTC','US/Pacific','Europe/Berlin']
for zone in timezonelist:
now_time = datetime.now(timezone(zone))
print now_time.strftime(fmt)
import datetime
import pytz
def convert_datetime_timezone(dt, tz1, tz2):
tz1 = pytz.timezone(tz1)
tz2 = pytz.timezone(tz2)
dt = datetime.datetime.strptime(dt,"%Y-%m-%d %H:%M:%S")
dt = tz1.localize(dt)
dt = dt.astimezone(tz2)
dt = dt.strftime("%Y-%m-%d %H:%M:%S")
return dt
-
dt: date time string
tz1: initial time zone
tz2: target time zone
-
> convert_datetime_timezone("2017-05-13 14:56:32", "Europe/Berlin", "PST8PDT")
'2017-05-13 05:56:32'
> convert_datetime_timezone("2017-05-13 14:56:32", "Europe/Berlin", "UTC")
'2017-05-13 12:56:32'
-
> pytz.all_timezones[0:10]
['Africa/Abidjan',
'Africa/Accra',
'Africa/Addis_Ababa',
'Africa/Algiers',
'Africa/Asmara',
'Africa/Asmera',
'Africa/Bamako',
'Africa/Bangui',
'Africa/Banjul',
'Africa/Bissau']
Python 3.9 adds the zoneinfo module so now only the the standard library is needed!
>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime
>>> d = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo('America/Los_Angeles'))
>>> d.astimezone(ZoneInfo('Europe/Berlin')) # 12:00 in Cali will be 20:00 in Berlin
datetime.datetime(2020, 10, 31, 20, 0, tzinfo=zoneinfo.ZoneInfo(key='Europe/Berlin'))
Wikipedia list of available time zones
Some functions such as now() and utcnow() return timezone-unaware datetimes, meaning they contain no timezone information. I recommend only requesting timezone-aware values from them using the keyword tz=ZoneInfo('localtime').
If astimezone gets a timezone-unaware input, it will assume it is local time, which can lead to errors:
>>> datetime.utcnow() # UTC -- NOT timezone-aware!!
datetime.datetime(2020, 6, 1, 22, 39, 57, 376479)
>>> datetime.now() # Local time -- NOT timezone-aware!!
datetime.datetime(2020, 6, 2, 0, 39, 57, 376675)
>>> datetime.now(tz=ZoneInfo('localtime')) # timezone-aware
datetime.datetime(2020, 6, 2, 0, 39, 57, 376806, tzinfo=zoneinfo.ZoneInfo(key='localtime'))
>>> datetime.now(tz=ZoneInfo('Europe/Berlin')) # timezone-aware
datetime.datetime(2020, 6, 2, 0, 39, 57, 376937, tzinfo=zoneinfo.ZoneInfo(key='Europe/Berlin'))
>>> datetime.utcnow().astimezone(ZoneInfo('Europe/Berlin')) # WRONG!!
datetime.datetime(2020, 6, 1, 22, 39, 57, 377562, tzinfo=zoneinfo.ZoneInfo(key='Europe/Berlin'))
Windows has no system time zone database, so here an extra package is needed:
pip install tzdata
There is a backport to allow use in Python 3.6 to 3.8:
sudo pip install backports.zoneinfo
Then:
from backports.zoneinfo import ZoneInfo
Time conversion
To convert a time in one timezone to another timezone in Python, you could use datetime.astimezone():
so, below code is to convert the local time to other time zone.
datetime.datetime.today() - return current the local time
datetime.astimezone() - convert the time zone, but we have to pass the time zone.
pytz.timezone('Asia/Kolkata') -passing the time zone to pytz module
Strftime - Convert Datetime to string
# Time conversion from local time
import datetime
import pytz
dt_today = datetime.datetime.today() # Local time
dt_India = dt_today.astimezone(pytz.timezone('Asia/Kolkata'))
dt_London = dt_today.astimezone(pytz.timezone('Europe/London'))
India = (dt_India.strftime('%m/%d/%Y %H:%M'))
London = (dt_London.strftime('%m/%d/%Y %H:%M'))
print("Indian standard time: "+India+" IST")
print("British Summer Time: "+London+" BST")
List all the time zones
import pytz
for tz in pytz.all_timezones:
print(tz)
To convert a time in one timezone to another timezone in Python, you could use datetime.astimezone():
time_in_new_timezone = time_in_old_timezone.astimezone(new_timezone)
Given aware_dt (a datetime object in some timezone), to convert it to other timezones and to print the times in a given time format:
#!/usr/bin/env python3
import pytz # $ pip install pytz
time_format = "%Y-%m-%d %H:%M:%S%z"
tzids = ['Asia/Shanghai', 'Europe/London', 'America/New_York']
for tz in map(pytz.timezone, tzids):
time_in_tz = aware_dt.astimezone(tz)
print(f"{time_in_tz:{time_format}}")
If f"" syntax is unavailable, you could replace it with "".format(**vars())
where you could set aware_dt from the current time in the local timezone:
from datetime import datetime
import tzlocal # $ pip install tzlocal
local_timezone = tzlocal.get_localzone()
aware_dt = datetime.now(local_timezone) # the current time
Or from the input time string in the local timezone:
naive_dt = datetime.strptime(time_string, time_format)
aware_dt = local_timezone.localize(naive_dt, is_dst=None)
where time_string could look like: '2016-11-19 02:21:42'. It corresponds to time_format = '%Y-%m-%d %H:%M:%S'.
is_dst=None forces an exception if the input time string corresponds to a non-existing or ambiguous local time such as during a DST transition. You could also pass is_dst=False, is_dst=True. See links with more details at Python: How do you convert datetime/timestamp from one timezone to another timezone?
For Python timezone conversions, I use the handy table from the PyCon 2012 presentation by Taavi Burns.
Please note: The first part of this answer is or version 1.x of pendulum. See below for a version 2.x answer.
I hope I'm not too late!
The pendulum library excels at this and other date-time calculations.
>>> import pendulum
>>> some_time_zones = ['Europe/Paris', 'Europe/Moscow', 'America/Toronto', 'UTC', 'Canada/Pacific', 'Asia/Macao']
>>> heres_a_time = '1996-03-25 12:03 -0400'
>>> pendulum_time = pendulum.datetime.strptime(heres_a_time, '%Y-%m-%d %H:%M %z')
>>> for tz in some_time_zones:
... tz, pendulum_time.astimezone(tz)
...
('Europe/Paris', <Pendulum [1996-03-25T17:03:00+01:00]>)
('Europe/Moscow', <Pendulum [1996-03-25T19:03:00+03:00]>)
('America/Toronto', <Pendulum [1996-03-25T11:03:00-05:00]>)
('UTC', <Pendulum [1996-03-25T16:03:00+00:00]>)
('Canada/Pacific', <Pendulum [1996-03-25T08:03:00-08:00]>)
('Asia/Macao', <Pendulum [1996-03-26T00:03:00+08:00]>)
Answer lists the names of the time zones that may be used with pendulum. (They're the same as for pytz.)
For version 2:
some_time_zones is a list of the names of the time zones that might be used in a program
heres_a_time is a sample time, complete with a time zone in the form '-0400'
I begin by converting the time to a pendulum time for subsequent processing
now I can show what this time is in each of the time zones in show_time_zones
...
>>> import pendulum
>>> some_time_zones = ['Europe/Paris', 'Europe/Moscow', 'America/Toronto', 'UTC', 'Canada/Pacific', 'Asia/Macao']
>>> heres_a_time = '1996-03-25 12:03 -0400'
>>> pendulum_time = pendulum.from_format('1996-03-25 12:03 -0400', 'YYYY-MM-DD hh:mm ZZ')
>>> for tz in some_time_zones:
... tz, pendulum_time.in_tz(tz)
...
('Europe/Paris', DateTime(1996, 3, 25, 17, 3, 0, tzinfo=Timezone('Europe/Paris')))
('Europe/Moscow', DateTime(1996, 3, 25, 19, 3, 0, tzinfo=Timezone('Europe/Moscow')))
('America/Toronto', DateTime(1996, 3, 25, 11, 3, 0, tzinfo=Timezone('America/Toronto')))
('UTC', DateTime(1996, 3, 25, 16, 3, 0, tzinfo=Timezone('UTC')))
('Canada/Pacific', DateTime(1996, 3, 25, 8, 3, 0, tzinfo=Timezone('Canada/Pacific')))
('Asia/Macao', DateTime(1996, 3, 26, 0, 3, 0, tzinfo=Timezone('Asia/Macao')))
For Python 3.2+ simple-date is a wrapper around pytz that tries to simplify things.
If you have a time then
SimpleDate(time).convert(tz="...")
may do what you want. But timezones are quite complex things, so it can get significantly more complicated - see the the docs.
# Program
import time
import os
os.environ['TZ'] = 'US/Eastern'
time.tzset()
print('US/Eastern in string form:',time.asctime())
os.environ['TZ'] = 'Australia/Melbourne'
time.tzset()
print('Australia/Melbourne in string form:',time.asctime())
os.environ['TZ'] = 'Asia/Kolkata'
time.tzset()
print('Asia/Kolkata in string form:',time.asctime())

How to get the difference in Localtime and GMT time python?

I get the server date and I need to get the difference of this date from GMT
I get
Datetime = "2011-04-27 2:17:45"
I would like to get the result like
Datetime = "2011-04-27 2:17:45 +0500"
Try this:
import datetime, pytz
now = datetime.datetime.now(pytz.timezone('Asia/Kolkata'))
print now.strftime('%Y-%m-%d %H:%M:%S %z')
# prints: '2011-04-27 13:56:09 +0530'
From the example you have given, it looks to me that what you are looking for is datetime.isoformat. The example in the page shows how to convert the datetime values to the ISO format with the time zone information.
To do this, you have to know the timezone (or the UTC offset) of the server date. What you have here is a "naive" date, without timezone info, you can't guess the UTC difference.
I think the datetime module is what you need here:
>>> from datetime import datetime
>>> datetime.now()
datetime.datetime(2011, 4, 27, 11, 8, 26, 149000)
>>> datetime.utcnow()
datetime.datetime(2011, 4, 27, 8, 8, 47, 712000)
For a difference between two dates:
>>> dtnow = datetime.now()
>>> dtutc = datetime.utcnow()
>>> dtnow - dtutc
datetime.timedelta(0, 10792, 847000)
Look up the datetime module and the relevant classes in Python's docs.
A very powerful extension of the datetime standard python library is the dateutil one, that allows you to easily:
set the delta of your time zone:
parse dates with various convenient options (in our case we will use the default option, which will allow us to set our time zone)
So 1st set time zone, and default date with this zone:
>>> from datetime import datetime
>>> from dateutil import parser
>>> from dateutil.tz import tzoffset
>>> tz_plus_5 = tzoffset(None, 5 * 60 * 60) # offset is in seconds !
>>> default = datetime.now(tz_plus_5)
Now use this default date in the parsing:
>>> Datetime = "2011-04-27 2:17:45"
>>> my_date = parser.parse(Datetime, default=default)
>>> my_date
datetime.datetime(2011, 4, 27, 2, 17, 45, tzinfo=tzoffset(None, 18000))
>>> my_date.strftime("%Y-%m-%d %H:%M:%S %z")
'2011-04-27 02:17:45 +0500'
For those that simply need to get the offset between local time and UTC, the time module has an attribute time.altzone that specifies the difference between UTC and local time in seconds:
The offset of the local DST timezone, in seconds west of UTC, if one is defined. This is negative if the local DST timezone is east of UTC (as in Western Europe, including the UK). Only use this if daylight is nonzero.
Here's an example of how it works:
>>> datetime.now().isoformat()
'2011-09-01T17:26:46.971000'
>>> datetime.utcnow().isoformat()
'2011-09-01T15:27:32.699000'
>>> time.altzone / (60*60)
-2
Doesn't get much cleaner than that.

Categories

Resources