00001 ## 00002 # 00003 # Julian day routines from Meeus, "Astronomical Formulae for Calculators". 00004 # The routines are: 00005 # 00006 # Julian(month, day, year) Integer Julian day number 00007 # JulianAstro(month, day, year) Astronomical Julian day number 00008 # JulianToMonthDayYear(julian_day) Returns month, day, year tuple 00009 # DayOfWeek(month, day, year) 0 = Sunday 00010 # DayOfYear(month, day, year) 1 to 365 (366 in leap year) 00011 # IsValidDate(month, day, year) Returns true if date is valid Gregorian 00012 # IsLeapYear(year) Returns true if year is leap year 00013 # NumDaysInMonth(month, year) 00014 # 00015 # The JulianAstro function returns the astronomical form and is returned 00016 # as a floating point number. The astronomical Julian day begins at 00017 # Greenwich mean noon. The Julian() function returns the more usual 00018 # Julian day as an integer; it is gotten from the astronomical form by 00019 # adding 0.55 and taking the integer part. 00020 # 00021 # Warning: In general, the functions do _not_ check their incoming parameters. 00022 # 00023 # Don Peterson 30 May 1998 00024 # 00025 # Copyright (C) 2002 GDS Software 00026 # 00027 # This program is free software; you can redistribute it and/or 00028 # modify it under the terms of the GNU General Public License as 00029 # published by the Free Software Foundation; either version 2 of 00030 # the License, or (at your option) any later version. 00031 # 00032 # This program is distributed in the hope that it will be useful, 00033 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00034 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00035 # GNU General Public License for more details. 00036 # 00037 # You should have received a copy of the GNU General Public 00038 # License along with this program; if not, write to the Free 00039 # Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 00040 # MA 02111-1307 USA 00041 # 00042 # See http://www.gnu.org/licenses/licenses.html for more details. 00043 # 00044 00045 __version__ = "$Id: julian.py,v 1.3 2002/08/21 12:41:48 donp Exp $" 00046 00047 def NumDaysInMonth(month, year): 00048 if month == 2: 00049 if IsLeapYear(year): 00050 return 29 00051 else: 00052 return 28 00053 elif month == 9 or month == 4 or month == 6 or month == 11: 00054 return 30 00055 elif month == 1 or month == 3 or month == 5 or month == 7 or month == 8 or month == 10 or month == 12: 00056 return 31 00057 else: 00058 raise "Bad month" 00059 00060 def JulianToMonthDayYear(julian_day): 00061 if julian_day < 0: raise "Bad input value" 00062 jd = julian_day + 0.5 00063 Z = int(jd) 00064 F = jd - Z 00065 A = Z 00066 if Z >= 2299161: 00067 alpha = int((Z - 1867216.26)/36254.25) 00068 A = Z + 1 + alpha - int(alpha/4) 00069 B = A + 1524 00070 C = int((B - 122.1)/365.25) 00071 D = int(365.25 * C) 00072 E = int((B - D)/30.6001) 00073 day = B - D - int(30.6001 * E) + F 00074 if E < 13.5: 00075 month = int(E - 1) 00076 else: 00077 month = int(E - 13) 00078 if month > 2.5: 00079 year = int(C - 4716) 00080 else: 00081 year = int(C - 4715) 00082 return month, day, year 00083 00084 def DayOfYear(month, day, year): 00085 if IsLeapYear(year): 00086 n = int((275*month)/9 - ((month + 9)/12) + int(day) - 30) 00087 else: 00088 n = int((275*month)/9 - 2*((month + 9)/12) + int(day) - 30) 00089 if n < 1 or n > 366: raise "Internal error" 00090 return n 00091 00092 def DayOfWeek(month, day, year): 00093 julian = int(JulianAstro(month, int(day), year) + 1.5) 00094 return julian % 7 00095 00096 def IsLeapYear(year): 00097 if (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0): 00098 return 1 00099 else: 00100 return 0 00101 00102 ## 00103 # Returns true if the year is later than 1752 and the month and day 00104 # numbers are valid. 00105 # 00106 def IsValidDate(month, day, year): 00107 if month < 1 or month > 12: return 0 00108 if int(month) != month : return 0 00109 if year < 1753 : return 0 00110 if day < 1.0 : return 0 00111 if int(day) != day: 00112 if month == 2: 00113 if IsLeapYear(year): 00114 if day >= 30.0: return 0 00115 else: 00116 if day >= 29.0: return 0 00117 elif month == 9 or month == 4 or month == 6 or month == 11: 00118 if day >= 31.0 : return 0 00119 else: 00120 if day >= 32.0 : return 0 00121 else: 00122 if month == 2: 00123 if IsLeapYear(year): 00124 if day >= 29 : return 0 00125 else: 00126 if day >= 28 : return 0 00127 elif month == 9 or month == 4 or month == 6 or month == 11: 00128 if day >= 30 : return 0 00129 else: 00130 if day >= 31 : return 0 00131 return 1 00132 00133 def JulianAstro(month, day, year): 00134 "Note that day can be either an integer or a float." 00135 if month < 3: 00136 year = year - 1 00137 month = month + 12 00138 julian = int(365.25*year) + int(30.6001*(month+1)) + day + 1720994.5 00139 tmp = year + month / 100.0 + day / 10000.0 00140 if tmp >= 1582.1015: 00141 A = year / 100 00142 B = 2 - A + A/4 00143 julian = julian + B 00144 return julian * 1.0 00145 00146 def Julian(month, day, year): 00147 return int(JulianAstro(month, day, year) + 0.55) 00148 00149 def Test(): 00150 if Julian(12, 31, 1989) != 2447892 : raise "TestError" 00151 if Julian(1, 1, 1990) != 2447893 : raise "TestError" 00152 if Julian(7, 4, 1776) != 2369916 : raise "TestError" 00153 if Julian(2, 29, 2000) != 2451604 : raise "TestError" 00154 if JulianAstro(1, 27.5, 333) != 1842713.0 : raise "TestError" 00155 if JulianAstro(10, 4.81, 1957) != 2436116.31: raise "TestError" 00156 if DayOfWeek(11, 13, 1949) != 0 : raise "TestError" 00157 if DayOfWeek( 5, 30, 1998) != 6 : raise "TestError" 00158 if DayOfWeek( 6, 30, 1954) != 3 : raise "TestError" 00159 if DayOfYear(11, 14, 1978) != 318 : raise "TestError" 00160 if DayOfYear( 4, 22, 1980) != 113 : raise "TestError" 00161 00162 month, day, year = JulianToMonthDayYear(2436116.31) 00163 if month != 10 : raise "TestError" 00164 if year != 1957 : raise "TestError" 00165 if abs(day - 4.81) > .00001 : raise "TestError" 00166 month, day, year = JulianToMonthDayYear(1842713.0) 00167 if month != 1 : raise "TestError" 00168 if year != 333 : raise "TestError" 00169 if abs(day - 27.5) > .00001 : raise "TestError" 00170 month, day, year = JulianToMonthDayYear(1507900.13) 00171 if month != 5 : raise "TestError" 00172 if year != -584 : raise "TestError" 00173 if abs(day - 28.63) > .00001 : raise "TestError" 00174 00175 if NumDaysInMonth( 1, 1999) != 31 : raise "TestError" 00176 if NumDaysInMonth( 2, 1999) != 28 : raise "TestError" 00177 if NumDaysInMonth( 3, 1999) != 31 : raise "TestError" 00178 if NumDaysInMonth( 4, 1999) != 30 : raise "TestError" 00179 if NumDaysInMonth( 5, 1999) != 31 : raise "TestError" 00180 if NumDaysInMonth( 6, 1999) != 30 : raise "TestError" 00181 if NumDaysInMonth( 7, 1999) != 31 : raise "TestError" 00182 if NumDaysInMonth( 8, 1999) != 31 : raise "TestError" 00183 if NumDaysInMonth( 9, 1999) != 30 : raise "TestError" 00184 if NumDaysInMonth(10, 1999) != 31 : raise "TestError" 00185 if NumDaysInMonth(11, 1999) != 30 : raise "TestError" 00186 if NumDaysInMonth(12, 1999) != 31 : raise "TestError" 00187 00188 if NumDaysInMonth( 1, 2000) != 31 : raise "TestError" 00189 if NumDaysInMonth( 2, 2000) != 29 : raise "TestError" 00190 if NumDaysInMonth( 3, 2000) != 31 : raise "TestError" 00191 if NumDaysInMonth( 4, 2000) != 30 : raise "TestError" 00192 if NumDaysInMonth( 5, 2000) != 31 : raise "TestError" 00193 if NumDaysInMonth( 6, 2000) != 30 : raise "TestError" 00194 if NumDaysInMonth( 7, 2000) != 31 : raise "TestError" 00195 if NumDaysInMonth( 8, 2000) != 31 : raise "TestError" 00196 if NumDaysInMonth( 9, 2000) != 30 : raise "TestError" 00197 if NumDaysInMonth(10, 2000) != 31 : raise "TestError" 00198 if NumDaysInMonth(11, 2000) != 30 : raise "TestError" 00199 if NumDaysInMonth(12, 2000) != 31 : raise "TestError" 00200 00201 if __name__ == "__main__": 00202 Test() 00203 00204
© 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...