00001 ## 00002 # 00003 # Script to print moon phase times for a given year, which should be the 00004 # single parameter passed on the command line. The times will be converted 00005 # to your local time by the ut_offset value, which gets added to the 00006 # calculated universal time for the phase. You'll want to modify the 00007 # ConvertToLocalTime() function to make its output appropriate for your 00008 # location. You can also make it do nothing, which results in the 00009 # program printing its times in UT. 00010 # 00011 # Converted to python from moon.c program from June 1995. Algorithms 00012 # from Meeus, Astronomical Formulas for Calculators, 2nd ed., 1982. 00013 # 00014 # Copyright (C) 2002 GDS Software 00015 # 00016 # This program is free software; you can redistribute it and/or 00017 # modify it under the terms of the GNU General Public License as 00018 # published by the Free Software Foundation; either version 2 of 00019 # the License, or (at your option) any later version. 00020 # 00021 # This program is distributed in the hope that it will be useful, 00022 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00024 # GNU General Public License for more details. 00025 # 00026 # You should have received a copy of the GNU General Public 00027 # License along with this program; if not, write to the Free 00028 # Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 00029 # MA 02111-1307 USA 00030 # 00031 # See http://www.gnu.org/licenses/licenses.html for more details. 00032 # 00033 00034 ######################################################################### 00035 00036 from math import pi, sin, cos, floor 00037 import sys 00038 import pdb 00039 xx = pdb.set_trace 00040 00041 NEW = 0 00042 FIRST = 1 00043 FULL = 2 00044 LAST = 3 00045 RAD = pi/180.0 # Converts degrees to radians 00046 desired_year = 0 00047 00048 # GetJulianFromPhase Derive the julian day number corresponding to the 00049 # number k. k is the integer corresponding to new moon and phase is 0 00050 # for new, 1 for first quarter, 2 for full, and 3 for last quarter. 00051 # Returns a float. From Meeus, pg 159. 00052 00053 def GetJulianFromPhase(k, phase): 00054 if phase != NEW and phase != FIRST and phase != FULL and phase != LAST: 00055 raise "Illegal phase value" 00056 k1 = k + phase/4.0 00057 T = k1/1236.85 00058 T2 = T*T 00059 T3 = T2*T 00060 # Get time of mean phase 00061 julian = 2415020.75933 + 29.53058868*k1 + 1.178e-4*T2 - 1.55e-7*T3 +3.3e-4*sin(RAD*(166.56 + 132.87*T - 0.009173*T2)) 00062 # Compute the corrections to get the time of true phase 00063 M = 359.2242 + 29.10535608*k - 3.33e-5*T2 - 3.47e-6*T3 00064 Mprime = 306.0253 + 385.81691806*k + 0.0107306*T2 + 1.236e-5*T3 00065 F = 21.2964 + 390.67050646*k - 1.6528e-3*T2 - 2.39e-6*T3 00066 # Adjust these values to the interval [0, 360] 00067 M = M - 360.0*(floor(M/360.0)) 00068 Mprime = Mprime - 360.0*(floor(Mprime/360.0)) 00069 F = F - 360.0*(floor(F/360.0)) 00070 # Convert them to radians 00071 M = M*RAD 00072 Mprime = Mprime*RAD 00073 F = F*RAD 00074 # Perform the corrections 00075 if phase == NEW or phase == FULL: 00076 correction = (0.1734 - 3.93e-4*T)*sin(M) + 0.0021*sin(2*M) - 0.4068*sin(Mprime) + 0.0161*sin(2*Mprime) - 0.0004*sin(3*Mprime) + 0.0104*sin(2*F) - 0.0051*sin(M+Mprime) - 0.0074*sin(M-Mprime) + 0.0004*sin(2*F+M) - 0.0004*sin(2*F-M) - 0.0006*sin(2*F+Mprime) + 0.0010*sin(2*F-Mprime) + 0.0005*sin(M+2*Mprime) 00077 else: 00078 correction = (0.1721 - 0.0004*T)*sin(M) + 0.0021*sin(2*M) - 0.6280*sin(Mprime) + 0.0089*sin(2*Mprime) - 0.0004*sin(3*Mprime) + 0.0079*sin(2*F) - 0.0119*sin(M+Mprime) - 0.0047*sin(M-Mprime) + 0.0003*sin(2*F+M) - 0.0004*sin(2*F-M) - 0.0006*sin(2*F+Mprime) + 0.0021*sin(2*F-Mprime) + 0.0003*sin(M+2*Mprime) + 0.0004*sin(M-2*Mprime) - 0.0003*sin(2*M+Mprime) 00079 julian = julian + correction 00080 if phase == FIRST: 00081 julian = julian + 0.0028 - 0.0004*cos(M) + 0.0003*cos(Mprime) 00082 if phase == LAST: 00083 julian = julian + -0.0028 + 0.0004*cos(M) - 0.0003*cos(Mprime) 00084 return julian 00085 00086 # Returns a structure that contains the calendar date associated 00087 # with a julian day. The tuple is (year, month, day) where year 00088 # and month are integers; day is a float. The julian parameter 00089 # is expected to be a float. Ref. Meeus pg 26. 00090 00091 def caldate(julian): 00092 julian = julian + 0.5 00093 Z = int(julian) 00094 F = julian - Z 00095 if Z < 2299161: 00096 A = Z 00097 else: 00098 alpha = int((Z-1867216.25)/36524.25) 00099 A = Z + 1 + alpha - int(alpha/4) 00100 B = A + 1524 00101 C = int((B - 122.1)/365.25) 00102 D = int(365.25*C) 00103 E = int((B - D)/30.6001) 00104 day = B - D - int(30.6001*E) + F 00105 if E < 13.5: 00106 month = int(E - 1) 00107 else: 00108 month = int(E - 13) 00109 if month > 2.5: 00110 year = int(C - 4716) 00111 else: 00112 year = int(C - 4715) 00113 return (year, month, day) 00114 00115 # UnivTimeCorrect Ref. Meeus pg 35. Calculates the correction to ephemeris 00116 # time to get universal time. The correction is gotten purely by his 00117 # approximate formula; the error is a maximum of 1.2 minutes between 1710 00118 # and 1987. 00119 00120 def UnivTimeCorrect(year): 00121 T = (year - 1900.0)/100.0 00122 return (0.41 + 1.2053*T + 0.4992*T*T)/60.0 00123 00124 def GetPhaseData(desired_year, phase): 00125 # Return a list of the julian days for the given year of each phase. 00126 # Start by getting a k that is in the middle of the previous year 00127 if desired_year < 1900: 00128 raise "Desired year should be > 1900" 00129 k1 = (desired_year - .5 - 1900) * 12.3685 00130 k = int(k1) 00131 done = 0 00132 data = [] 00133 while not done: 00134 julian = GetJulianFromPhase(k, phase) 00135 year, month, day = caldate(julian) 00136 if year == desired_year: 00137 data.append([julian, phase]) 00138 if year > desired_year: 00139 done = 1 00140 k = k + 1 00141 return data 00142 00143 def PrintItem(julian): 00144 month_name = ["", "Jan", "Feb", "Mar", "Apr", "May", 00145 "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] 00146 year, month, day = caldate(julian) 00147 Day = int(day) 00148 fraction = day - Day 00149 hours = 24.0*fraction 00150 decimal_time = hours + 12.0 + UnivTimeCorrect(year) 00151 if decimal_time > 24.0: 00152 day = day + 1 00153 decimal_time = decimal_time - 24.0 00154 minutes = int((decimal_time - int(decimal_time))*60) 00155 print " %02d %s %02d:%02d " % (Day, month_name[month], int(decimal_time), minutes) 00156 00157 def main(): 00158 desired_year = 2002 00159 if len(sys.argv) > 1: 00160 desired_year = int(sys.argv[1]) 00161 # Get a list of the phase times in julian days. Each element of the 00162 # list is another list containing the julian day and the phase number. 00163 results = [] 00164 data = GetPhaseData(desired_year, NEW) 00165 results = results + data 00166 data = GetPhaseData(desired_year, FIRST) 00167 results = results + data 00168 data = GetPhaseData(desired_year, FULL) 00169 results = results + data 00170 data = GetPhaseData(desired_year, LAST) 00171 results = results + data 00172 # Print header 00173 print "Moon phases for", desired_year 00174 # Convert to a dictionary keyed by the phase 00175 dict = {} 00176 for result in results: 00177 julian = result[0] 00178 phase = result[1] 00179 if dict.has_key(phase): 00180 dict[phase].append(julian) 00181 else: 00182 dict[phase] = [julian] 00183 phases = ["New", "First", "Full", "Last"] 00184 for phase in range(4): 00185 print phases[phase] 00186 for date in dict[phase]: 00187 PrintItem(date) 00188 00189 00190 main() 00191 00192
© Copyright 2008-2009 Vyper Logix Corp., All Right Reserved; If you reference this document or any part of this document you must use the citation verbatim (including the link) "© Copyright 2008-2009 Vyper Logix Corp., All Right Reserved."
Notice: This source code contained in this document is NOT open source and is NOT being distributed as open source.
122,241 lines of code and growing...