Get new datetime object according to timezone difference - python

Here is my code
>>>from datetime import datetime
>>>from dateutil import tz
>>>current_time = datetime.utcnow().replace(tzinfo=tz.gettz('Asia/Calcutta'))
>>>2013-05-12 17:11:36.362000+05:30
i don't want offset-aware i want to add time difference to my current time
so the time will be
>>>2013-05-12 22:41:36.362000
so that i will be able to get time difference from by simply.
>>> datetime.utcnow() - current_time
Thanks,

You can obtain the offset with as a datetime.timedelta using:
offset = current_time.utcoffset()
The offset can then be added or subtracted from the current_time to obtain the desired datetime.
import datetime as DT
import dateutil.tz as tz
import dateutil
current_time = DT.datetime.utcnow().replace(tzinfo=tz.gettz('Asia/Calcutta'))
print(current_time)
# 2013-05-12 18:33:19.368122+05:30
offset = current_time.utcoffset()
naive_time = current_time.replace(tzinfo=None)
print(naive_time)
# 2013-05-12 18:33:19.368122
print(naive_time + offset)
# 2013-05-13 00:03:19.368122
Note that if you want the UTC time, you should subtract the offset:
print(naive_time - offset)
# 2013-05-12 13:03:19.368122
A simpler way to get the UTC datetime would be to use the astimezone method however:
utc = dateutil.tz.tzutc()
print(current_time.astimezone(utc))
# 2013-05-12 13:03:19.368122+00:00
Finally, note that using dateutil and replace to set the timezone does not always return the correct time. Here is how you could do it with pytz:
import pytz
calcutta = pytz.timezone('Asia/Calcutta')
utc = pytz.utc
current_time = calcutta.localize(DT.datetime.utcnow())
print(current_time)
# 2013-05-12 18:33:19.368705+05:30
print(current_time.astimezone(utc))
# 2013-05-12 13:03:19.368705+00:00

You can get the offset by using datetime.utcoffset()
current_time = datetime.utcnow().replace(tzinfo=tz.gettz('Asia/Calcutta'))
td = datetime.utcoffset(current_time)
#datetime.timedelta(0, 19800)
td.total_seconds() / 3600
#5.5

Related

How can I convert from UTC time to local time in python?

So, I want to convert UTC date time 2021-08-05 10:03:24.585Z to Indian date time how to convert it?
What I tried is
from datetime import datetime
from pytz import timezone
st = "2021-08-05 10:03:24.585Z"
datetime_object = datetime.strptime(st, '%Y-%m-%d %H:%M:%S.%fZ')
local_tz = timezone('Asia/Kolkata')
start_date = local_tz.localize(datetime_object)
print(start_date.replace(tzinfo=local_tz))
But Still the output is not with the timezone I have mentioned how can I convert the time and print the time from the time.
Output:
2021-08-05 10:03:24.585000+05:21
You can use sth like this:
from datetime import datetime
from dateutil import tz
from_zone = tz.gettz('UTC')
to_zone = tz.gettz('Asia/Kolkata')
utc = datetime.strptime('2011-01-21 02:37:21', '%Y-%m-%d %H:%M:%S')
utc = utc.replace(tzinfo=from_zone)
central = utc.astimezone(to_zone)
parse the date/time string to UTC datetime correctly and use astimezone instead of replace to convert to a certain time zone (option for newer Python version (3.9+) in comments):
from datetime import datetime
# from zoneinfo import ZoneInfo
from dateutil.tz import gettz
st = "2021-08-05 10:03:24.585Z"
zone = "Asia/Kolkata"
# dtUTC = datetime.fromisoformat(st.replace('Z', '+00:00'))
dtUTC = datetime.strptime(st, '%Y-%m-%d %H:%M:%S.%f%z')
# dtZone = dtUTC.astimezone(ZoneInfo(zone))
dtZone = dtUTC.astimezone(gettz(zone))
print(dtZone.isoformat(timespec='seconds'))
# 2021-08-05T15:33:24+05:30
If you just need local time, i.e. your machine's setting, you can use astimezone(None) as well.
In Python 3.10.8
from datetime import datetime
st = "2021-08-05 10:03:24.585Z"
dtUTC = datetime.fromisoformat(st[:-1]+'+00:00')
dtUTC = dtUTC.astimezone()
print(dtUTC.isoformat(timespec='seconds'))
# 2021-08-05T15:33:24+05:30

Python get local timezone offset in hours [duplicate]

