In my Django project, I have a form (forms.py) which implements pytz to get current timezone like this:
tz = timezone.get_current_timezone()
and I have passed this value to a form field as an initial value like this:
timezone = forms.CharField(label='Time Zone', initial=tznow)
which gives the field a default value of current Timezone, in my case, it happens to be Asia/Calcutta.
Now i want to find the UTC Offset value for the given Timezone, which in this case Asia/Calcutta is +5:30
I tried tzinfo() method as well, but i couldn't find the expected result. Can somebody guide me through this?
The UTC offset is given as a timedelta by the utcoffset method of any implementation of tzinfo such as pytz. For example:
import pytz
import datetime
tz = pytz.timezone('Asia/Calcutta')
dt = datetime.datetime.utcnow()
offset_seconds = tz.utcoffset(dt).total_seconds()
offset_hours = offset_seconds / 3600.0
print "{:+d}:{:02d}".format(int(offset_hours), int((offset_hours % 1) * 60))
# +5:30
A single timezone such as Asia/Calcutta may have different utc offsets at different dates. You can enumerate the utc offsets known so far using pytz's _tzinfos in this case:
>>> offsets = {off for off, dst, abbr in pytz.timezone('Asia/Calcutta')._tzinfos}
>>> for utc_offset in offsets:
... print(utc_offset)
...
5:30:00
6:30:00
5:53:00
To get the current utc offset for a given timezone:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
utc_offset = datetime.now(pytz.timezone('Asia/Calcutta')).utcoffset()
print(utc_offset)
# -> 5:30:00
In case you just want the normalized hour offset:
def curr_calcutta_offset():
tz_calcutta = pytz.timezone('Asia/Calcutta')
offset = tz_calcutta.utcoffset(datetime.utcnow())
offset_seconds = (offset.days * 86400) + offset.seconds
offset_hours = offset_seconds / 3600
return offset_hours
curr_calcutta_offset()
# 5.5
Related
I'm getting a dataset with UTC data, and coordinates lat,long
I want to compute the solarposition for each of the row of this dateset, but I'm having trouble with manipulating the timezone.
So far,
I've managed to make the UTC data, timezone aware by:
# library for timezone computations
from timezonefinder import TimezoneFinder
from pytz import timezone
import pytz
# scientific python add-ons
import numpy as np
import pandas as pd
tf = TimezoneFinder()
litteralTimeZone = tf.timezone_at(lng=longitude, lat=latitude)
print(litteralTimeZone)
tz = pytz.timezone(litteralTimeZone)
# Adjust date Time, currently in CSV like: 20070101:0000
Data['time(LOC)'] = pd.DatetimeIndex(
pd.to_datetime(Data['time(UTC)'], format='%Y%m%d:%H%M')
).tz_localize(tz, ambiguous=True, nonexistent='shift_forward')
Data = Data.set_index('time(LOC)')
now, when I pass the data to the get solar position function with
pvlib.solarposition.get_solarposition(
data.index, metadata['latitude'],metadata['longitude'])
The get_solarposition are computed on the UTC portion of the data, ignoring the localized part of it.
Any thoughts?
Thanks for using pvlib!
I believe your issue is that you have UTC timestamps, but you are mixing them with the local timezone. UTC is a timezone. Therefore, you should first localize the naive timestamps with 'UTC'.
# make time-zone aware timestamps from string format in UTC
>>> Data['time(TZ-UTC)'] = pd.DatetimeIndex(
... pd.to_datetime(Data['time(UTC)'], format='%Y%m%d:%H%M')).tz_localize('UTC')
Then you can use these directly in pvlib.solarposition.get_solarposition.
# mimic OP data
>>> Data = pd.DataFrame(
... {'time(UTC)': ['20200420:2030', '20200420:2130', '20200420:2230']})
>>> Data
# time(UTC)
# 0 20200420:2030
# 1 20200420:2130
# 2 20200420:2230
# apply the UTC timezone to the naive timestamps after parsing the string format
>>> Data['time(TZ-UTC)'] = pd.DatetimeIndex(
... pd.to_datetime(Data['time(UTC)'], format='%Y%m%d:%H%M')).tz_localize('UTC')
>>> Data
# time(UTC) time(TZ-UTC)
# 0 20200420:2030 2020-04-20 20:30:00+00:00
# 1 20200420:2130 2020-04-20 21:30:00+00:00
# 2 20200420:2230 2020-04-20 22:30:00+00:00
# now call pvlib.solarposition.get_solarposition with the TZ-aware timestamps
>>> lat, lon = 39.74,-105.24
>>> solarposition.get_solarposition(Data['time(TZ-UTC)'], latitude=lat, longitude=lon)
# apparent_zenith zenith apparent_elevation elevation azimuth equation_of_time
# time(TZ-UTC)
# 2020-04-20 20:30:00+00:00 34.242212 34.253671 55.757788 55.746329 221.860950 1.249402
# 2020-04-20 21:30:00+00:00 43.246151 43.261978 46.753849 46.738022 240.532481 1.257766
# 2020-04-20 22:30:00+00:00 53.872320 53.895328 36.127680 36.104672 254.103959 1.266117
You don't need to convert them to the local timezone. If desired, use pd.DatetimeIndex.tz_convert to convert them from UTC to the local (eg: Golden, CO) timezone. Note: it may be more convenient to use a fixed offset like Etc/GMT+7 because daylight savings time may cause Pandas to raise an ambiguous time error.
>>> Data['time(LOC)'] = pd.DatetimeIndex(Data['time(TZ-UTC)']).tz_convert('Etc/GMT+7')
>>> Data = Data.set_index('time(LOC)')
>>> Data
# time(UTC) time(TZ-UTC)
# time(LOC)
# 2020-04-20 13:30:00-07:00 20200420:2030 2020-04-20 20:30:00+00:00
# 2020-04-20 14:30:00-07:00 20200420:2130 2020-04-20 21:30:00+00:00
# 2020-04-20 15:30:00-07:00 20200420:2230 2020-04-20 22:30:00+00:00
The solar position results should be exactly the same with either local (eg: Golden, CO) time or UTC time:
>>> solarposition.get_solarposition(Data.index, latitude=lat, longitude=lon)
# apparent_zenith zenith apparent_elevation elevation azimuth equation_of_time
# time(LOC)
# 2020-04-20 13:30:00-07:00 34.242212 34.253671 55.757788 55.746329 221.860950 1.249402
# 2020-04-20 14:30:00-07:00 43.246151 43.261978 46.753849 46.738022 240.532481 1.257766
# 2020-04-20 15:30:00-07:00 53.872320 53.895328 36.127680 36.104672 254.103959 1.266117
Does this help? Happy to answer more questions! Cheers!
This question already has answers here:
Apply timezone offset to datetime in Python
(3 answers)
Closed 4 years ago.
from dateutil.parser import parse
from dateutil.relativedelta import relativedelta
from dateutil.tz import gettz
from datetime import datetime, timedelta
input_time = '2019-02-01 09:50:08+11:00'
parsed=parse(input_time)
print parsed.tzinfo
I have a time input string:
input_time = '2019-02-01 09:50:08+11:00'
I want to convert it into this format: YYYY-MM-DD HH:MM:SS. Basically, adding the offset to the actual time object. For the above example I am looking for below output:
input_time_converted = '2019-02-01 20:50:08'
Found some useful stuff in dateutil library to parse the date object passed as a string and get the offset details but it gives me this output:
tzoffset(None, 39600)
But I don't know how to get the actual digits from the above and do the rest of the maths.
I have tried to call it with -as explained in the official dateutil parser documentation-
print parsed.tzinfo.tzoffset
But didn't work.
#!/usr/bin/env python2
def process_messed_up_timestamp(ts):
"""Convert messed up timestamps to something else.
Input timestamp is in UTC format with the offset that
should be applied but hasn't been.
"""
from datetime import datetime, timedelta
timestamp, plus, offset = ts[:19], ts[19], ts[20:]
# should validate plus is '+' or '-'
fmt = '%Y-%m-%d %H:%M:%S'
base = datetime.strptime(timestamp, fmt)
hours, minutes = [int(n) for n in offset.split(':')]
delta = timedelta(hours=hours, minutes=minutes)
multiplier = -1 if plus == '-' else 1
return (base + multiplier * delta).strftime(fmt)
input_time = '2019-02-01 09:50:08+11:00'
input_time_converted = '2019-02-01 20:50:08'
assert process_messed_up_timestamp(input_time) == input_time_converted
I'm trying to do some time math, but I'm not sure how I could do this. I'd like to subtract a specific date & time I have in a string (e.g.: 15:54:00 2017-5-20) from current GMT time (e.g: 20:06:27 2017-12-22).
Any thoughts on how I could do this?
# import data into Python
with open(output_file2) as f:
reader = csv.reader(f, delimiter="\t")
d = list(reader)
# here, objects [0][4] and [0][5] would be, for instance: 15:54:00 and 2017-5-20
# , respectively
# UTC Time
os.system("date -u \"+%H:%M:%S %Y-%m-%d\" | gawk '{print \" UTC Date & Time: \", $1, \"\", $2}'")
# eg.: 20:06:27 2017-12-22
Any thoughts would be great! Thanks =)
Update: I've tried so far:
UTC_time = datetime.datetime.utcnow().strftime("%H:%M:%S %Y-%m-%d")
print ' UTC Date & Time: ', UTC_time
time1 = d[0][4]
date1 = d[0][5]
mytime = time1, date1
time_difference = datetime.datetime.utcnow() - mytime
print "HELLO", time_difference
but I keep getting an error:
TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'tuple'
Not sure what I am doing wrong...
Your mytime variable is not a datetime.datetime object and cannot be used to operate against one. Instead of mytime = time1, date1 you are looking for something more along the lines of
my_date_str = "{} {}".format(time1, date1)
mytime = datetime.datetime.strptime(my_date_str, "%H:%M:%S %Y-%m-%d")
Do realize that in spite of using utcnow() the resulting datetime.datetime object is NOT timezone aware, and neither is mytime. So any math between the two is pure clock math, no timezones taken into account.
If you require timezone support, look into pytz or Pendulum or perhaps find another if they don't suit you.
I am trying to convert local date time to UTC format but I am unable to convert Please let me know how to get required output using following input
Input : 2008-09-17 10:45:00 PM
Output : 2008-09-17 17:15:00 PM
required output: 1715UTC
from datetime import *
from dateutil import *
from dateutil.tz import tz
utc_zone = tz.gettz('UTC')
local_zone = tz.gettz('Asia/kolkata')
utc_zone = tz.tzutc()
local_zone = tz.tzlocal()
# Convert time string to datetime
local_time = datetime.strptime("2008-09-17 10:45:00 PM", '%Y-%m-%d %I:%M:%S %p')
local_time = local_time.replace(tzinfo=local_zone)
utc_time = local_time.astimezone(utc_zone)
utc_string = utc_time.strftime('%Y-%m-%d %H:%M:%S %p')
print utc_string
See this:
How do I convert local time to UTC in Python?
It shows how to format the time as per your requirements.
How would I convert the result from strptime into an integer value or a value that can be used by date.date()?
convertTOdate = time.strptime('2007-07-18 10:03:19', '%Y-%m-%d %H:%M:%S')
duedate = datetime.datetime(convertTOdate)
A Solution on stackoverflow was to do:
Use time.mktime() to convert the time tuple (in localtime) into seconds since the Epoch, then use datetime.fromtimestamp() to get the datetime object.
from time import mktime
from datetime import datetime
dt = datetime.fromtimestamp(mktime(struct))
I do not want to get the local time as it would not work with my function
I am using Python 2
Thank you
You can use the following approach.
from datetime import datetime
def time_in_seconds(dt):
epoch = datetime.utcfromtimestamp(0)
delta = dt - epoch
return delta.total_seconds()
convertTOdate = datetime.strptime('2007-07-18 10:03:19', '%Y-%m-%d %H:%M:%S')
duedate = time_in_seconds(convertTOdate)
returns 1184752999.0 which is equivalent to 2007-07-18 10:03:19
duedate = datetime.utcfromtimestamp(duedate)
print duedate
Just remember before using the following two:
fromtimestamp give you the date and time in local time and utcfromtimestamp gives you the date and time in UTC.