我目前正在构造一个带有输入(位置,时间("城市,州,国家"和"年-月-日小时:分钟:秒"的函数,输出恒星时间可用于天文计算。目前,我正在通过geopy传递位置以查找经度/纬度,然后使用时区查找器查找确切的时区。
从那里我使用 pytz 将我的本地时间转换为 UTC,同时考虑到 DST。我有一个内置的数据库,我可以在其中使用转换的时间和日期找到恒星时间。
我的问题是要准确,我不能使用本地时间,我需要使用当地平均时间,这是根据与时区子午线的距离调整的本地时间。例如,如果你的城市的经度是-80,并且在美国/New_York(东部时间(,那么实际与太阳对齐的子午线是-75经度,这意味着你实际上比东部时间早20分钟相对于太阳。但是由于夏令时以及时区在地图上并未真正被视为统一段的事实,我找不到计算这种差异的可靠方法。
我能想到的最好的方法是将我的位置转换为长/纬度。 找到该位置的时区,然后以某种方式将该时区隐藏到子午线中。
我将为其他更好地处理视觉效果的人发布我的代码。
from timezonefinder import TimezoneFinder
import geopy.geocoders, pytz, certifi, ssl, datetime, ephem, math
def position(city, state, country):
"""
:param city: String of city Ex. Chattannoga
:param state: String of state Ex. TN
:param country: String USA
:return: latitude and longitude
"""
ctx = ssl.create_default_context(cafile=certifi.where())
geopy.geocoders.options.default_ssl_context = ctx
geo_locator = geopy.geocoders.Nominatim(user_agent="my-application", scheme='http')
location = geo_locator.geocode(city + ' ' + state + ' ' + country)
return location.longitude, location.latitude
def timezone(longitude, latitude):
"""
:param longitude:
:param latitude:
:return: timezone
"""
tf = TimezoneFinder()
zone = (tf.certain_timezone_at(lng=longitude, lat=latitude))
return zone
# def localmeantime(longitude):
# zones = [-0, -15, -30, -45, -60, -75, -90, -105, -120, -135, -150, -165, -180]
# x = min(zones, key=lambda x: abs(x - longitude))
# print(x)
def localtoutc(time, timezo):
"""
:param time: Ex. "2001-2-3 10:11:12" String
:param timezo: Ex. America/New_York String
:return:
"""
local = pytz.timezone(timezo)
naive = datetime.datetime.strptime(time, "%Y-%m-%d %H:%M:%S")
local_dt = local.localize(naive, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)
return utc_dt
我能想到的另一种方法是找出该位置是否在夏令时中,然后通过计算经过的小时数来找出子午线。 每小时 15 度。
我想知道是否有更好的方法来获取本地平均时间,或者是否有一种方法可以通过所有这些调整更轻松地获得恒星时间。
万一有人偶然发现这一点,我通过采用上面的通用时间并减去经度 x 4 分钟来找到当地平均时间来解决我的问题。
def localmeantime(utc, longitude):
"""
:param utc: string Ex. '2008-12-2'
:param longitude: longitude
:return: Local Mean Time Timestamp
"""
lmt = utc + datetime.timedelta(seconds=round(4*60*longitude))
lmt = lmt.replace(tzinfo=None)
return lmt