In Python, how do you find what UTC time offset the computer is set to?
time.timezone:
import time
print -time.timezone
It prints UTC offset in seconds (to take into account Daylight Saving Time (DST) see time.altzone:
is_dst = time.daylight and time.localtime().tm_isdst > 0
utc_offset = - (time.altzone if is_dst else time.timezone)
where utc offset is defined via: "To get local time, add utc offset to utc time."
In Python 3.3+ there is tm_gmtoff attribute if underlying C library supports it:
utc_offset = time.localtime().tm_gmtoff
Note: time.daylight may give a wrong result in some edge cases.
tm_gmtoff is used automatically by datetime if it is available on Python 3.3+:
from datetime import datetime, timedelta, timezone
d = datetime.now(timezone.utc).astimezone()
utc_offset = d.utcoffset() // timedelta(seconds=1)
To get the current UTC offset in a way that workarounds the time.daylight issue and that works even if tm_gmtoff is not available, #jts's suggestion to substruct the local and UTC time can be used:
import time
from datetime import datetime
ts = time.time()
utc_offset = (datetime.fromtimestamp(ts) -
datetime.utcfromtimestamp(ts)).total_seconds()
To get UTC offset for past/future dates, pytz timezones could be used:
from datetime import datetime
from tzlocal import get_localzone # $ pip install tzlocal
tz = get_localzone() # local timezone
d = datetime.now(tz) # or some other local date
utc_offset = d.utcoffset().total_seconds()
It works during DST transitions, it works for past/future dates even if the local timezone had different UTC offset at the time e.g., Europe/Moscow timezone in 2010-2015 period.
gmtime() will return the UTC time and localtime() will return the local time so subtracting the two should give you the utc offset.
From https://pubs.opengroup.org/onlinepubs/009695399/functions/gmtime.html
The gmtime() function shall convert the time in seconds since the Epoch pointed to by timer into a broken-down time, expressed as Coordinated Universal Time (UTC).
So, despite the name gmttime, the function returns UTC.
I like:
>>> strftime('%z')
'-0700'
I tried JTS' answer first, but it gave me the wrong result. I'm in -0700 now, but it was saying I was in -0800. But I had to do some conversion before I could get something I could subtract, so maybe the answer was more incomplete than incorrect.
the time module has a timezone offset, given as an integer in "seconds west of UTC"
import time
time.timezone
You can use the datetime and dateutil libraries to get the offset as a timedelta object:
>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>>
>>> # From a datetime object
>>> current_time = datetime.now(tzlocal())
>>> current_time.utcoffset()
datetime.timedelta(seconds=7200)
>>> current_time.dst()
datetime.timedelta(seconds=3600)
>>>
>>> # From a tzlocal object
>>> time_zone = tzlocal()
>>> time_zone.utcoffset(datetime.now())
datetime.timedelta(seconds=7200)
>>> time_zone.dst(datetime.now())
datetime.timedelta(seconds=3600)
>>>
>>> print('Your UTC offset is {:+g}'.format(current_time.utcoffset().total_seconds()/3600))
Your UTC offset is +2
hours_delta = (time.mktime(time.localtime()) - time.mktime(time.gmtime())) / 60 / 60
Create a Unix Timestamp with UTC Corrected Timezone
This simple function will make it easy for you to get the current time from a MySQL/PostgreSQL database date object.
def timestamp(date='2018-05-01'):
return int(time.mktime(
datetime.datetime.strptime( date, "%Y-%m-%d" ).timetuple()
)) + int(time.strftime('%z')) * 6 * 6
Example Output
>>> timestamp('2018-05-01')
1525132800
>>> timestamp('2018-06-01')
1527811200
Here is some python3 code with just datetime and time as imports. HTH
>>> from datetime import datetime
>>> import time
>>> def date2iso(thedate):
... strdate = thedate.strftime("%Y-%m-%dT%H:%M:%S")
... minute = (time.localtime().tm_gmtoff / 60) % 60
... hour = ((time.localtime().tm_gmtoff / 60) - minute) / 60
... utcoffset = "%.2d%.2d" %(hour, minute)
... if utcoffset[0] != '-':
... utcoffset = '+' + utcoffset
... return strdate + utcoffset
...
>>> date2iso(datetime.fromtimestamp(time.time()))
'2015-04-06T23:56:30-0400'
This works for me:
if time.daylight > 0:
return time.altzone
else:
return time.timezone

How to round a datetime up to a specific time?

Given a datetime object, how do I round it up to the next occurrence of 8AM PST?
If the result is a timezone-aware datetime object in a timezone with a non-fixed UTC offset then you can't just call .replace() or .combine() -- it may create a datetime with a wrong UTC offset. The issue is similar to How do I get the UTC time of "midnight" for a given timezone? (00:00 is used instead of 08:00).
Assuming 8AM always exists and unambiguous in PST:
from datetime import datetime, time as datetime_time, timedelta
import pytz # $ pip install pytz
def next_8am_in_pst(aware_dt, tz=pytz.timezone('America/Los_Angeles')):
pst_aware_dt = tz.normalize(aware_dt.astimezone(tz)) # convert to PST
naive_dt = round_up_to_8am(pst_aware_dt.replace(tzinfo=None))
return tz.localize(naive_dt, is_dst=None)
def round_up_to_8am(dt):
rounded = datetime.combine(dt, datetime_time(8))
return rounded + timedelta(rounded < dt)
Example:
>>> str(next_8am_in_pst(datetime.now(pytz.utc)))
'2016-02-25 08:00:00-08:00'
Just test whether the time is before or after 8, then add a day if it's after and construct a new datetime.
import datetime
def round_datetime(dt):
t = datetime.time(8)
# If time is after 8am, add a day.
if dt.time() > datetime.time(8):
dt += datetime.timedelta(days=1)
return datetime.datetime.combine(dt, t)
I made an answer based on some ideas from the comments:
def nextDay(d):
pstTime = d.astimezone(pytz.timezone('US/Pacific'))
pstTime = pstTime.replace(hour=8, minute=0, second=0, microsecond=0)
if pstTime < d:
pstTime += datetime.timedelta(days=1)
return pstTime

How to add hours to current time in python

I am able to get the current time as below:
from datetime import datetime
str(datetime.now())[11:19]
Result
'19:43:20'
Now, I am trying to add 9 hours to the above time, how can I add hours to current time in Python?
from datetime import datetime, timedelta
nine_hours_from_now = datetime.now() + timedelta(hours=9)
#datetime.datetime(2012, 12, 3, 23, 24, 31, 774118)
And then use string formatting to get the relevant pieces:
>>> '{:%H:%M:%S}'.format(nine_hours_from_now)
'23:24:31'
If you're only formatting the datetime then you can use:
>>> format(nine_hours_from_now, '%H:%M:%S')
'23:24:31'
Or, as #eumiro has pointed out in comments - strftime
Import datetime and timedelta:
>>> from datetime import datetime, timedelta
>>> str(datetime.now() + timedelta(hours=9))[11:19]
'01:41:44'
But the better way is:
>>> (datetime.now() + timedelta(hours=9)).strftime('%H:%M:%S')
'01:42:05'
You can refer strptime and strftime behavior to better understand how python processes dates and time field
This works for me working with seconds not hours and also using a function to convert back to UTC time.
from datetime import timezone, datetime, timedelta
import datetime
def utc_converter(dt):
dt = datetime.datetime.now(timezone.utc)
utc_time = dt.replace(tzinfo=timezone.utc)
utc_timestamp = utc_time.timestamp()
return utc_timestamp
# create start and end timestamps
_now = datetime.datetime.now()
str_start = str(utc_converter(_now))
_end = _now + timedelta(seconds=10)
str_end = str(utc_converter(_end))
This is an answer which is significant for nowadays (python 3.9 or later).
Use strptime to create a datetime object from the timestring. Add 9 hours with timedelta, and match the time format with the timestring you have.
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
time_format = "%H:%M:%S"
timestring = datetime.strptime(str(datetime.now() + timedelta(hours=9))[11:19], time_format)
#You can then apply custom time formatting as well as a timezone.
TIMEZONE = [Add a timezone] #https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
custom_time_format = "%H:%M"
time_modification = datetime.fromtimestamp(timestring.timestamp(), ZoneInfo(TIMEZONE)).__format__(custom_time_format)
While I think it's more meaningful to apply a timezone, you don't necessarily need to, so you can also simply do that:
time_format = "%H:%M:%S"
timestring = datetime.strptime(str(datetime.now() + timedelta(hours=9))[11:19], time_format)
time_modification = datetime.fromtimestamp(timestring.timestamp())
datetime
https://docs.python.org/3/library/datetime.html
strftime-and-strptime-format-codes
https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes
timedelta
https://docs.python.org/3/library/datetime.html#datetime.timedelta
zoneinfo
https://docs.python.org/3/library/zoneinfo.html#module-zoneinfo

Getting computer's UTC offset in Python

In Python, how do you find what UTC time offset the computer is set to?
time.timezone:
import time
print -time.timezone
It prints UTC offset in seconds (to take into account Daylight Saving Time (DST) see time.altzone:
is_dst = time.daylight and time.localtime().tm_isdst > 0
utc_offset = - (time.altzone if is_dst else time.timezone)
where utc offset is defined via: "To get local time, add utc offset to utc time."
In Python 3.3+ there is tm_gmtoff attribute if underlying C library supports it:
utc_offset = time.localtime().tm_gmtoff
Note: time.daylight may give a wrong result in some edge cases.
tm_gmtoff is used automatically by datetime if it is available on Python 3.3+:
from datetime import datetime, timedelta, timezone
d = datetime.now(timezone.utc).astimezone()
utc_offset = d.utcoffset() // timedelta(seconds=1)
To get the current UTC offset in a way that workarounds the time.daylight issue and that works even if tm_gmtoff is not available, #jts's suggestion to substruct the local and UTC time can be used:
import time
from datetime import datetime
ts = time.time()
utc_offset = (datetime.fromtimestamp(ts) -
datetime.utcfromtimestamp(ts)).total_seconds()
To get UTC offset for past/future dates, pytz timezones could be used:
from datetime import datetime
from tzlocal import get_localzone # $ pip install tzlocal
tz = get_localzone() # local timezone
d = datetime.now(tz) # or some other local date
utc_offset = d.utcoffset().total_seconds()
It works during DST transitions, it works for past/future dates even if the local timezone had different UTC offset at the time e.g., Europe/Moscow timezone in 2010-2015 period.
gmtime() will return the UTC time and localtime() will return the local time so subtracting the two should give you the utc offset.
From https://pubs.opengroup.org/onlinepubs/009695399/functions/gmtime.html
The gmtime() function shall convert the time in seconds since the Epoch pointed to by timer into a broken-down time, expressed as Coordinated Universal Time (UTC).
So, despite the name gmttime, the function returns UTC.
I like:
>>> strftime('%z')
'-0700'
I tried JTS' answer first, but it gave me the wrong result. I'm in -0700 now, but it was saying I was in -0800. But I had to do some conversion before I could get something I could subtract, so maybe the answer was more incomplete than incorrect.
the time module has a timezone offset, given as an integer in "seconds west of UTC"
import time
time.timezone
You can use the datetime and dateutil libraries to get the offset as a timedelta object:
>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>>
>>> # From a datetime object
>>> current_time = datetime.now(tzlocal())
>>> current_time.utcoffset()
datetime.timedelta(seconds=7200)
>>> current_time.dst()
datetime.timedelta(seconds=3600)
>>>
>>> # From a tzlocal object
>>> time_zone = tzlocal()
>>> time_zone.utcoffset(datetime.now())
datetime.timedelta(seconds=7200)
>>> time_zone.dst(datetime.now())
datetime.timedelta(seconds=3600)
>>>
>>> print('Your UTC offset is {:+g}'.format(current_time.utcoffset().total_seconds()/3600))
Your UTC offset is +2
hours_delta = (time.mktime(time.localtime()) - time.mktime(time.gmtime())) / 60 / 60
Create a Unix Timestamp with UTC Corrected Timezone
This simple function will make it easy for you to get the current time from a MySQL/PostgreSQL database date object.
def timestamp(date='2018-05-01'):
return int(time.mktime(
datetime.datetime.strptime( date, "%Y-%m-%d" ).timetuple()
)) + int(time.strftime('%z')) * 6 * 6
Example Output
>>> timestamp('2018-05-01')
1525132800
>>> timestamp('2018-06-01')
1527811200
Here is some python3 code with just datetime and time as imports. HTH
>>> from datetime import datetime
>>> import time
>>> def date2iso(thedate):
... strdate = thedate.strftime("%Y-%m-%dT%H:%M:%S")
... minute = (time.localtime().tm_gmtoff / 60) % 60
... hour = ((time.localtime().tm_gmtoff / 60) - minute) / 60
... utcoffset = "%.2d%.2d" %(hour, minute)
... if utcoffset[0] != '-':
... utcoffset = '+' + utcoffset
... return strdate + utcoffset
...
>>> date2iso(datetime.fromtimestamp(time.time()))
'2015-04-06T23:56:30-0400'
This works for me:
if time.daylight > 0:
return time.altzone
else:
return time.timezone

Categories