UTC時間と経度を指定して、真夜中以降の現地時間(または現地の太陽時)を計算するPython関数/モジュールがあるかどうか疑問に思っていますか?夏時間を考慮する必要はありません。
前もって感謝します。
ephem
の方法を使用sidereal_time()
する:
import ephem # pip install pyephem (on Python 2)
# pip install ephem (on Python 3)
def solartime(observer, sun=ephem.Sun()):
sun.compute(observer)
# sidereal time == ra (right ascension) is the highest point (noon)
hour_angle = observer.sidereal_time() - sun.ra
return ephem.hours(hour_angle + ephem.hours('12:00')).norm # norm for 24h
注:ephem.hours
は、角度をラジアンで表し、文字列との間で「hh:mm:ss.ff」として変換される浮動小数点数です。
比較のために、「utc+経度」の式を次に示します。
import math
from datetime import timedelta
def ul_time(observer):
utc_dt = observer.date.datetime()
longitude = observer.long
return utc_dt + timedelta(hours=longitude / math.pi * 12)
from datetime import datetime
# "solar time" for some other cities
for name in ['Los Angeles', 'New York', 'London',
'Paris', 'Moscow', 'Beijing', 'Tokyo']:
city = ephem.city(name)
print("%-11s %11s %s" % (name, solartime(city),
ul_time(city).strftime('%T')))
# set date, longitude manually
o = ephem.Observer()
o.date = datetime(2012, 4, 15, 1, 0, 2) # some utc time
o.long = '00:00:00.0' # longitude (you could also use a float (radians) here)
print("%s %s" % (solartime(o), ul_time(o).strftime('%T')))
Los Angeles 14:59:34.11 14:44:30
New York 17:56:31.27 17:41:27
London 22:52:02.04 22:36:58
Paris 23:01:56.56 22:46:53
Moscow 1:23:00.33 01:07:57
Beijing 6:38:09.53 06:23:06
Tokyo 8:11:17.81 07:56:15
1:00:00.10 01:00:01
または、さらに短くしたい場合は、NOAAの低精度の方程式を使用できます。
#!/usr/local/bin/python
import sys
from datetime import datetime, time, timedelta
from math import pi, cos, sin
def solar_time(dt, longit):
return ha
def main():
if len(sys.argv) != 4:
print 'Usage: hour_angle.py [YYYY/MM/DD] [HH:MM:SS] [longitude]'
sys.exit()
else:
dt = datetime.strptime(sys.argv[1] + ' ' + sys.argv[2], '%Y/%m/%d %H:%M:%S')
longit = float(sys.argv[3])
gamma = 2 * pi / 365 * (dt.timetuple().tm_yday - 1 + float(dt.hour - 12) / 24)
eqtime = 229.18 * (0.000075 + 0.001868 * cos(gamma) - 0.032077 * sin(gamma) \
- 0.014615 * cos(2 * gamma) - 0.040849 * sin(2 * gamma))
decl = 0.006918 - 0.399912 * cos(gamma) + 0.070257 * sin(gamma) \
- 0.006758 * cos(2 * gamma) + 0.000907 * sin(2 * gamma) \
- 0.002697 * cos(3 * gamma) + 0.00148 * sin(3 * gamma)
time_offset = eqtime + 4 * longit
tst = dt.hour * 60 + dt.minute + dt.second / 60 + time_offset
solar_time = datetime.combine(dt.date(), time(0)) + timedelta(minutes=tst)
print solar_time
if __name__ == '__main__':
main()
ジャン・メーウスの天文アルゴリズムを見てみました。時間(0-24hr)、度(0-360)、またはラジアン(0-2pi)で表すことができるローカル時角を求めているのではないかと思います。
ephemでこれができると思います。しかし、それの一体のために、ここにいくつかのPythonがあります:
#!/usr/local/bin/python
import sys
from datetime import datetime, time, timedelta
from math import pi, sin, cos, atan2, asin
# helpful constant
DEG_TO_RAD = pi / 180
# hardcode difference between Dynamical Time and Universal Time
# delta_T = TD - UT
# This comes from IERS Bulletin A
# ftp://maia.usno.navy.mil/ser7/ser7.dat
DELTA = 35.0
def coords(yr, mon, day):
# @input year (int)
# @input month (int)
# @input day (float)
# @output right ascention, in radians (float)
# @output declination, in radians (float)
# get julian day (AA ch7)
day += DELTA / 60 / 60 / 24 # use dynamical time
if mon <= 2:
yr -= 1
mon += 12
a = yr / 100
b = 2 - a + a / 4
jd = int(365.25 * (yr + 4716)) + int(30.6 * (mon + 1)) + day + b - 1524.5
# get sidereal time at greenwich (AA ch12)
t = (jd - 2451545.0) / 36525
# Calculate mean equinox of date (degrees)
l = 280.46646 + 36000.76983 * t + 0.0003032 * t**2
while (l > 360):
l -= 360
while (l < 0):
l += 360
# Calculate mean anomoly of sun (degrees)
m = 357.52911 + 35999.05029 * t - 0.0001537 * t**2
# Calculate eccentricity of Earth's orbit
e = 0.016708634 - 0.000042037 * t - 0.0000001267 * t**2
# Calculate sun's equation of center (degrees)
c = (1.914602 - 0.004817 * t - .000014 * t**2) * sin(m * DEG_TO_RAD) \
+ (0.019993 - .000101 * t) * sin(2 * m * DEG_TO_RAD) \
+ 0.000289 * sin(3 * m * DEG_TO_RAD)
# Calculate the sun's radius vector (AU)
o = l + c # sun's true longitude (degrees)
v = m + c # sun's true anomoly (degrees)
r = (1.000001018 * (1 - e**2)) / (1 + e * cos(v * DEG_TO_RAD))
# Calculate right ascension & declination
seconds = 21.448 - t * (46.8150 + t * (0.00059 - t * 0.001813))
e0 = 23 + (26 + (seconds / 60)) / 60
ra = atan2(cos(e0 * DEG_TO_RAD) * sin(o * DEG_TO_RAD), cos(o * DEG_TO_RAD)) # (radians)
decl = asin(sin(e0 * DEG_TO_RAD) * sin(o * DEG_TO_RAD)) # (radians)
return ra, decl
def hour_angle(dt, longit):
# @input UTC time (datetime)
# @input longitude (float, negative west of Greenwich)
# @output hour angle, in degrees (float)
# get gregorian time including fractional day
y = dt.year
m = dt.month
d = dt.day + ((dt.second / 60.0 + dt.minute) / 60 + dt.hour) / 24.0
# get right ascention
ra, _ = coords(y, m, d)
# get julian day (AA ch7)
if m <= 2:
y -= 1
m += 12
a = y / 100
b = 2 - a + a / 4
jd = int(365.25 * (y + 4716)) + int(30.6 * (m + 1)) + d + b - 1524.5
# get sidereal time at greenwich (AA ch12)
t = (jd - 2451545.0) / 36525
theta = 280.46061837 + 360.98564736629 * (jd - 2451545) \
+ .000387933 * t**2 - t**3 / 38710000
# hour angle (AA ch13)
ha = (theta + longit - ra / DEG_TO_RAD) % 360
return ha
def main():
if len(sys.argv) != 4:
print 'Usage: hour_angle.py [YYYY/MM/DD] [HH:MM:SS] [longitude]'
sys.exit()
else:
dt = datetime.strptime(sys.argv[1] + ' ' + sys.argv[2], '%Y/%m/%d %H:%M:%S')
longit = float(sys.argv[3])
ha = hour_angle(dt, longit)
# convert hour angle to timedelta from noon
days = ha / 360
if days > 0.5:
days -= 0.5
td = timedelta(days=days)
# make solar time
solar_time = datetime.combine(dt.date(), time(12)) + td
print solar_time
if __name__ == '__main__':
main()
非常に単純な関数と非常に近似された現地時間の場合:時間変動は-12hから+ 12hになり、経度は-180から180になります。
import datetime as dt
def localTimeApprox(myDateTime, longitude):
"""Returns local hour approximation"""
return myDateTime+dt.timedelta(hours=(longitude*12/180))
呼び出し例:localTimeApprox(dt.datetime(2014, 7, 9, 20, 00, 00), -75)
戻り値:datetime.datetime(2014, 7, 9, 15, 0)
ephemで再試行します。引数として緯度と標高を含めましたが、もちろん必要ありません。0
あなたはあなたの目的のためにそれらを呼び出すことができます。
#!/usr/local/bin/python
import sys
from datetime import datetime, time, timedelta
import ephem
def hour_angle(dt, longit, latit, elev):
obs = ephem.Observer()
obs.date = dt.strftime('%Y/%m/%d %H:%M:%S')
obs.lon = longit
obs.lat = latit
obs.elevation = elev
sun = ephem.Sun()
sun.compute(obs)
# get right ascention
ra = ephem.degrees(sun.g_ra) - 2 * ephem.pi
# get sidereal time at greenwich (AA ch12)
jd = ephem.julian_date(dt)
t = (jd - 2451545.0) / 36525
theta = 280.46061837 + 360.98564736629 * (jd - 2451545) \
+ .000387933 * t**2 - t**3 / 38710000
# hour angle (AA ch13)
ha = (theta + longit - ra * 180 / ephem.pi) % 360
return ha
def main():
if len(sys.argv) != 6:
print 'Usage: hour_angle.py [YYYY/MM/DD] [HH:MM:SS] [longitude] [latitude] [elev]'
sys.exit()
else:
dt = datetime.strptime(sys.argv[1] + ' ' + sys.argv[2], '%Y/%m/%d %H:%M:%S')
longit = float(sys.argv[3])
latit = float(sys.argv[4])
elev = float(sys.argv[5])
# get hour angle
ha = hour_angle(dt, longit, latit, elev)
# convert hour angle to timedelta from noon
days = ha / 360
if days > 0.5:
days -= 0.5
td = timedelta(days=days)
# make solar time
solar_time = datetime.combine(dt.date(), time(12)) + td
print solar_time
if __name__ == '__main__':
main()