#! /usr/bin/env python3 # def calpak_test ( ): #*****************************************************************************80 # ## calpak_test() tests calpak(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 January 2018 # # Author: # # John Burkardt # import numpy as np import platform print ( '' ) print ( 'calpak_test():' ) print ( ' python version: ' + platform.python_version ( ) ) print ( ' numpy version: ' + np.version.version ) print ( ' Test calpak().' ) ch_cap_test ( ) datenum_to_jed_test ( ) datenum_values_test ( ) day_list_common_test ( ) easter_gregorian_ds_test ( ) easter_gregorian_egr_test ( ) easter_gregorian_egr2_test ( ) easter_gregorian_knuth_test ( ) easter_gregorian_stewart_test ( ) easter_julian_egr_test ( ) easter_julian_egr2_test ( ) gps_to_jed_test ( ) i4_modp_test ( ) i4_normal_ab_test ( ) i4_wrap_test ( ) jed_ce_values_test ( ) jed_is_legal_test ( ) jed_mjd_values_test ( ) jed_rd_values_test ( ) jed_to_datenum_test ( ) jed_to_gps_test ( ) jed_to_noon_nearest_test ( ) jed_to_noon_next_test ( ) jed_to_weekday_test ( ) jed_weekday_values_test ( ) month_to_month_name_common_test ( ) month_to_month_name_common3_test ( ) r8_mod_test ( ) weekday_to_name_common_test ( ) weekday_to_name_common2_test ( ) weekday_to_name_common3_test ( ) weekday_values_test ( ) y_common_to_astronomical_test ( ) y_to_s_common_test ( ) year_is_leap_gregorian_test ( ) year_length_days_common_test ( ) year_to_golden_number_test ( ) ymd_to_weekday_common_test ( ) # # Terminate. # print ( '' ) print ( 'calpak_test():' ) print ( ' Normal end of execution.' ) return def ch_cap ( c ): #*****************************************************************************80 # ## ch_cap() capitalizes a single character. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 June 2015 # # Author: # # John Burkardt # # Input: # # character C, the character to capitalize. # # Output: # # character C2, the capitalized character. # i = ord ( c ) if ( ord ( 'a' ) <= i and i <= ord ( 'z' ) ): i2 = i + ord ( 'A' ) - ord ( 'a' ) c2 = chr ( i2 ) else: c2 = c return c2 def ch_cap_test ( ): #*****************************************************************************80 # ## ch_cap_test() tests ch_cap(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 June 2015 # # Author: # # John Burkardt # print ( '' ) print ( 'ch_cap_test():' ) print ( ' ch_cap() uppercases a character.' ) print ( '' ) print ( ' C ch_cap(C)' ) print ( '' ) c = 'F' c2 = ch_cap ( c ) print ( ' %c %c' % ( c, c2 ) ) c = 'f' c2 = ch_cap ( c ) print ( ' %c %c' % ( c, c2 ) ) c = '1' c2 = ch_cap ( c ) print ( ' %c %c' % ( c, c2 ) ) c = 'b' c2 = ch_cap ( c ) print ( ' %c %c' % ( c, c2 ) ) c = '&' c2 = ch_cap ( c ) print ( ' %c %c' % ( c, c2 ) ) return def datenum_to_jed ( dn ): #*****************************************************************************80 # ## datenum_to_jed() converts a MATLAB DATENUM to a JED. # # Discussion: # # The MATLAB "datenum" function accepts a string defining # a date and returns a MATLAB date number: # # dn = datenum ( 'Aug 17 1939' ) # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # real DN, a MATLAB DATENUM. # # Output: # # real JED, the Julian Ephemeris Date. # jed = dn + epoch_to_jed_datenum ( ) return jed def datenum_to_jed_test ( ): #*****************************************************************************80 # ## datenum_to_jed_test() tests datenum_to_jed(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'datenum_to_jed_test():' ) print ( ' datenum_to_jed: Matlab DATENUM -> JED.' ) print ( '' ) print ( ' JED (in) DATENUM JED (out)' ) print ( '' ) jed_epoch = epoch_to_jed_datenum ( ) i = 0 while ( True ): i = i + 1 jed1 = jed_test ( i ) if ( jed1 < 0.0 ): break if ( jed_epoch <= jed1 ): date_num = jed_to_datenum ( jed1 ) jed3 = datenum_to_jed ( date_num ) print ( ' %11.2f %12.2f %11.2f'% ( jed1, date_num, jed3 ) ) return def datenum_values ( n_data ): #*****************************************************************************80 # ## datenum_values() returns the MATLAB DATENUM for various dates. # # Discussion: # # The CE or Common Era calendar is used, under the # hybrid Julian/Gregorian Calendar, with a transition from Julian # to Gregorian. The day after 04 October 1582 was 15 October 1582. # # The year before 1 AD or CE is 1 BC or BCE. In this data set, # years BC/BCE are indicated by a negative year value. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 13 December 2017 # # Author: # # John Burkardt # # Reference: # # Edward Reingold, Nachum Dershowitz, # Calendrical Calculations: The Millennium Edition, # Cambridge University Press, 2001, # ISBN: 0 521 77752 6 # LC: CE12.R45. # # Input: # # integer N_DATA. The user sets N_DATA to 0 before the first call. # # Output: # # integer N_DATA. On each call, the routine increments N_DATA by 1, # and returns the corresponding data; when there is no more data, the # output value of N_DATA will be 0 again. # # integer Y, M, D, the Common Era date. # # integer DATENUM, the MATLAB DATENUM value. # import numpy as np n_max = 11 d_vec = np.array ( ( \ 1, \ 1, \ 1, \ 1, \ 17, \ 9, \ 10, \ 12, \ 6, \ 25, \ 1 )) date_num_vec = np.array ( ( \ 1, \ 367, \ 36526, \ 365244, \ 708434, \ 710284, \ 713023, \ 718199, \ 723186, \ 729080, \ 730486 )) m_vec = np.array ( ( \ 1, \ 1, \ 1, \ 1, \ 8, \ 9, \ 3, \ 5, \ 1, \ 2, \ 1 )) y_vec = np.array ( ( \ 0, \ 1, \ 100, \ 1000, \ 1939, \ 1944, \ 1952, \ 1966, \ 1980, \ 1996, \ 2000 )) if ( n_data < 0 ): n_data = 0 if ( n_max <= n_data ): n_data = 0 y = 0 m = 0 d = 0 date_num = 0 else: y = y_vec[n_data] m = m_vec[n_data] d = d_vec[n_data] date_num = date_num_vec[n_data] n_data = n_data + 1 return n_data, y, m, d, date_num def datenum_values_test ( ): #*****************************************************************************80 # ## datenum_values_test() tests datenum_values(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 13 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'datenum_values_test():' ) print ( ' datenum_values() stores values of' ) print ( ' the MATLAB datenum for a given Y/M/D date' ) print ( '' ) print ( ' Y M D DateNum' ) print ( '' ) n_data = 0 while ( True ): n_data, y, m, d, date_num = datenum_values ( n_data ) if ( n_data == 0 ): break print ( ' %6d %6d %6d %6d' % ( y, m, d, date_num ) ) return def day_borrow_alexandrian ( y, m, d ): #*****************************************************************************80 # ## day_borrow_alexandrian() borrows days from months in an Alexandrian date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after borrowing. # while ( d <= 0 ): m = m - 1 y, m = month_borrow_alexandrian ( y, m ) days = month_length_alexandrian ( y, m ) d = d + days return y, m, d def day_borrow_common ( y, m, d ): #*****************************************************************************80 # ## day_borrow_common() borrows days from months in a Common date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, a year, month, and day representing a date. # # Output: # # integer Y, M, D. On M should have decreased by one month, # and D gone up by the number of days in the month we "cashed in". # Y may be affected if the input value of M was 1. # while ( d <= 0 ): m = m - 1 y, m = month_borrow_common ( y, m ) days = month_length_common ( y, m ) d = d + days return y, m, d def day_borrow_eg_civil ( y, m, d ): #*****************************************************************************80 # ## day_borrow_eg_civil() borrows days from months in an Egyptian Civil date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after borrowing. # while ( d <= 0 ): m = m - 1 [ y, m ] = month_borrow_eg_civil ( y, m ) days = month_length_eg_civil ( y, m ) d = d + days return y, m, d def day_borrow_english ( y, m, d ): #*****************************************************************************80 # ## day_borrow_english() borrows days from months in an English date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after borrowing. # while ( d <= 0 ): m = m - 1 y, m = month_borrow_english ( y, m ) days = month_length_english ( y, m ) d = d + days return y, m, d def day_borrow_gregorian ( y, m, d ): #*****************************************************************************80 # ## day_borrow_gregorian() borrows days from months in a Gregorian date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after borrowing. # while ( d <= 0 ): m = m - 1 y, m = month_borrow_gregorian ( y, m ) days = month_length_gregorian ( y, m ) d = d + days return y, m, d def day_borrow_hebrew ( y, m, d ): #*****************************************************************************80 # ## day_borrow_hebrew() borrows days from months in a Hebrew date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after borrowing. # while ( d <= 0 ): m = m - 1 y, m = month_borrow_hebrew ( y, m ) days = month_length_hebrew ( y, m ) d = d + days return y, m, d def day_borrow_islamic ( y, m, d ): #*****************************************************************************80 # ## day_borrow_islamic() borrows days from months in an Islamic date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after borrowing. # while ( d <= 0 ): m = m - 1 y, m = month_borrow_islamic ( y, m ) days = month_length_islamic ( y, m ) d = d + days return y, m, d def day_borrow_julian ( y, m, d ): #*****************************************************************************80 # ## day_borrow_julian() borrows days from months in a Julian date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after borrowing. # while ( d <= 0 ): m = m - 1 y, m = month_borrow_julian ( y, m ) days = month_length_julian ( y, m ) d = d + days return y, m, d def day_borrow_republican ( y, m, d ): #*****************************************************************************80 # ## day_borrow_republican() borrows days from months in a Republican date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after borrowing. # while ( d <= 0 ): m = m - 1 y, m = month_borrow_republican ( y, m ) days = month_length_republican ( y, m ) d = d + days return y, m, d def day_borrow_roman ( y, m, d ): #*****************************************************************************80 # ## day_borrow_roman() borrows days from months in a Roman date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after borrowing. # while ( d <= 0 ): m = m - 1 y, m = month_borrow_roman ( y, m ) days = month_length_roman ( y, m ) d = d + days return y, m, d def day_carry_alexandrian ( y, m, d ): #*****************************************************************************80 # ## day_carry_alexandrian() carries days to months in an Alexandrian date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after carrying. # days = month_length_alexandrian ( y, m ) while ( days < d ): d = d - days m = m + 1 days = month_length_alexandrian ( y, m ) # # Make sure the month isn't too big. # y, m = month_carry_alexandrian ( y, m ) return y, m, d def day_carry_common ( y, m, d ): #*****************************************************************************80 # ## day_carry_common() carries days to months in a Common date. # # Discussion: # # While ( number of days in M ) < D: # decrease the day D by the number of days in the month M; # increase M by 1; # if necessary, adjust Y. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date. # D is guaranteed to be between 1 and the number of days in M. # # # If the date is in the transition month, deflate it, # so we can perform ordinary arithmetic. # y, m, d = deflate_common ( y, m, d ); days = month_length_common ( y, m ) while ( days < d ): d = d - days m = m + 1 days = month_length_common ( y, m ) # # Make sure the month isn't too big. # y, m = month_carry_common ( y, m ) # # If the date is in the transition month, inflate it. # y, m, d = inflate_common ( y, m, d ) return y, m, d def day_carry_eg_civil ( y, m, d ): #*****************************************************************************80 # ## day_carry_eg_civil() carries days to months in an Egyptian Civil date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after carrying. # days = month_length_eg_civil ( y, m ) while ( days < d ): d = d - days m = m + 1 days = month_length_eg_civil ( y, m ) # # Make sure the month isn't too big. # y, m = month_carry_eg_civil ( y, m ) return y, m, d def day_carry_english ( y, m, d ): #*****************************************************************************80 # ## day_carry_english() carries days to months in an English date. # # Discussion: # # While ( number of days in M ) < D: # decrease the day D by the number of days in the month M # increase M by 1 # if necessary, adjust Y. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after carrying. # # # If the date is in the transition month, deflate it, # so we can perform ordinary arithmetic. # y, m, d = deflate_english ( y, m, d ) days = month_length_english ( y, m ) while ( days < d ): d = d - days m = m + 1 days = month_length_english ( y, m ) # # Make sure the month isn't too big. # y, m = month_carry_english ( y, m ) # # If the date is in the transition month, inflate it. # y, m, d = inflate_english ( y, m, d ) return y, m, d def day_carry_gregorian ( y, m, d ): #*****************************************************************************80 # ## day_carry_gregorian() carries days to months in a Gregorian date. # # Discussion: # # While ( number of days in M ) < D: # decrease the day D by the number of days in the month M # increase M by 1 # if necessary, adjust Y. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after carrying. # days = month_length_gregorian ( y, m ) while ( days < d ): d = d - days m = m + 1 days = month_length_gregorian ( y, m ) # # Make sure the month isn't too big. # y, m = month_carry_gregorian ( y, m ) return y, m, d def day_carry_hebrew ( y, m, d ): #*****************************************************************************80 # ## day_carry_hebrew() carries days to months in a Hebrew date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after carrying. # days = month_length_hebrew ( y, m ) while ( days < d ): d = d - days m = m + 1 days = month_length_hebrew ( y, m ) # # Make sure the month isn't too big. # y, m = month_carry_hebrew ( y, m ) return y, m, d def day_carry_islamic ( y, m, d ): #*****************************************************************************80 # ## day_carry_islamic() carries days to months in an Islamic date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after carrying. # days = month_length_islamic ( y, m ) while ( days < d ): d = d - days m = m + 1 days = month_length_islamic ( y, m ) # # Make sure the month isn't too big. # y, m = month_carry_islamic ( y, m ) return y, m, d def day_carry_julian ( y, m, d ): #*****************************************************************************80 # ## day_carry_julian() carries days to months in a Julian date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after carrying. # days = month_length_julian ( y, m ) while ( days < d ): d = d - days m = m + 1 days = month_length_julian ( y, m ) # # Make sure the month isn't too big. # y, m = month_carry_julian ( y, m ) return y, m, d def day_carry_republican ( y, m, d ): #*****************************************************************************80 # ## day_carry_republican() carries days to months in a Republican date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after carrying. # days = month_length_republican ( y, m ) while ( days < d ): d = d - days m = m + 1 days = month_length_republican ( y, m ) # # Make sure the month isn't too big. # y, m = month_carry_republican ( y, m ) return y, m, d def day_carry_roman ( y, m, d ): #*****************************************************************************80 # ## day_carry_roman() carries days to months in a Roman date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after carrying. # days = month_length_roman ( y, m ) while ( days < d ): d = d - days m = m + 1 days = month_length_roman ( y, m ) # # Make sure the month isn't too big. # y, m = month_carry_roman ( y, m ) return y, m, d def day_list_common ( y1, m1, d1, y2, m2, d2 ): #*****************************************************************************80 # ## day_list_common() prints a list of days between two dates. # # Discussion: # # Given the dates of September 25, 2005 and October 2, 2005, # the routine should print out: # # Sun, Sep 25 2005 - # Mon, Sep 26 2005 - # Tue, Sep 27 2005 - # Wed, Sep 28 2005 - # Thu, Sep 29 2005 - # Fri, Sep 30 2005 - # Sat, Oct 01 2005 - # Sun, Oct 02 2005 - # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 15 June 2012 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, the first date. # # integer Y2, M2, D2, the second date. # y = y1 m = m1 d = d1 f = 0.0 cmp = '<' while ( cmp != '>' ): w = ymdf_to_weekday_common ( y, m, d, f ) w_name = weekday_to_name_common3 ( w ) m_name = month_to_month_name_common3 ( m ) print ( '%3s, %3s %02d %4d -' % ( w_name, m_name, d, y ) ) y, m, d, f = ymdf_next_common ( y, m, d, f ) cmp = ymdf_compare ( y, m, d, f, y2, m2, d2, f ) return def day_list_common_test ( ): #*****************************************************************************80 # ## day_list_common_test() tests day_list_common(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 24 December 2017 # # Author: # # John Burkardt # d1 = 1 d2 = 31 m1 = 9 m2 = 12 y1 = 2012 y2 = 2012 print ( '' ) print ( 'day_list_common_test():' ) print ( ' day_list_common() prints a list of days between' ) print ( ' two given YMD dates in the common calendar.' ) print ( '' ) s = ymd_to_s_common ( y1, m1, d1 ) print ( ' Initial date: %s' % ( s ) ) s = ymd_to_s_common ( y2, m2, d2 ) print ( ' Final date: %s' % ( s ) ) print ( '\n' ) day_list_common ( y1, m1, d1, y2, m2, d2 ) return def days_before_month_common ( y, m ): #*****************************************************************************80 # ## days_before_month_common() returns the number of days before a Common month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year in which the month occurred. # # integer M, the number of the month. # # Output: # # integer DAYS, the number of # days in the year before the first day of the given month. # mdays = [ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 ] # # Copy the input. # m2 = m y2 = y # # Check the input. # y2, m2, ierror = ym_check_common ( y2, m2 ) if ( ierror ): days = 0 return days days = mdays[m2-1] if ( 2 < m2 and year_is_leap_common ( y2 ) ): days = days + 1 return days def days_before_month_gregorian ( y, m ): #*****************************************************************************80 # ## days_before_month_gregorian(): number of days before a Gregorian month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year in which the month occurred. # # integer M, the number of the month. # # Output: # # integer DAYS_BEFORE_MONTH_GREGORIAN, the number of # days in the year before the first day of the given month. # mdays = [ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 ] # # Copy the input. # m2 = m y2 = y # # Check the input. # y2, m2, ierror = ym_check_gregorian ( y2, m2 ) if ( ierror ): value = 0 return value value = mdays[m2-1] if ( 2 < m2 and year_is_leap_gregorian ( y2 ) ): value = value + 1 return value def days_before_month_julian ( y, m ): #*****************************************************************************80 # ## days_before_month_julian() returns the number of days before a Julian month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year in which the month occurred. # # integer M, the number of the month. # # Output: # # integer VALUE, the number of # days in the year before the first day of the given month. # mdays = [ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 ] # # Copy the input. # m2 = m y2 = y # # Check the input. # y2, m2, ierror = ym_check_julian ( y2, m2 ) if ( ierror ): value = 0 return value value = mdays[m2-1] if ( 2 < m2 and year_is_leap_julian ( y2 ) ): value = value + 1 return value def deflate_common ( y, m, d ): #*****************************************************************************80 # ## deflate_common() "deflates" dates in the Common Calendar transition month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the "deflated" YMD date. # if ( y == 1582 ): if ( m == 10 ): if ( 15 <= d ): d = d - 10 return y, m, d def deflate_english ( y, m, d ): #*****************************************************************************80 # ## deflate_english() "deflates" dates in the English Calendar transition month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after deflation. # if ( y == 1752 ): if ( m == 9 ): if ( 14 <= d ): d = d - 11 return y, m, d def easter_gregorian_ds ( y ): #*****************************************************************************80 # ## easter_gregorian_ds() computes the month and day of Easter for a Gregorian year. # # Example: # # Input: # # Y = 2000 # # Output: # # M = 4 # D = 23 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 24 December 2017 # # Author: # # John Burkardt # # Reference: # # Peter Duffett-Smith, # Practical Astronomy With Your Calculator, # Third Edition, # Cambridge University Press, 1996, # ISBN: 0-521-35699-7, # LC: QB62.5.D83. # # Input: # # integer Y, the year, which must be 1583 or greater. # (The formula is only valid for years after the Gregorian calendar # was adopted.) # # Output: # # integer M, D, the month and day of Easter. # if ( y <= 0 ): m = -1; d = -1; return m, d a = year_to_golden_number ( y ) a = a - 1 b = ( y // 100 ) c = ( y % 100 ) dd = ( b // 4 ) e = ( b % 4 ) f = ( ( b + 8 ) // 25 ) g = ( ( b - f + 1 ) // 3 ) h = ( ( 19 * a + b - dd - g + 15 ) % 30 ) i = ( c // 4 ) k = ( c % 4 ) l = ( ( 32 + 2 * e + 2 * i - h - k ) % 7 ) mm = ( ( a + 11 * h + 22 * l ) // 451 ) m = ( ( h + l - 7 * mm + 114 ) // 31 ) d = ( ( h + l - 7 * mm + 114 ) % 31 ) + 1 return m, d def easter_gregorian_ds_test ( ): #*****************************************************************************80 # ## easter_gregorian_ds_test() tests easter_gregorian_ds(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 24 December 2017 # # Author: # # John Burkardt # import numpy as np n_test = 10 d_test = np.array ( \ [ 30, 12, 4, 23, 15, 31, 20, 11, 27, 16 ] ) m_test = np.array ( \ [ 3, 4, 4, 4, 4, 3, 4, 4, 3, 4 ] ) y_test = np.array ( \ [ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ] ) print ( '' ) print ( 'easter_gregorian_ds_test():' ) print ( ' easter_gregorian_ds() uses Duffett-Smith\'s algorithm' ) print ( ' for the Gregorian calendar,' ) print ( ' for a given year, to compute the day and month of Easter.' ) for i in range ( 0, n_test ): y = y_test[i] m = m_test[i] d = d_test[i] print ( '' ) s = ymd_to_s_gregorian ( y, m, d ) print ( ' CORRECT: %s' % ( s ) ) m, d = easter_gregorian_ds ( y ) s = ymd_to_s_gregorian ( y, m, d ) print ( ' COMPUTED: %s' % ( s ) ) return def easter_gregorian_egr ( y ): #*****************************************************************************80 # ## easter_gregorian_egr() computes the month and day of Easter for a Common year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 24 December 2017 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm O, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 375. # # Input: # # integer Y, the year. # # Output: # # integer M, D, the month and day of Easter. # if ( y <= 0 ): m = -1 d = -1 return m, d p = y + ( y // 4 ) - ( y // 100 ) + ( y // 400 ) - 1 n = 7 - ( p % 7 ) h = ( y // 100 ) q = h - ( h // 4 ) g = 1 + ( y % 19 ) e = ( ( 57 + 11 * g - q + ( ( h - ( ( h - 17 ) // 25 ) ) // 3 ) ) % 30 ) u = ( ( 53 - e ) % 30 ) vp = ( ( g - 1 + 11 * u ) // 319 ) r = 22 + u - vp c = i4_wrap ( r + 3, 1, 7 ) s = r + ( ( 7 + n - c ) % 7 ) m = 3 + ( s // 32 ) d = i4_wrap ( s, 1, 31 ) return m, d def easter_gregorian_egr_test ( ): #*****************************************************************************80 # ## easter_gregorian_egr_test() tests easter_gregorian_egr(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 24 December 2017 # # Author: # # John Burkardt # import numpy as np n_test = 10 d_test = np.array ( \ [ 30, 12, 4, 23, 15, 31, 20, 11, 27, 16 ] ) m_test = np.array ( \ [ 3, 4, 4, 4, 4, 3, 4, 4, 3, 4 ] ) y_test = np.array ( \ [ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ] ) print ( '' ) print ( 'easter_gregorian_egr_test():' ) print ( ' For the Gregorian calendar,' ) print ( ' for a given year, compute the day and month of Easter.' ) print ( ' easter_gregorian_egr uses Richards\'s algorithm #1.' ) for i in range ( 0, n_test ): y = y_test[i] m = m_test[i] d = d_test[i] print ( '' ) s = ymd_to_s_gregorian ( y, m, d ) print ( ' CORRECT: %s' % ( s ) ) m, d = easter_gregorian_egr ( y ) s = ymd_to_s_gregorian ( y, m, d ) print ( ' COMPUTED: %s' % ( s ) ) return def easter_gregorian_egr2 ( y ): #*****************************************************************************80 # ## easter_gregorian_egr2() computes the month and day of Easter for a Common year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 January 2018 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm P, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 376. # # Input: # # integer Y, the year. # # Output: # # integer M, D, the month and day of Easter. # if ( y <= 0 ): m = -1 d = -1 return m, d a = ( y // 100 ) b = a - ( a // 4 ) c = ( y % 19 ) d = ( ( 15 + 19 * c + b - ( ( a - ( ( a - 17 ) // 25 ) ) // 3 ) ) % 30 ) e = d - ( ( c + 11 * d ) // 319 ) s = 22 + e + ( ( 140004 - y - ( y // 4 ) + b - e ) % 7 ) m = 3 + ( s // 32 ) d = i4_wrap ( s, 1, 31 ) return m, d def easter_gregorian_egr2_test ( ): #*****************************************************************************80 # ## easter_gregorian_egr2_test() tests easter_gregorian_egr2(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 January 2018 # # Author: # # John Burkardt # import numpy as np n_test = 10 d_test = np.array ( \ [ 30, 12, 4, 23, 15, 31, 20, 11, 27, 16 ] ) m_test = np.array ( \ [ 3, 4, 4, 4, 4, 3, 4, 4, 3, 4 ] ) y_test = np.array ( \ [ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ] ) print ( '' ) print ( 'easter_gregorian_egr2_test():' ) print ( ' For the Gregorian calendar,' ) print ( ' for a given year, compute the day and month of Easter.' ) print ( ' easter_gregorian_egr2() uses Richards\'s algorithm #2.' ) for i in range ( 0, n_test ): y = y_test[i] m = m_test[i] d = d_test[i] print ( '' ) s = ymd_to_s_gregorian ( y, m, d ) print ( ' CORRECT: %s' % ( s ) ) m, d = easter_gregorian_egr2 ( y ) s = ymd_to_s_gregorian ( y, m, d ) print ( ' COMPUTED: %s' % ( s ) ) return def easter_gregorian_knuth ( y ): #*****************************************************************************80 # ## easter_gregorian_knuth() computes the month and day of Easter for a Gregorian year. # # Discussion: # # Knuth attributes the algorithm to Aloysius Lilius and Christopher Clavius # in the late 16th century. The algorithm is for use with the Gregorian # calendar. # # Example: # # Input: # # Y = 2000 # # Output: # # M = 4 # D = 23 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 January 2018 # # Author: # # John Burkardt # # Reference: # # Donald Knuth, # The Art of Computer Programming, # Volume 1: Fundamental Algorithms, # Addison Wesley, 1968, pages 155-156. # # Donald Knuth, # The Calculation of Easter, # Communications of the ACM, # Volume 5, Number 4, April 1962, pages 209-210. # # Thomas O'Beirne, # Puzzles and Paradoxes, # Oxford University Press, 1965, chapter 10. # # Input: # # integer Y, the year, which must be 1583 or greater. # (The formula is only valid for years after the Gregorian calendar # was adopted.) # # Output: # # integer M, D, the month and day of Easter. # if ( y <= 0 ): m = -1 d = -1 return m, d # # E1: Set the golden number of the year in the 19-year Metonic cycle. # g = year_to_golden_number ( y ) # # E2: Set the century. # c = ( y // 100 ) + 1 # # E3: Corrections. # X is the number of years divisible by 100 in which leap year was dropped. # Z is a special correction to synchronize Easter with the moon's orbit. # x = ( 3 * c // 4 ) - 12 z = ( ( 8 * c + 5 ) // 25 ) - 5 # # E4: Find Sunday. # dd = ( 5 * y // 4 ) - x - 10 # # E5: Epact # e = i4_modp ( 11 * g + 20 + z - x, 30 ) if ( ( e == 25 and 11 < g ) or ( e == 24 ) ): e = e + 1 # # E6: Find the full moon. # n = 44 - e if ( n < 21 ): n = n + 30 # # E7: Advance to Sunday. # n = n + 7 - ( ( dd + n) % 7 ) # # E8: Get month. # if ( 31 < n ): d = n - 31 m = 4 else: d = n m = 3 return m, d def easter_gregorian_knuth_test ( ): #*****************************************************************************80 # ## easter_gregorian_knuth_test() tests easter_gregorian_knuth(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 January 2018 # # Author: # # John Burkardt # import numpy as np n_test = 10 d_test = np.array ( \ [ 30, 12, 4, 23, 15, 31, 20, 11, 27, 16 ] ) m_test = np.array ( \ [ 3, 4, 4, 4, 4, 3, 4, 4, 3, 4 ] ) y_test = np.array ( \ [ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ] ) print ( '' ) print ( 'easter_gregorian_knuth_test():' ) print ( ' For the Gregorian calendar,' ) print ( ' for a given year, compute the day and month of Easter.' ) print ( ' easter_gregorian_knuth uses Knuth\'s algorithm.' ) for i in range ( 0, n_test ): y = y_test[i] m = m_test[i] d = d_test[i] print ( '' ) s = ymd_to_s_gregorian ( y, m, d ) print ( ' CORRECT: %s' % ( s ) ) m, d = easter_gregorian_knuth ( y ) s = ymd_to_s_gregorian ( y, m, d ) print ( ' COMPUTED: %s' % ( s ) ) return def easter_gregorian_stewart ( y ): #*****************************************************************************80 # ## easter_gregorian_stewart() computes the month and day of Easter for a Gregorian year. # # Example: # # Y = 2001 # # A = 6 # B = 20 # C = 1 # DD = 5 # E = 0 # G = 6 # H = 18 # MM = 0 # J = 0 # K = 1 # L = 6 # M = 4 # D = 15 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 January 2018 # # Author: # # John Burkardt # # Reference: # # Thomas O'Beirne, # Puzzles and Paradoxes, # Oxford University Press, 1965. # # Ian Stewart, # Easter is a Quasicrystal, # Scientific American, # March 2001, pages 80-83. # # Input: # # integer Y, the year. # # Output: # # integer M, D, the month and day of Easter. # a = ( y % 19 ) b = ( y // 100 ) c = ( y % 100 ) dd = ( b // 4 ) e = ( b % 4 ) g = ( ( 8 * b + 13 ) // 25 ) h = ( ( 19 * a + b - dd - g + 15 ) % 30 ) mm = ( ( a + 11 * h ) // 319 ) j = ( c // 4 ) k = ( c % 4 ) l = ( ( 2 * e + 2 * j - k - h + mm + 32 )% 7 ) m = ( ( h - mm + l + 90 ) // 25 ) d = ( ( h - mm + l + m + 19) % 32 ) return m, d def easter_gregorian_stewart_test ( ): #*****************************************************************************80 # ## easter_gregorian_stewart_test() tests easter_gregorian_stewart(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 January 2018 # # Author: # # John Burkardt # import numpy as np n_test = 10 d_test = np.array ( \ [ 30, 12, 4, 23, 15, 31, 20, 11, 27, 16 ] ) m_test = np.array ( \ [ 3, 4, 4, 4, 4, 3, 4, 4, 3, 4 ] ) y_test = np.array ( \ [ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ] ) print ( '' ) print ( 'easter_gregorian_stewart_test():' ) print ( ' For the Gregorian calendar,' ) print ( ' for a given year, compute the day and month of Easter.' ) print ( ' easter_gregorian_stewart uses Stewart\'s algorithm.' ) for i in range ( 0, n_test ): y = y_test[i] m = m_test[i] d = d_test[i] print ( '' ) s = ymd_to_s_gregorian ( y, m, d ) print ( ' CORRECT: %s' % ( s ) ) m, d = easter_gregorian_stewart ( y ) s = ymd_to_s_gregorian ( y, m, d ) print ( ' COMPUTED: %s' % ( s ) ) return def easter_julian_egr ( y ): #*****************************************************************************80 # ## easter_julian_egr() computes the date of Easter in the Julian calendar. # # Discussion: # # This computation for the date of Easter uses the Dionysian # canon that applied to the Julian calendar. The determination # of the date of Easter changed at the same time that the calendar # was modified to use the Gregorian system. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 January 2018 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm M, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 365. # # Input: # # integer Y, the year. # # Output: # # integer M, D, the month and day of the Julian # calendar on which Easter occurs. # if ( y <= 0 ): m = -1 d = -1 return m, d p = y + ( y // 4 ) + 4 n = 7 - ( p % 7 ) e = year_to_epact_julian ( y ) r = 22 + ( ( 53 - e ) % 30 ) c = i4_wrap ( r + 3, 1, 7 ) s = r + ( ( 7 + n - c ) % 7 ) m = 3 + ( s // 32 ) # # Use wrapping so that 1 <= D <= 31. # d = i4_wrap ( s, 1, 31 ) return m, d def easter_julian_egr_test ( ): #*****************************************************************************80 # ## easter_julian_egr_test() tests easter_julian_egr(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 January 2018 # # Author: # # John Burkardt # import numpy as np n_test = 10 d_test = np.array ( [ 27, 19, 11, 30, 15, 5, 27, 11, 1, 23 ] ) m_test = np.array ( [ 4, 4, 4, 4, 4, 5, 4, 4, 5, 4 ] ) y_test = np.array ( [ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ] ) print ( '' ) print ( 'easter_julian_egr_test():' ) print ( ' For the Julian calendar,' ) print ( ' for a given year, compute the day and month of Easter.' ) print ( ' easter_julian_egr uses Richards''s algorithm #1.' ) for i in range ( 0, n_test ): y = y_test[i] m = m_test[i] d = d_test[i] f = 0.5 print ( '' ) s = ymd_to_s_gregorian ( y, m, d ) print ( ' CORRECT (Gregorian): %s' % ( s ) ) jed = ymdf_to_jed_gregorian ( y, m, d, f ) y, m, d, f = jed_to_ymdf_julian ( jed ) s = ymd_to_s_julian ( y, m, d ) print ( ' CORRECT (Julian): %s' % ( s ) ) m, d = easter_julian_egr ( y ) s = ymd_to_s_julian ( y, m, d ) print ( ' COMPUTED %s' % ( s ) ) return def easter_julian_egr2 ( y ): #*****************************************************************************80 # ## easter_julian_egr2() computes the date of Easter in the Julian calendar. # # Discussion: # # This computation for the date of Easter uses the Dionysian # canon that applied to the Julian calendar. The determination # of the date of Easter changed at the same time that the calendar # was modified to use the Gregorian system. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 January 2018 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm N, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 365. # # Input: # # integer Y, the year. # # Output: # # integer M, D, the month and day of the Julian calendar # on which Easter occurs. # if ( y <= 0 ): m = -1 d = -1 return m, d a = year_to_golden_number ( y ) a = a - 1 b = 22 + ( ( 225 - 11 * a ) % 30 ) s = b + ( ( 56 + 6 * y - ( y // 4 ) - b ) % 7 ) m = 3 + ( s // 32 ) # # Use wrapping to ensure that 1 <= D <= 31. # d = i4_wrap ( s, 1, 31 ) return m, d def easter_julian_egr2_test ( ): #*****************************************************************************80 # ## easter_julian_egr2_test() tests easter_julian_egr2(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 January 2018 # # Author: # # John Burkardt # import numpy as np n_test = 10 d_test = np.array ( [ 27, 19, 11, 30, 15, 5, 27, 11, 1, 23 ] ) m_test = np.array ( [ 4, 4, 4, 4, 4, 5, 4, 4, 5, 4 ] ) y_test = np.array ( [ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ] ) print ( '' ) print ( 'easter_julian_egr2_test():' ) print ( ' For the Julian calendar,' ) print ( ' for a given year, compute the day and month of Easter.' ) print ( ' easter_julian_egr2 uses Richards''s algorithm #2.' ) for i in range ( 0, n_test ): y = y_test[i] m = m_test[i] d = d_test[i] f = 0.5 print ( '' ) s = ymd_to_s_gregorian ( y, m, d ) print ( ' CORRECT (Gregorian): %s' % ( s ) ) jed = ymdf_to_jed_gregorian ( y, m, d, f ) y, m, d, f = jed_to_ymdf_julian ( jed ) s = ymd_to_s_julian ( y, m, d ) print ( ' CORRECT (Julian): %s' % ( s ) ) m, d = easter_julian_egr2 ( y ) s = ymd_to_s_julian ( y, m, d ) print ( ' COMPUTED %s' % ( s ) ) return def epoch_to_jed_akbar ( ): #*****************************************************************************80 # ## epoch_to_jed_akbar(): epoch of the Akbar calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 2289425.5 return jed def epoch_to_jed_alexandrian ( ): #*****************************************************************************80 # ## epoch_to_jed_alexandrian(): epoch of the Alexandrian calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1713262.5 return jed def epoch_to_jed_armenian ( ): #*****************************************************************************80 # ## epoch_to_jed_armenian(): epoch of the Armenian calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1922867.5 return jed def epoch_to_jed_bahai ( ): #*****************************************************************************80 # ## epoch_to_jed_bahai(): epoch of the Bahai calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 2394646.5 return jed def epoch_to_jed_bessel ( ): #*****************************************************************************80 # ## epoch_to_jed_bessel(): epoch of the Bessel calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 2415020.31352 return jed def epoch_to_jed_byzantine ( ): #*****************************************************************************80 # ## epoch_to_jed_byzantine(): epoch of the Byzantine calendar as a JED. # # Discussion: # # The Byzantine calendar has the epoch 1 September 5509 BC. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 12 March 2021 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = -290495.5 return jed def epoch_to_jed_chinese ( ): #*****************************************************************************80 # ## epoch_to_jed_chinese(): epoch of the Chinese calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 758325.5 return jed def epoch_to_jed_common ( ): #*****************************************************************************80 # ## epoch_to_jed_common()(): epoch of the Common calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1721423.5 return jed def epoch_to_jed_coptic ( ): #*****************************************************************************80 # ## epoch_to_jed_coptic(): epoch of the Coptic calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1825029.5 return jed def epoch_to_jed_datenum ( ): #*****************************************************************************80 # ## epoch_to_jed_datenum(): epoch of the MATLAB DATENUM calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1721058.5 return jed def epoch_to_jed_deccan ( ): #*****************************************************************************80 # ## epoch_to_jed_deccan(): epoch of the Fasli Deccan calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1936747.5 return jed def epoch_to_jed_eg_civil ( ): #*****************************************************************************80 # ## epoch_to_jed_eg_civil(): epoch of the Egyptian Civil calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1448637.5 return jed def epoch_to_jed_eg_lunar ( ): #*****************************************************************************80 # ## epoch_to_jed_eg_lunar(): epoch of the Egyptian Lunar calendar as a JED. # # Discussion: # # This is just a fake value, making the Egyptian Lunar calendar start # at the same data as the Egyptian Civil calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1448637.5 return jed def epoch_to_jed_english ( ): #*****************************************************************************80 # ## epoch_to_jed_english(): epoch of the English calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1721423.5 return jed def epoch_to_jed_ethiopian ( ): #*****************************************************************************80 # ## epoch_to_jed_ethiopian(): epoch of the Ethiopian calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1724220.5 return jed def epoch_to_jed_gps ( ): #*****************************************************************************80 # ## epoch_to_jed_gps(): epoch of the GPS calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 2444244.5 return jed def epoch_to_jed_greek ( ): #*****************************************************************************80 # ## epoch_to_jed_greek(): epoch of the Greek calendar as a JED. # # Discussion: # # The Greek Olympiad calendar began on 9 July 776 BC. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1438178.5 return jed def epoch_to_jed_gregorian ( ): #*****************************************************************************80 # ## epoch_to_jed_gregorian(): epoch of the Gregorian calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1721425.5 return jed def epoch_to_jed_hebrew ( ): #*****************************************************************************80 # ## epoch_to_jed_hebrew(): epoch of the Hebrew calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 347998.5 return jed def epoch_to_jed_hindu_lunar ( ): #*****************************************************************************80 # ## epoch_to_jed_hindu_lunar(): epoch of the Hindu lunar calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1741959.5 return jed def epoch_to_jed_hindu_solar ( ): #*****************************************************************************80 # ## epoch_to_jed_hindu_solar(): epoch of the Hindu solar calendar as a JED. # # Discussion: # # This is the beginning of the Kali Yuga era. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 588465.75 return jed def epoch_to_jed_islamic_a ( ): #*****************************************************************************80 # ## epoch_to_jed_islamic_a(): epoch of the Islamic A calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1948438.5 return jed def epoch_to_jed_islamic_b ( ): #*****************************************************************************80 # ## epoch_to_jed_islamic_b(): epoch of the Islamic B calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1948439.5 return jed def epoch_to_jed_jed ( ): #*****************************************************************************80 # ## epoch_to_jed_jed(): epoch of the JED as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 0.0 return jed def epoch_to_jed_jelali ( ): #*****************************************************************************80 # ## epoch_to_jed_jelali(): epoch of the Jelali calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 2114872.5 return jed def epoch_to_jed_julian ( ): #*****************************************************************************80 # ## epoch_to_jed_julian(): epoch of the Julian calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1721423.5 return jed def epoch_to_jed_khwarizmian ( ): #*****************************************************************************80 # ## epoch_to_jed_khwarizmian(): epoch of the Khwarizmian calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1952067.5 return jed def epoch_to_jed_macedonian ( ): #*****************************************************************************80 # ## epoch_to_jed_macedonian(): epoch of the Macedonian calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1607708.5 return jed def epoch_to_jed_mayan_long ( ): #*****************************************************************************80 # ## epoch_to_jed_mayan_long(): epoch of the Mayan long count calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 584282.5 return jed def epoch_to_jed_mjd ( ): #*****************************************************************************80 # ## epoch_to_jed_mjd(): epoch of the MJD calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 2400000.5 return jed def epoch_to_jed_nyt ( ): #*****************************************************************************80 # ## epoch_to_jed_nyt(): epoch of the NYT calendar as a JED. # # Discussion: # # The "epoch" of the NYT calendar is the mythical date when issue "0" # would have been printed, namely, a tad past midnight, 17 September 1851. # # Volume #1, Issue #1 was printed on 18 September 1851. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 2397382.5 return jed def epoch_to_jed_nyt_50000 ( ): #*****************************************************************************80 # ## epoch_to_jed_nyt_50000(): epoch of the NYT_50000 calendar as a JED. # # Discussion: # # The "epoch" of the NYT_50000 calendar is the date when issue "50,000" # was printed. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 2449790.5 return jed def epoch_to_jed_persian ( ): #*****************************************************************************80 # ## epoch_to_jed_persian(): epoch of the Persian calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1952062.5 return jed def epoch_to_jed_persian_solar ( ): #*****************************************************************************80 # ## epoch_to_jed_persian_solar(): epoch of the Persian solar calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1948320.5 return jed def epoch_to_jed_rd ( ): #*****************************************************************************80 # ## epoch_to_jed_rd(): epoch of the RD calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1721425.5 return jed def epoch_to_jed_republican ( ): #*****************************************************************************80 # ## epoch_to_jed_republican(): epoch of the Republican calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 2375839.5 return jed def epoch_to_jed_roman ( ): #*****************************************************************************80 # ## epoch_to_jed_roman(): epoch of the Roman calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1446389.5 return jed def epoch_to_jed_saka ( ): #*****************************************************************************80 # ## epoch_to_jed_saka(): epoch of the Saka calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1749994.5 return jed def epoch_to_jed_soor_san ( ): #*****************************************************************************80 # ## epoch_to_jed_soor_san(): epoch of the Fasli Soor San calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1940351.5 return jed def epoch_to_jed_syrian ( ): #*****************************************************************************80 # ## epoch_to_jed_syrian(): epoch of the Syrian calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1607738.5 return jed def epoch_to_jed_unix ( ): #*****************************************************************************80 # ## epoch_to_jed_unix(): epoch of the UNIX calendar as a JED. # # Discussion: # # The UNIX Epoch is taken to be the first second of 1 January 1970. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 2440587.50 return jed def epoch_to_jed_y2k ( ): #*****************************************************************************80 # ## epoch_to_jed_y2k(): epoch of the Y2K calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 2451544.5 return jed def epoch_to_jed_zoroastrian ( ): #*****************************************************************************80 # ## epoch_to_jed_zoroastrian(): epoch of the Zoroastrian calendar as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the epoch. # jed = 1862836.5 return jed def frac_borrow_common ( y, m, d, f ): #*****************************************************************************80 # ## frac_borrow_common() borrows fractions from days in a Common YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 20 July 2022 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after borrowing. # while ( f < 0.0 ): f = f + 1.0 d = d - 1 y, m, d = day_borrow_common ( y, m, d ) return y, m, d, f def frac_borrow_english ( y, m, d, f ): #*****************************************************************************80 # ## frac_borrow_english() borrows fractions from days in an English YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after borrowing. # while ( f < 0.0 ): f = f + 1.0 d = d - 1 y, m, d = day_borrow_english ( y, m, d ) return y, m, d, f def frac_borrow_gregorian ( y, m, d, f ): #*****************************************************************************80 # ## frac_borrow_gregorian() borrows fractions from days in a Gregorian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after borrowing. # while ( f < 0.0 ): f = f + 1.0 d = d - 1 y, m, d = day_borrow_gregorian ( y, m, d ) return y, m, d, f def frac_borrow_hebrew ( y, m, d, f ): #*****************************************************************************80 # ## frac_borrow_hebrew() borrows fractions from days in a Hebrew YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after borrowing. # while ( f < 0.0 ): f = f + 1.0 d = d - 1 y, m, d = day_borrow_hebrew ( y, m, d ) return y, m, d, f def frac_borrow_islamic ( y, m, d, f ): #*****************************************************************************80 # ## frac_borrow_islamic() borrows fractions from days in an Islamic YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after borrowing. # while ( f < 0.0 ): f = f + 1.0 d = d - 1 y, m, d = day_borrow_islamic ( y, m, d ) return y, m, d, f def frac_borrow_julian ( y, m, d, f ): #*****************************************************************************80 # ## frac_borrow_julian() borrows fractions from days in a Julian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after borrowing. # while ( f < 0.0 ): f = f + 1.0 d = d - 1 y, m, d = day_borrow_julian ( y, m, d ) return y, m, d, f def frac_borrow_republican ( y, m, d, f ): #*****************************************************************************80 # ## frac_borrow_republican() borrows fractions from days in a Republican YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after borrowing. # while ( f < 0.0 ): f = f + 1.0 d = d - 1 y, m, d = day_borrow_republican ( y, m, d ) return y, m, d, f def frac_borrow_roman ( y, m, d, f ): #*****************************************************************************80 # ## frac_borrow_roman() borrows fractions from days in a Roman YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after borrowing. # while ( f < 0.0 ): f = f + 1.0 d = d - 1 y, m, d = day_borrow_roman ( y, m, d ) return y, m, d, f def frac_carry_common ( y, m, d, f ): #*****************************************************************************80 # ## frac_carry_common() carries fractions to days in a Common YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 20 July 2022 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after carrying. # if ( f < 1.0 ): return y, m, d, f days = np.floor ( f ) f = f - days d = d + days y, m, d = day_carry_common ( y, m, d ) return y, m, d, f def frac_carry_english ( y, m, d, f ): #*****************************************************************************80 # ## frac_carry_english() carries fractions to days in an English YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after carrying. # from math import floor if ( f < 1.0 ): return y, m, d, f days = floor ( f ) f = f - days d = d + days y, m, d = day_carry_english ( y, m, d ) return y, m, d, f def frac_carry_gregorian ( y, m, d, f ): #*****************************************************************************80 # ## frac_carry_gregorian() carries fractions from days in a Gregorian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after carrying. # from math import floor if ( f < 1.0 ): return y, m, d, f days = floor ( f ) f = f - days d = d + days y, m, d = day_carry_gregorian ( y, m, d ) return y, m, d, f def frac_carry_hebrew ( y, m, d, f ): #*****************************************************************************80 # ## frac_carry_hebrew() carries fractions from days in a Hebrew YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after carrying. # from math import floor if ( f < 1.0 ): return y, m, d, f days = floor ( f ) f = f - days d = d + days y, m, d = day_carry_hebrew ( y, m, d ) return y, m, d, f def frac_carry_islamic ( y, m, d, f ): #*****************************************************************************80 # ## frac_carry_islamic() carries fractions from days in an Islamic YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after carrying. # from math import floor if ( f < 1.0 ): return y, m, d, f days = floor ( f ) f = f - days d = d + days y, m, d = day_carry_islamic ( y, m, d ) return y, m, d, f def frac_carry_julian ( y, m, d, f ): #*****************************************************************************80 # ## frac_carry_julian() carries fractions from days in a Julian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after carrying. # from math import floor if ( f < 1.0 ): return y, m, d, f days = floor ( f ) f = f - days d = d + days y, m, d = day_carry_julian ( y, m, d ) return y, m, d, f def frac_carry_republican ( y, m, d, f ): #*****************************************************************************80 # ## frac_carry_republican() carries fractions from days in a Republican YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after carrying. # from math import floor if ( f < 1.0 ): return y, m, d, f days = floor ( f ) f = f - days d = d + days y, m, d = day_carry_republican ( y, m, d ) return y, m, d, f def frac_carry_roman ( y, m, d, f ): #*****************************************************************************80 # ## frac_carry_roman() carries fractions to days in a Roman YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date after carrying. # from math import floor if ( f < 1.0 ): return y, m, d, f days = floor ( f ) f = f - days d = d + days y, m, d = day_carry_roman ( y, m, d ) return y, m, d, f def frac_to_hms ( f ): #*****************************************************************************80 # ## frac_to_hms() converts a fractional day into hours, minutes, seconds. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # real F, a day fraction between 0.0 and 1.0. # # Output: # # integer H, M, S, the equivalent hours, minutes and seconds. # from math import floor f2 = f f2 = 24.0 * f2 h = floor ( f2 ) f2 = f2 - h f2 = 60.0 * f2 m = floor ( f2 ) f2 = f2 - m f2 = 60.0 * f2 s = floor ( f2 ) f2 = f2 - s return h, m, s def frac_to_s ( f ): #*****************************************************************************80 # ## frac_to_s() writes a positive fraction into a left justified character string. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # real F, the number to be written into the string. # F should be between 0.0 and 1.0. # # Output: # # string S, a representation of F. # if ( f < 0.0 ): print ( '' ) print ( 'frac_to_s(): Fatal error!' ) print ( ' The input fraction F = ', f, ' was negative.' ) raise Exception ( 'frac_to_s(): Fatal error!' ) if ( 1.0 <= f ): print ( '' ) print ( 'frac_to_s(): Fatal error!' ) print ( ' The input fraction F = ', f, ' was 1 or more:' ) raise Exception ( 'frac_to_s(): Fatal error!' ) s = ( '%f' % ( f ) ) return s def gps_to_jed ( c, w, s ): #*****************************************************************************80 # ## gps_to_jed() converts a GPS date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 17 December 2017 # # Author: # # John Burkardt # # Input: # # integer C, integer W, real S, # the GPS cycle/week/second date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # jed_epoch = epoch_to_jed_gps ( ) d = float ( 7 * ( 1024 * c + w ) ) + s / ( 24.0 * 60.0 * 60.0 ) jed = jed_epoch + d return jed def gps_to_jed_test ( ): #*****************************************************************************80 # ## gps_to_jed_test() tests gps_to_jed(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 15 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'gps_to_jed_test()' ) print ( ' gps_to_jed(): GPS => JED' ) print ( '' ) print ( ' JED (in) GPS (C/W/S) JED (out)' ) print ( '' ) jed_epoch = epoch_to_jed_gps ( ) i = 0 while ( True ): i = i + 1 jed1 = jed_test ( i ) if ( jed1 < 0.0 ): break if ( jed_epoch <= jed1 ): c2, w2, sec2 = jed_to_gps ( jed1 ) jed3 = gps_to_jed ( c2, w2, sec2 ) print ( ' %11.2f %d/%d/%9.2f GPS %11.2f' % ( jed1, c2, w2, sec2, jed3 ) ) return def hms_to_s ( h, n, second ): #*****************************************************************************80 # ## hms_to_s() "prints" an HMS date into a string. # # Format: # # HH:MM:SS # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer H, N, SECOND, the HMS date. # # Output: # # string S, contains a representation of the date. # s = ( '%02d:%02d:%02d' % ( h, n, second ) ) return s def hour_borrow_common ( y, m, d, h ): #*****************************************************************************80 # ## hour_borrow_common() "borrows" a day of hours. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, H, the year, month, day # and hour of the date. The value of H is presumably negative, and # so hours will be "borrowed" to make H positive. # # Output: # # integer Y, M, D, H, the year, month, day # and hour of the date after borrowing. # while ( h <= 0 ): h = h + 24 d = d - 1 y, m, d = day_borrow_common ( y, m, d ) return y, m, d, h def hour_carry_common ( y, m, d, h ): #*****************************************************************************80 # ## hour_carry_common() is given a YMDH date, and carries hours to days. # # Algorithm: # # While 24 < H: # # decrease H by the number of hours in a day; # increase D by 1; # if necessary, adjust M and Y. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, H, the year, month, day # and hour of the date. On H is presumably 24 or greater. # # Output: # # integer Y, M, D, H, the year, month, day # and hour of the date, after carrying. # while ( 24 < h ): h = h - 24 d = d + 1 y, m, d = day_carry_common ( y, m, d ) return y, m, d, h def i4_modp ( i, j ): #*****************************************************************************80 # ## i4_modp() returns the nonnegative remainder of I4 division. # # Discussion: # # If # NREM = i4_modp ( I, J ) # NMULT = ( I - NREM ) / J # then # I = J * NMULT + NREM # where NREM is always nonnegative. # # The MOD function computes a result with the same sign as the # quantity being divided. Thus, suppose you had an angle A, # and you wanted to ensure that it was between 0 and 360. # Then mod(A,360) would do, if A was positive, but if A # was negative, your result would be between -360 and 0. # # On the other hand, i4_modp(A,360) is between 0 and 360, always. # # Example: # # I J MOD i4_modp Factorization # # 107 50 7 7 107 = 2 * 50 + 7 # 107 -50 7 7 107 = -2 * -50 + 7 # -107 50 -7 43 -107 = -3 * 50 + 43 # -107 -50 -7 43 -107 = 3 * -50 + 43 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 May 2013 # # Author: # # John Burkardt # # Input: # # integer I, the number to be divided. # # integer J, the number that divides I. # # Output: # # integer VALUE, the nonnegative remainder when I is divided by J. # if ( j == 0 ): print ( '' ) print ( 'i4_modp(): Fatal error!' ) print ( ' Illegal divisor J = ', j ) raise Exception ( 'i4_modp(): Fatal error!' ) value = ( i % j ) if ( value < 0 ): value = value + abs ( j ) return value def i4_modp_test ( ): #*****************************************************************************80 # ## i4_modp_test() tests i4_modp(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 28 September 2014 # # Author: # # John Burkardt # import numpy as np test_num = 4 n_vec = np.array ( ( 107, 107, -107, -107 ) ) d_vec = np.array ( ( 50, -50, 50, -50 ) ) print ( '' ) print ( 'i4_modp_test():' ) print ( ' i4_modp() factors a number' ) print ( ' into a multiple M and a positive remainder R.' ) print ( '' ) print ( ' Number Divisor Multiple Remainder' ) print ( '' ) for test in range ( 0, test_num ): n = n_vec[test] d = d_vec[test] r = i4_modp ( n, d ) m = ( n - r ) // d print ( ' %8d %8d %8d %8d' % ( n, d, m, r ) ) print ( '' ) print ( ' Repeat using Python % Operator:' ) print ( '' ) for test in range ( 0, test_num ): n = n_vec[test] d = d_vec[test] m = n // d r = n % d print ( ' %8d %8d %8d %8d' % ( n, d, m, r ) ) return def i4_normal_ab ( mu, sigma ): #*****************************************************************************80 # ## i4_normal_ab() returns a scaled pseudonormal I4. # # Discussion: # # The normal probability distribution function (PDF) is sampled, # with mean MU and standard deviation SIGMA. # # The result is rounded to the nearest integer. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 March 2015 # # Author: # # John Burkardt # # Input: # # real MU, the mean of the PDF. # # real SIGMA, the standard deviation of the PDF. # # Output: # # integer VALUE, a normally distributed random value. # from numpy.random import default_rng import numpy as np rng = default_rng ( ) r1 = rng.random ( ) r2 = rng.random ( ) value = np.sqrt ( - 2.0 * np.log ( r1 ) ) * np.cos ( 2.0 * np.pi * r2 ) value = int ( mu + sigma * value ) return value def i4_normal_ab_test ( ): #*****************************************************************************80 # ## i4_normal_ab_test() tests i4_normal_ab(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 March 2015 # # Author: # # John Burkardt # print ( '' ) print ( 'i4_normal_ab_test():' ) print ( ' i4_normal_ab() computes integer pseudonormal values with' ) print ( ' mean MU and standard deviation SIGMA.' ) mu = 10.0 sigma = 2.0 print ( '' ) print ( ' MU = %g' % ( mu ) ) print ( ' SIGMA = %g' % ( sigma ) ) print ( '' ) for i in range ( 0, 10 ): r = i4_normal_ab ( mu, sigma ) print ( ' %2d %12d' % ( i, r ) ) return def i4_to_a ( i ): #*****************************************************************************80 # ## i4_to_a() returns the I-th alphabetic character. # # Example: # # I A # # -8 ' ' # 0 ' ' # 1 'A' # 2 'B' # .. # 26 'Z' # 27 'a' # 52 'z' # 53 ' ' # 99 ' ' # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer I, the index of the letter to be returned. # 0 is a space; # 1 through 26 requests 'A' through 'Z', (ASCII 65:90); # 27 through 52 requests 'a' through 'z', (ASCII 97:122); # # Output: # # character A, the requested alphabetic letter. # if ( i <= 0 ): a = ' ' elif ( 1 <= i and i <= 26 ): a = chr ( ord ( 'A' ) + i - 1 ) elif ( 27 <= i and i <= 52 ): a = chr ( ord ( 'a' ) + i - 27 ) else: a = ' ' return a def i4_to_roman ( i ): #*****************************************************************************80 # ## i4_to_roman() converts an integer to a string of Roman numerals. # # Example: # # I S # # -2 -II <-- Not a Roman numeral # -1 -I <-- Not a Roman numeral # 0 0 <-- Not a Roman numeral # 1 I # 2 II # 3 III # 4 IV # 5 V # 10 X # 20 XX # 30 XXX # 40 XL # 50 L # 60 LX # 70 LXX # 80 LXXX # 90 XC # 100 C # 500 D # 1000 M # 4999 MMMMCMLXLIX # # Discussion: # # To generate numbers greater than 4999, the numeral 'V' had a bar # above it, representing a value of 5000, a barred 'X' represented # 10,000 and so on. # # In the subtractive representation of 4 by 'IV', 9 by 'IX' and so on, # 'I' can only subtract from 'V' or 'X', # 'X' can only subtract from 'L' or 'C', # 'C' can only subtract from 'D' or 'M'. # Under these rules, 1999 cannot be written IMM! # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer I, an integer to be converted. If the integer # has absolute value greater than 4999, the string '?' will be returned. # If the integer is 0, then the string '0' will be returned. If # the integer is negative, then a minus sign will precede it, even # though this has nothing to do with Roman numerals. # # Output: # # string S, the representation of the integer as a Roman numeral. # s = '' if ( 4999 < abs ( i ) ): s = '?' return s if ( i == 0 ): s = '0' return s if ( i <= 0 ): s = '-' i = -i while ( 0 < i ) : if ( 1000 <= i ): s = s + 'M' i = i - 1000 elif ( 900 <= i ): s = s + 'CM' i = i - 900 elif ( 500 <= i ): s = s + 'D' i = i - 500 elif ( 400 <= i ): s = s + 'CD' i = i - 400 elif ( 100 <= i ): s = s + 'C' i = i - 100 elif ( 90 <= i ): s = s + 'XC' i = i - 90 elif ( 50 <= i ): s = s + 'L' i = i - 50 elif ( 40 <= i ): s = s + 'XL' i = i - 40 elif ( 10 <= i ): s = s + 'X' i = i - 10 elif ( 9 <= i ): s = s + 'IX' i = i - 9 elif ( 5 <= i ): s = s + 'V' i = i - 5 elif ( 4 <= i ): s = s + 'IV' i = i - 4 else: s = s + 'I' i = i - 1 return s def i4_wrap ( ival, ilo, ihi ): #*****************************************************************************80 # ## i4_wrap() forces an integer to lie between given limits by wrapping. # # Example: # # ILO = 4, IHI = 8 # # I Value # # -2 8 # -1 4 # 0 5 # 1 6 # 2 7 # 3 8 # 4 4 # 5 5 # 6 6 # 7 7 # 8 8 # 9 4 # 10 5 # 11 6 # 12 7 # 13 8 # 14 4 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 May 2013 # # Author: # # John Burkardt # # Input: # # integer IVAL, an integer value. # # integer ILO, IHI, the desired bounds for the integer value. # # Output: # # integer VALUE, a "wrapped" version of IVAL. # jlo = min ( ilo, ihi ) jhi = max ( ilo, ihi ) wide = jhi - jlo + 1 if ( wide == 1 ): value = jlo else: value = jlo + i4_modp ( ival - jlo, wide ) return value def i4_wrap_test ( ): #*****************************************************************************80 # ## i4_wrap_test() tests i4_wrap(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 May 2013 # # Author: # # John Burkardt # ilo = 4 ihi = 8 print ( '' ) print ( 'i4_wrap_test():' ) print ( ' i4_wrap() forces an integer to lie within given limits.' ) print ( '' ) print ( ' ILO = %d' % ( ilo ) ) print ( ' IHI = %d' % ( ihi ) ) print ( '' ) print ( ' I i4_wrap(I)' ) print ( '' ) for i in range ( -10, 21 ): j = i4_wrap ( i, ilo, ihi ) print ( ' %6d %6d' % ( i, j ) ) return def inflate_common ( y, m, d ): #*****************************************************************************80 # ## inflate_common() "inflates" dates in the Common Calendar transition month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the inflated YMD date. # if ( y == 1582 ): if ( m == 10 ): if ( 5 <= d ): d = d + 10 return y, m, d def inflate_english ( y, m, d ): #*****************************************************************************80 # ## inflate_english() "inflates" dates in the English Calendar transition month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after inflation. # if ( y == 1752 ): if ( m == 9 ): if ( 3 <= d ): d = d + 11 return y, m, d def j_borrow_common ( y, j ): #*****************************************************************************80 # ## j_borrow_common() borrows year-days from years in a Common date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after borrowing. # while ( j <= 0 ): y = y - 1 days = year_length_days_common ( y ) j = j + days return y, j def j_borrow_english ( y, j ): #*****************************************************************************80 # ## j_borrow_english() borrows year-days from years in an English date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after borrowing. # while ( j <= 0 ): y = y - 1 days = year_length_days_english ( y ) j = j + days return y, j def j_borrow_gregorian ( y, j ): #*****************************************************************************80 # ## j_borrow_gregorian() borrows year-days from years in a Gregorian date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after borrowing. # while ( j <= 0 ): y = y - 1 days = year_length_days_gregorian ( y ) j = j + days return y, j def j_borrow_hebrew ( y, j ): #*****************************************************************************80 # ## j_borrow_hebrew() borrows year-days from years in a Hebrew date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after borrowing. # while ( j <= 0 ): y = y - 1 days = year_length_days_hebrew ( y ) j = j + days return y, j def j_borrow_islamic ( y, j ): #*****************************************************************************80 # ## j_borrow_islamic() borrows year-days from years in an Islamic date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after borrowing. # while ( j <= 0 ): y = y - 1 days = year_length_days_islamic ( y ) j = j + days return y, j def j_borrow_julian ( y, j ): #*****************************************************************************80 # ## j_borrow_julian() borrows year-days from years in a Julian date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after borrowing. # while ( j <= 0 ): y = y - 1 days = year_length_days_julian ( y ) j = j + days return y, j def j_borrow_republican ( y, j ): #*****************************************************************************80 # ## j_borrow_republican() borrows year-days from years in a Republican date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after borrowing. # while ( j <= 0 ): y = y - 1 days = year_length_days_republican ( y ) j = j + days return y, j def j_borrow_roman ( y, j ): #*****************************************************************************80 # ## j_borrow_roman() borrows year-days from years in a Roman date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after borrowing. # while ( j <= 0 ): y = y - 1 days = year_length_days_roman ( y ) j = j + days return y, j def j_carry_common ( y, j ): #*****************************************************************************80 # ## j_carry_common() carries year-days to years in a Common date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after carrying. # while ( True ): days = year_length_days_common ( y ) if ( j < days ): break j = j - days y = y + 1 return y, j def j_carry_english ( y, j ): #*****************************************************************************80 # ## j_carry_english() carries year-days to years in an English date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after carrying. # while ( True ): days = year_length_days_english ( y ) if ( j < days ): break j = j - days y = y + 1 return y, j def j_carry_gregorian ( y, j ): #*****************************************************************************80 # ## j_carry_gregorian() carries year-days to years in a Gregorian date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after carrying. # while ( True ): days = year_length_days_gregorian ( y ) if ( j < days ): break j = j - days y = y + 1 return y, j def j_carry_hebrew ( y, j ): #*****************************************************************************80 # ## j_carry_hebrew() carries year-days to years in a Hebrew date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after carrying. # while ( True ): days = year_length_days_hebrew ( y ) if ( j < days ): break j = j - days y = y + 1 return y, j def j_carry_islamic ( y, j ): #*****************************************************************************80 # ## j_carry_islamic() carries year-days to years in an Islamic date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after carrying. # while ( True ): days = year_length_days_islamic ( y ) if ( j < days ): break j = j - days y = y + 1 return y, j def j_carry_julian ( y, j ): #*****************************************************************************80 # ## j_carry_julian() carries year-days to years in a Julian date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after carrying. # while ( True ): days = year_length_days_julian ( y ) if ( j < days ): break j = j - days y = y + 1 return y, j def j_carry_republican ( y, j ): #*****************************************************************************80 # ## j_carry_republican() carries year-days to years in a Republican date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after carrying. # while ( True ): days = year_length_days_republican ( y ) if ( j < days ): break j = j - days y = y + 1 return y, j def j_carry_roman ( y, j ): #*****************************************************************************80 # ## j_carry_roman() carries year-days to years in a Roman date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date after carrying. # while ( True ): days = year_length_days_roman ( y ) if ( j < days ): break j = j - days y = y + 1 return y, j def jed_ce_values ( n_data ): #*****************************************************************************80 # ## jed_ce_values() returns the Common Era dates for Julian Ephemeris Dates. # # Discussion: # # The JED (Julian Ephemeris Date) is a calendrical system which counts days, # starting from noon on 1 January 4713 BCE. # # The CE or Common Era is the day, month and year under the # hybrid Julian/Gregorian Calendar, with a transition from Julian # to Gregorian. The day after 04 October 1582 was 15 October 1582. # # The year before 1 AD or CE is 1 BC or BCE. In this data set, # years BC/BCE are indicated by a negative year value. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 16 February 2015 # # Author: # # John Burkardt # # Reference: # # Edward Reingold and Nachum Dershowitz, # Calendrical Calculations: The Millennium Edition, # Cambridge University Press, 2001, # ISBN: 0 521 77752 6 # # Input: # # integer N_DATA. The user sets N_DATA to 0 before the first call. # # Output: # # integer N_DATA. On each call, the routine increments N_DATA by 1, # and returns the corresponding data; when there is no more data, the # output value of N_DATA will be 0 again. # real JED, the Julian Ephemeris Date. # # integer Y, M, D, the Common Era date. # # real F, the fractional part of the day. # import numpy as np n_max = 51 d_vec = np.array ( ( \ 1, \ 2, \ 26, \ 8, \ 6, \ 18, \ 8, \ 9, \ 1, \ 26, \ 26, \ 1, \ 1, \ 29, \ 31, \ 1, \ 3, \ 3, \ 29, \ 24, \ 24, \ 29, \ 3, \ 11, \ 12, \ 24, \ 19, \ 15, \ 16, \ 16, \ 21, \ 17, \ 9, \ 4, \ 15, \ 4, \ 13, \ 14, \ 18, \ 22, \ 21, \ 24, \ 17, \ 31, \ 1, \ 6, \ 25, \ 1, \ 9, \ 23, \ 1 )) f_vec = np.array ( ( \ 0.50, \ 0.50, \ 0.50, \ 0.00, \ 0.00, \ 0.25, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.50, \ 0.50, \ 0.00, \ 0.50, \ 0.50, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.81, \ 0.00, \ 0.00, \ 0.00, \ 0.00, \ 0.33, \ 0.00, \ 0.50 )) jed_vec = np.array ( ( \ 0.00, \ 1.00, \ 259261.00, \ 347998.50, \ 584282.50, \ 588465.75, \ 758325.50, \ 1438178.50, \ 1446389.50, \ 1448637.50, \ 1448637.50, \ 1607708.50, \ 1607738.50, \ 1713262.50, \ 1721422.50, \ 1721423.50, \ 1721425.50, \ 1721425.50, \ 1724220.50, \ 1741959.50, \ 1749994.50, \ 1825029.50, \ 1862836.50, \ 1922867.50, \ 1936747.50, \ 1940351.50, \ 1948320.50, \ 1948438.50, \ 1948439.50, \ 1952062.50, \ 1952067.50, \ 2114872.50, \ 2289425.50, \ 2299160.00, \ 2299161.00, \ 2333269.50, \ 2361221.00, \ 2361222.00, \ 2372547.50, \ 2375839.50, \ 2394646.50, \ 2394710.50, \ 2400000.50, \ 2415020.31, \ 2440587.50, \ 2444244.50, \ 2450138.50, \ 2451544.50, \ 2453073.83, \ 2456284.50, \ 2913943.00 )) m_vec = np.array ( ( \ 1, \ 1, \ 10, \ 10, \ 9, \ 2, \ 3, \ 7, \ 1, \ 2, \ 2, \ 9, \ 10, \ 8, \ 12, \ 1, \ 1, \ 1, \ 8, \ 3, \ 3, \ 8, \ 3, \ 7, \ 7, \ 5, \ 3, \ 7, \ 7, \ 6, \ 6, \ 3, \ 2, \ 10, \ 10, \ 3, \ 9, \ 9, \ 9, \ 9, \ 3, \ 5, \ 11, \ 12, \ 1, \ 1, \ 2, \ 1, \ 3, \ 12, \ 1 )) y_vec = np.array ( ( \ -4713, \ -4713, \ -4004, \ -3761, \ -3114, \ -3102, \ -2637, \ -776, \ -753, \ -747, \ -747, \ -312, \ -312, \ -23, \ -1, \ 1, \ 1, \ 1, \ 8, \ 57, \ 79, \ 284, \ 388, \ 552, \ 590, \ 600, \ 622, \ 622, \ 622, \ 632, \ 632, \ 1078, \ 1556, \ 1582, \ 1582, \ 1676, \ 1752, \ 1752, \ 1783, \ 1792, \ 1844, \ 1844, \ 1858, \ 1899, \ 1970, \ 1980, \ 1996, \ 2000, \ 2004, \ 2012, \ 3266 )) if ( n_data < 0 ): n_data = 0 if ( n_max <= n_data ): n_data = 0 jed = 0.0 y = 0 m = 0 d = 0 f = 0.0 else: jed = jed_vec[n_data] y = y_vec[n_data] m = m_vec[n_data] d = d_vec[n_data] f = f_vec[n_data] n_data = n_data + 1 return n_data, jed, y, m, d, f def jed_ce_values_test ( ): #*****************************************************************************80 # ## jed_ce_values_test() tests jed_ce_values(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 16 February 2015 # # Author: # # John Burkardt # print ( '' ) print ( 'jed_ce_values_test():' ) print ( ' jed_ce_values() stores of the YMDF CE calendar date for a given JED' ) print ( '' ) print ( ' JED Y M D F' ) print ( '' ) n_data = 0 while ( True ): n_data, jed, y, m, d, f = jed_ce_values ( n_data ) if ( n_data == 0 ): break print ( ' %12.1f %6d %6d %6d %12.2g' % ( jed, y, m, d, f ) ) return def jed_is_legal ( jed ): #*****************************************************************************80 # ## jed_is_legal() checks a Julian Ephemeris Date. # # Discussion: # # The routine returns an error if JED < 0, although there is no # reason why such dates are invalid. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 16 June 2012 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # logical VALUE, is TRUE if JED is legal, and FALSE otherwise. # if ( 0.0 <= jed ): value = True else: value = False return value def jed_is_legal_test ( ): #*****************************************************************************80 # ## jed_is_legal_test() tests jed_is_legal(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'jed_is_legal_test():' ) print ( ' jed_is_legal() returns TRUE if JED is a legal JED value' ) print ( '' ) print ( ' JED jed_is_legal' ) print ( '' ) for jed in [ -100, -1, 0, 1, 1.5, 100, 50000 ]: legal = jed_is_legal ( jed ) if ( legal ): print ( ' %12.1f True' % ( jed ) ) else: print ( ' %12.1f False' % ( jed ) ) return def jed_mjd_values ( n_data ): #*****************************************************************************80 # ## jed_mjd_values() returns the MJD for Julian Ephemeris Dates. # # Discussion: # # The JED (Julian Ephemeris Date) is a calendrical system which counts days, # starting from noon on 1 January 4713 BCE. # # The MJD (Modified Julian Day) counts days starting from midnight, # 17 November 1858. This essentially subtracts 2400000.5 days from the JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 16 February 2015 # # Author: # # John Burkardt # # Reference: # # Edward Reingold and Nachum Dershowitz, # Calendrical Calculations: The Millennium Edition, # Cambridge University Press, 2001, # ISBN: 0 521 77752 6 # # Input: # # integer N_DATA. The user sets N_DATA to 0 before the first call. # # Output: # # integer N_DATA. On each call, the routine increments N_DATA by 1, # and returns the corresponding data; when there is no more data, the # output value of N_DATA will be 0 again. # real JED, the Julian Ephemeris Date. # # real MJD, the Modified Julian Ephemeris Date. # import numpy as np n_max = 33 jed_vec = np.array ( ( \ 1507231.5E+00, \ 1660037.5E+00, \ 1746893.5E+00, \ 1770641.5E+00, \ 1892731.5E+00, \ 1931579.5E+00, \ 1974851.5E+00, \ 2091164.5E+00, \ 2121509.5E+00, \ 2155779.5E+00, \ 2174029.5E+00, \ 2191584.5E+00, \ 2195261.5E+00, \ 2229274.5E+00, \ 2245580.5E+00, \ 2266100.5E+00, \ 2288542.5E+00, \ 2290901.5E+00, \ 2323140.5E+00, \ 2334848.5E+00, \ 2348020.5E+00, \ 2366978.5E+00, \ 2385648.5E+00, \ 2392825.5E+00, \ 2416223.5E+00, \ 2425848.5E+00, \ 2430266.5E+00, \ 2430833.5E+00, \ 2431004.5E+00, \ 2448698.5E+00, \ 2450138.5E+00, \ 2465737.5E+00, \ 2486076.5E+00 )) mjd_vec = np.array ( ( \ -892769.0E+00, \ -739963.0E+00, \ -653107.0E+00, \ -629359.0E+00, \ -507269.0E+00, \ -468421.0E+00, \ -425149.0E+00, \ -308836.0E+00, \ -278491.0E+00, \ -244221.0E+00, \ -225971.0E+00, \ -208416.0E+00, \ -204739.0E+00, \ -170726.0E+00, \ -154420.0E+00, \ -133900.0E+00, \ -111458.0E+00, \ -109099.0E+00, \ -76860.0E+00, \ -65152.0E+00, \ -51980.0E+00, \ -33022.0E+00, \ -14352.0E+00, \ -7175.0E+00, \ 16223.0E+00, \ 25848.0E+00, \ 30266.0E+00, \ 30833.0E+00, \ 31004.0E+00, \ 48698.0E+00, \ 50138.0E+00, \ 65737.0E+00, \ 86076.0E+00 )) if ( n_data < 0 ): n_data = 0 if ( n_max <= n_data ): n_data = 0 jed = 0.0 mjd = 0.0 else: jed = jed_vec[n_data] mjd = mjd_vec[n_data] n_data = n_data + 1 return n_data, jed, mjd def jed_mjd_values_test ( ): #*****************************************************************************80 # ## jed_mjd_values_test() tests jed_mjd_values(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 16 February 2015 # # Author: # # John Burkardt # print ( '' ) print ( 'jed_mjd_values_test():' ) print ( ' jed_mjd_values() stores values of the Modified Julian Date.' ) print ( '' ) print ( ' JED MJD(JED)' ) print ( '' ) n_data = 0 while ( True ): n_data, jed, mjd = jed_mjd_values ( n_data ) if ( n_data == 0 ): break print ( ' %12f %24.16f' % ( jed, mjd ) ) return def jed_rd_values ( n_data ): #*****************************************************************************80 # ## jed_rd_values() returns the RD for Julian Ephemeris Dates. # # Discussion: # # The JED (Julian Ephemeris Date) is a calendrical system which counts days, # starting from noon on 1 January 4713 BCE. # # The RD is the Reingold Dershowitz Date, which counts days from # midnight, 1 January year 1 in the Gregorian calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 16 February 2015 # # Author: # # John Burkardt # # Reference: # # Edward Reingold and Nachum Dershowitz, # Calendrical Calculations: The Millennium Edition, # Cambridge University Press, 2001, # ISBN: 0 521 77752 6 # # Input: # # integer N_DATA. The user sets N_DATA to 0 before the first call. # # Output: # # integer N_DATA. On each call, the routine increments N_DATA by 1, # and returns the corresponding data; when there is no more data, the # output value of N_DATA will be 0 again. # real JED, the Julian Ephemeris Date. # # real RD, the Modified Julian Ephemeris Date. # import numpy as np n_max = 33 jed_vec = np.array ( ( \ 1507231.5E+00, \ 1660037.5E+00, \ 1746893.5E+00, \ 1770641.5E+00, \ 1892731.5E+00, \ 1931579.5E+00, \ 1974851.5E+00, \ 2091164.5E+00, \ 2121509.5E+00, \ 2155779.5E+00, \ 2174029.5E+00, \ 2191584.5E+00, \ 2195261.5E+00, \ 2229274.5E+00, \ 2245580.5E+00, \ 2266100.5E+00, \ 2288542.5E+00, \ 2290901.5E+00, \ 2323140.5E+00, \ 2334848.5E+00, \ 2348020.5E+00, \ 2366978.5E+00, \ 2385648.5E+00, \ 2392825.5E+00, \ 2416223.5E+00, \ 2425848.5E+00, \ 2430266.5E+00, \ 2430833.5E+00, \ 2431004.5E+00, \ 2448698.5E+00, \ 2450138.5E+00, \ 2465737.5E+00, \ 2486076.5E+00 )) rd_vec = np.array ( ( \ -214193.0E+00, \ -61387.0E+00, \ 25469.0E+00, \ 49217.0E+00, \ 171307.0E+00, \ 210155.0E+00, \ 253427.0E+00, \ 369740.0E+00, \ 400085.0E+00, \ 434355.0E+00, \ 452605.0E+00, \ 470160.0E+00, \ 473837.0E+00, \ 507850.0E+00, \ 524156.0E+00, \ 544676.0E+00, \ 567118.0E+00, \ 569477.0E+00, \ 601716.0E+00, \ 613424.0E+00, \ 626596.0E+00, \ 645554.0E+00, \ 664224.0E+00, \ 671401.0E+00, \ 694799.0E+00, \ 704424.0E+00, \ 708842.0E+00, \ 709409.0E+00, \ 709580.0E+00, \ 727274.0E+00, \ 728714.0E+00, \ 744313.0E+00, \ 764652.0E+00 )) if ( n_data < 0 ): n_data = 0 if ( n_max <= n_data ): n_data = 0 jed = 0.0 rd = 0.0 else: jed = jed_vec[n_data] rd = rd_vec[n_data] n_data = n_data + 1 return n_data, jed, rd def jed_rd_values_test ( ): #*****************************************************************************80 # ## jed_rd_values_test() tests jed_rd_values(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 16 February 2015 # # Author: # # John Burkardt # print ( '' ) print ( 'jed_rd_values_test():' ) print ( ' jed_rd_values() stores values of the Reingold Dershowitz Date.' ) print ( '' ) print ( ' JED RD(JED)' ) print ( '' ) n_data = 0 while ( True ): n_data, jed, rd = jed_rd_values ( n_data ) if ( n_data == 0 ): break print ( ' %12f %24.16f' % ( jed, rd ) ) return def jed_test ( i ): #*****************************************************************************80 # ## jed_test() returns some "interesting" JED's. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Reference: # # Bonnie Blackburn, Leofranc Holford-Stevens, # The Oxford Companion to the Year, # Oxford, 1999. # # Frank Parise, editor, # The Book of Calendars, # Facts on File, Inc, 1982, # CE11.K4 / 529.3. # # Edward Reingold, Nachum Dershowitz, # Calendrical Calculations, the Millennium Edition, # Cambridge, 2002, # CE12.R45 / 529.3-dc21 # # Edward Richards, # Mapping Time, The Calendar and Its History, # Oxford, 1999. # # Input: # # integer I, the test date requested. # # Output: # # real JED, the Julian Ephemeris Date. # If I is less than 1, or greater than the number of test dates # available, JED is returned as -1.0. # # # JED Epoch: # Beginning of current Scaliger cycle. # Monday, Noon, 1 January 4713 BCE/Julian # if ( i == 1 ): jed = 0.0 # # The day after the JED Epoch. # Tuesday, Noon, 2 January 4713 BCE/Julian # elif ( i == 2 ): jed = 1.0 # # Archbishop James Ussher's estimate of the date of Creation, # (Noon), 23 October 4004 BCE/Julian # elif ( i == 3 ): jed = 259258.000 # # Hebrew Epoch. # 7 October 3761 BCE/Julian # elif ( i == 4 ): jed = 347998.5 # # Mayan Long Count Epoch. # 6 September 3114 BCE/Julian # (Reingold and Dershowitz) # elif ( i == 5 ): jed = 584282.5 # # Hindu Solar Epoch. # Beginning of the Kali Yuga age. # 18 February 3102 BCE/Julian # elif ( i == 6 ): jed = 588465.75 # # Chinese Epoch. # 8 March 2637 BCE/Julian # elif ( i == 7 ): jed = 758325.5 # # Greek Olympiad Epoch # 9 July 776 BCE/Julian # elif ( i == 8 ): jed = 1438178.5 # # Roman Epoch # Ab Urbe Condita # 1 January 753 BCE/Julian # elif ( i == 9 ): jed = 1446389.5 # # Egyptian Civil Calendar Epoch. # Ascension of Nabonassar to throne of Babylon. # 26 February 747 BCE/Julian # elif ( i == 10 ): jed = 1448637.5 # # Egyptian Lunar Calendar Epoch. # (Don't really know where to set this...) # Ascension of Nabonassar to throne of Babylon. # 26 February 747 BCE/Julian # elif ( i == 11 ): jed = 1448637.5 # # Macedonian Epoch # 1 September 312 BCE/Julian # elif ( i == 12 ): jed = 1607708.5 # # Syrian Epoch # 1 October 312 BCE/Julian # elif ( i == 13 ): jed = 1607738.5 # # Alexandrian Epoch # 29 August 23 BCE/Julian # elif ( i == 14 ): jed = 1713262.5 # # "1 January, 0 BC"? DATENUM epoch. # elif ( i == 15 ): jed = 1721058.5 # # Julian Epoch MINUS ONE DAY # Friday, 31 December 1 BCE/Julian # elif ( i == 16 ): jed = 1721423.5 jed = jed - 1.0 # # Julian Epoch # Saturday, 1 January 1 CE/Julian # elif ( i == 17 ): jed = 1721423.5 # # Gregorian Epoch # Monday, 3 January 1 CE/Julian # Monday, 1 January 1 Gregorian # elif ( i == 18 ): jed = 1721425.5 # # RD: Reingold and Dershowitz Epoch # Monday, 3 January 1 CE/Julian # Monday, 1 January 1 Gregorian # elif ( i == 19 ): jed = 1721425.5 # # Ethiopian Epoch # 29 August 8 CE/Julian # (Reingold and Dershowitz) # elif ( i == 20 ): jed = 1724220.5 # # Hindu Lunar Epoch, the Vikrama # 24 March 57 CE/Julian # (The actual day and month are not specified by RD) # (Reingold and Dershowitz) # elif ( i == 21 ): jed = 1741959.5 # # Saka Epoch # 4 March 79 CE/Julian # elif ( i == 22 ): jed = 1749994.5 # # Coptic Epoch # 29 August 284 CE/Julian # elif ( i == 23 ): jed = 1825029.5 # # Zoroastrian Epoch. # 3 March 388 CE/Julian # elif ( i == 24 ): jed = 1862836.5 # # Armenian Epoch # 11 July 552 CE/Julian # elif ( i == 25 ): jed = 1922867.5 # # Fasli Deccan Epoch # 12 July 590 CE/Julian # elif ( i == 26 ): jed = 1936747.5 # # Fasli Soor San Epoch # 24 May 600 CE/Julian # elif ( i == 27 ): jed = 1940351.5 # # Persian Solar Epoch # 19 March 622 CE/Julian # elif ( i == 28 ): jed = 1948320.5 # # Islamic A Epoch # Thursday, 15 July 622 CE/Julian # elif ( i == 29 ): jed = 1948438.5 # # Islamic B Epoch # Friday, 16 July 622 CE/Julian # elif ( i == 30 ): jed = 1948439.5 # # Yazdegerd Epoch # 16 June 632 CE # elif ( i == 31 ): jed = 1952062.5 # # Khwarizmian Epoch # 21 June 632 CE/Julian # elif ( i == 32 ): jed = 1952067.5 # # Battle of Hastings. # Saturday, 14 October 1066 CE/Julian. # (20 October 1066 Gregorian.) # elif ( i == 33 ): jed = 2110700.5 # # Jelali Epoch # 17 March 1078 CE/Julian # elif ( i == 34 ): jed = 2114872.5 # # Akbar Epoch # 9 February 1556 CE/Julian # 19 February 1556 Gregorian # elif ( i == 35 ): jed = 2289425.5 # # Common Era calendar transition: # Noon of the last day of Julian calendar usage. # Thursday, 04 October 1582 CE/English/Julian # Thursday, 14 October 1582 Gregorian # elif ( i == 36 ): jed = 2299160.5 jed = jed - 0.5 # # Common Era calendar transition: # Noon of the first day of Gregorian calendar usage. # Friday, 05 October 1582 English/Julian # Friday, 15 October 1582 CE/Gregorian # elif ( i == 37 ): jed = 2299160.5 jed = jed + 0.5 # # A day chosen by Lewis Carroll to test his day-of-the-week algorithm, # Wednesday, 4 March 1676 CE/Gregorian # Wednesday, 23 February 1676 English/Julian # elif ( i == 38 ): jed = 2333269.5 # # English calendar # noon of the last day of Julian calendar usage. # 02 September 1752 English/Julian # 13 September 1752 CE/Gregorian # elif ( i == 39 ): jed = 2361221.5 jed = jed - 0.5 # # English calendar, # noon of the first day of Gregorian calendar usage. # 03 September 1752 Julian # 14 September 1752 CE/English/Gregorian # elif ( i == 40 ): jed = 2361221.5 jed = jed + 0.5 # # A day chosen by Lewis Carroll to test his day-of-the-week algorithm, # Thursday, 18 September 1783 CE/Gregorian # elif ( i == 41 ): jed = 2372547.5 # # French Republican Epoch # Saturday, 11 September 1792 Julian # Saturday, 22 September 1792 CE/Gregorian # elif ( i == 42 ): jed = 2375839.5 # # Bahai Epoch. # 9 March 1844 Julian # 21 March 1844 CE/Gregorian # elif ( i == 43 ): jed = 2394646.5 # # Clive James Lucas test date. # elif ( i == 44 ): jed = 2394710.50 # # New York Times "epoch" date, # fictitious Volume 1, issue #0, # 17 September 1851 # (issue #1 was on 18 September 1851): # elif ( i == 45 ): jed = 2397383.50 # # Modified Julian Date Epoch. # 17 November 1858 CE/Gregorian # elif ( i == 46 ): jed = 2400000.5 # # NYT issue 10,000 # 24 September 1883 # elif ( i == 47 ): jed_epoch_50000 = 2449790.5 jed = jed_epoch_50000 - 40000.0 - 88.0 # # Bessel Year Count Epoch. # 1 January 1900 CE/Gregorian # elif ( i == 48 ): jed = 2415020.31352 # # NYT issue 30,000 # 14 March 1940 # elif ( i == 49 ): jed_epoch_50000 = 2449790.5 jed = jed_epoch_50000 - 20000.0 - 88.0 # # NYT issue 40,000 # ??? # elif ( i == 50 ): jed_epoch_50000 = 2449790.5 jed = jed_epoch_50000 - 10000.0 - 88.0 # # UNIX epoch. # 1 January 1970 CE/Gregorian. # elif ( i == 51 ): jed = 2440587.50 # # NYT issue 44027 # ??? # elif ( i == 52 ): jed_epoch_50000 = 2449790.5 jed = jed_epoch_50000 - 5973 # # NYT issue 44028 # ??? # elif ( i == 53 ): jed_epoch_50000 = 2449790.5 jed = jed_epoch_50000 - 5972 # # GPS epoch. # 6 January 1980 CE/Gregorian # elif ( i == 54 ): jed = 2444244.5 # # NYT issue 50,000 # 14 March 1995 # elif ( i == 55 ): jed_epoch_50000 = 2449790.5 jed = jed_epoch_50000 # # 25 February 1996 # A Reingold/Dershowitz test date. # elif ( i == 56 ): jed = 2450138.5 # # Y2K day # 1 January 2000 CE/Gregorian # elif ( i == 57 ): jed = 2451544.5 # # Today # elif ( i == 58 ): jed = now_to_jed ( ) # # End of Current Mayan Great Cycle # 21 December 2012 CE/Gregorian # elif ( i == 59 ): jed = 2456282.5 # # Scaliger cycle repeats. # 1 January 3266 CE/Gregorian # elif ( i == 60 ): jed = 2913943.0 else: jed = -1.0 return jed def jed_to_datenum ( jed ): #*****************************************************************************80 # ## jed_to_datenum() converts a JED to a MATLAB DATENUM. # # Discussion: # # The MATLAB "datenum" function accepts a string defining # a date and returns a datenumber: # # dn = datenum ( 'Aug 17 1939' ) # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # real DN, a MATLAB DATENUM. # dn = jed - epoch_to_jed_datenum ( ) return dn def jed_to_datenum_test ( ): #*****************************************************************************80 # ## jed_to_datenum_test() tests jed_to_datenum(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'jed_to_datenum_test():' ) print ( ' jed_to_datenum(): JED => Matlab DATENUM.' ) print ( '' ) print ( ' JED (in) DATENUM JED (out)' ) print ( '' ) jed_epoch = epoch_to_jed_datenum ( ) i = 0 while ( True ): i = i + 1 jed1 = jed_test ( i ) if ( jed1 < 0.0 ): break if ( jed_epoch <= jed1 ): date_num = jed_to_datenum ( jed1 ) jed3 = datenum_to_jed ( date_num ) print ( ' %11.2f %12.2f %11.2f'% ( jed1, date_num, jed3 ) ) return def jed_to_gps ( jed ): #*****************************************************************************80 # ## jed_to_gps() converts a JED to a GPS date. # # Discussion: # # The GPS time keeping is in terms of seconds, weeks, and cycles # of 1024 weeks. The weeks and cycles begin numbering at 0. # # The computation is only valid for dates after the GPS epoch, # that is, after 6 January 1980. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 15 December 2017 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer C, W, real S, the # corresponding GPS cycles/weeks/seconds date. # jed_epoch = epoch_to_jed_gps ( ) d = jed - jed_epoch if ( d < 0.0 ): s = -1.0 w = -1 c = -1 return c, w, s w = int ( d ) // 7 d = d - ( 7 * w ) c = w // 1024 w = w - 1024 * c s = d * ( 24.0 * 60.0 * 60.0 ) return c, w, s def jed_to_gps_test ( ): #*****************************************************************************80 # ## jed_to_gps_test() tests jed_to_gps(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 15 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'jed_to_gps_test():' ) print ( ' jed_to_gps(): JED -> GPS.' ) print ( '' ) print ( ' JED (in) GPS (C/W/S) JED (out)' ) print ( '' ) jed_epoch = epoch_to_jed_gps ( ) i = 0 while ( True ): i = i + 1 jed1 = jed_test ( i ) if ( jed1 < 0.0 ): break if ( jed_epoch <= jed1 ): c2, w2, sec2 = jed_to_gps ( jed1 ) jed3 = gps_to_jed ( c2, w2, sec2 ) print ( ' %11.2f %d/%d/%.2f GPS %11.2f' % ( jed1, c2, w2, sec2, jed3 ) ) return def jed_to_mayan_long ( jed ): #*****************************************************************************80 # ## jed_to_mayan_long() converts a JED to a Mayan long count date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Mapping Time, The Calendar and Its History, # Oxford, 1999, chapter 27. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer PICTUN, BAKTUN, KATUN, TUN, UINAL, KIN: values # defining the Mayan long date. # # real F, the fractional part of the date. # from math import floor jed_epoch = epoch_to_jed_mayan_long ( ) j = floor ( jed - jed_epoch ) f = jed - jed_epoch - j days = j if ( 0 <= days ): pictun = floor ( days / 2880000 ) days = days - pictun * 2880000 else: pictun = 0 while ( days < 0 ): pictun = pictun - 1 days = days + 2880000 baktun = floor ( days / 144000 ) days = days - baktun * 144000 katun = floor ( days / 7200 ) days = days - katun * 7200 tun = floor ( days / 360 ) days = days - tun * 360 uinal = floor ( days / 20 ) days = days - uinal * 20 kin = days return pictun, baktun, katun, tun, uinal, kin, f def jed_to_mayan_round ( jed ): #*****************************************************************************80 # ## jed_to_mayan_round() converts a JED to a Mayan round date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm K, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 340. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, A, B, C, D, values defining the Mayan round date. # # real F, the fractional part of the date. # from math import floor jed_epoch = epoch_to_jed_mayan_long ( ) j = floor ( jed - jed_epoch ) f = jed - jed_epoch - j days = j y = 0 while ( days < 0 ): days = days + 18980 y = y - 1 y = y + floor ( days / 18980 ) days = ( days % 18980 ) a = i4_wrap ( days + 4, 1, 13 ) b = i4_wrap ( days, 1, 20 ) n = ( days + 348 ) % 365 c = ( n % 20 ) d = floor ( n / 20 ) return y, a, b, c, d, f def jed_to_mjd ( jed ): #*****************************************************************************80 # ## jed_to_mjd() converts a JED to a modified JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # real MJD, the modified Julian Ephemeris Date. # jed_epoch = epoch_to_jed_mjd ( ) mjd = jed - jed_epoch return mjd def jed_to_noon_nearest ( jed1 ): #*****************************************************************************80 # ## jed_to_noon_nearest() converts a JED to the JED of the nearest noon. # # Discussion: # # This is primarily to make a fair test of the weekday routines, # which have trouble when the JED is at midnight. # # Note that noon corresponds to an integral JED value. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 25 December 2017 # # Author: # # John Burkardt # # Input: # # real JED1, the Julian Ephemeris Date. # # Output: # # real JED2, the Julian Ephemeris Date # of the nearest noon. # jed2 = round ( jed1 ) return jed2 def jed_to_noon_nearest_test ( ): #*****************************************************************************80 # ## jed_to_noon_nearest_test() tests jed_to_noon_nearest(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 25 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'jed_to_noon_nearest_test():' ) print ( ' jed_to_noon_nearest(): JED => JED of nearest noon.' ) print ( '' ) print ( ' JED JED(noon nearest)' ) print ( '' ) i = 0 while ( True ): i = i + 1 jed1 = jed_test ( i ) if ( jed1 < 0 ): break y1, m1, d1, f1 = jed_to_ymdf_common ( jed1 ) s1 = ymdf_to_s_common ( y1, m1, d1, f1 ) jed2 = jed_to_noon_nearest ( jed1 ) y2, m2, d2, f2 = jed_to_ymdf_common ( jed2 ) s2 = ymdf_to_s_common ( y2, m2, d2, f2 ) print ( '%11.2f %s %11.2f %s' % ( jed1, s1, jed2, s2 ) ) return def jed_to_noon_next ( jed1 ): #*****************************************************************************80 # ## jed_to_noon_next() converts a JED to the JED of the next noon. # # Discussion: # # This is primarily to make a fair test of the weekday routines, # which have trouble when the JED is at midnight. # # Note that noon corresponds to an integral JED value. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 22 June 2012 # # Author: # # John Burkardt # # Input: # # real JED1, the Julian Ephemeris Date. # # Output: # # real JED2, the Julian Ephemeris Date # of the next noon. # jed2 = round ( jed1 ) # # The integer part of JED1 is one of the two integers that # bracket JED1. If it's the smaller one (which it should # be as long as JED1 is positive), make it the bigger one. # # This correctly leaves undisturbed cases where JED1 is # already an integer, and where JED1 is negative (which # is not a case we expect to occur often). # if ( jed2 < jed1 ): jed2 = jed2 + 1.0 return jed2 def jed_to_noon_next_test ( ): #*****************************************************************************80 # ## jed_to_noon_next_test() tests jed_to_noon_next(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 25 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'jed_to_noon_next_test():' ) print ( ' jed_to_noon_next(): JED => JED of following noon time.' ) print ( '' ) print ( ' JED JED(noon next)' ) print ( '' ) i = 0 while ( True ): i = i + 1 jed1 = jed_test ( i ) if ( jed1 < 0 ): break y1, m1, d1, f1 = jed_to_ymdf_common ( jed1 ) s1 = ymdf_to_s_common ( y1, m1, d1, f1 ) jed2 = jed_to_noon_next ( jed1 ) y2, m2, d2, f2 = jed_to_ymdf_common ( jed2 ) s2 = ymdf_to_s_common ( y2, m2, d2, f2 ) print ( '%11.2f %s %11.2f %s' % ( jed1, s1, jed2, s2 ) ) return def jed_to_nyt ( jed ): #*****************************************************************************80 # ## jed_to_nyt() converts a JED to an NYT date. # # Discussion: # # The New York Times began publication with Volume 1, Issue 1 on # Thursday, 18 September 1851. # # The Volume number is incremented annually, on 18 September. # # It seemed an initriguing idea, then, to devise a formula that would # produce the New York Times issue number for a given date, or that # could start with the issue number and return the date on which that # issue appeared. # # In a simple world, this would have been essentially a translation # of the JED, that is, the first approximation would be # # NYT(today) - NYT(18 September 1851) = JED(today) - JED(18 September 1851) # # so # # NYT(today) = NYT(18 September 1851) + JED(today) - JED(18 September 1851) # # and we're done. # # However, the first problem involved Sunday issues. No Sunday paper was # printed at all, until 21 April 1861. Moreover, that paper was given # the issue number 2990, which was the same issue number as the Saturday # paper. This persisted until some time around April 1905, when Sunday # papers were assigned their own issue number. Once this was done, the # New York Times issue number began to "track" the Julian Ephemeris Date # in a simple way. # # The second obvious problem occurred because there was an 88 day strike # in 1978. The issue for August 9 was 44027, and the issue for November 6 # was 44028 (I THINK, I AM NOT COMPLETELY SURE HERE). During other strikes, # the New York Times had increased the issue number each day, even if no # paper was printed. This was the first time that a strike caused the issue # number sequence to halt. # # The third problem was more subtle. An article printed on 14 March 1995 # heralded the printing of issue 50,000 of the New York Times. It also # mentioned issues and corresponding dates for several points in the past, # explained the 88 day strike lacuna, and the fact that there were no # Sunday papers at all until 21 April 1861. This information seemed enough # to define a new formula that would work for the present era, at least, # after Sunday papers were printed and given their own issue number. # We could do this by basing the formula on the JED for issue 50,000, which # turned out to have the value 2449790.5. # # For days on or after 6 November 1978, # # NYT(today) = NYT(14 March 1995) + JED(today) - JED(14 March 1995) # # For days on or before 9 August 1978, # # NYT(today) = NYT(14 March 1995) + JED(today) - JED(14 March 1995) + 88 # # I set up this formula, and it worked pretty well for my list of known # dates and issue numbers between 1909 and 1995. # # Then I pulled out the New York Times that I had bought that day # (22 November 2007), and tried out the formula. To my dismay, the value # returned by the formula was exactly 500 higher than the value printed # on my paper. This was very disturbing# # # Going online, I tried to find more examples of issues and dates in the # interval between 14 March 1995 and 22 November 2007. This was harder # than you might think. Almost no one refers to the issue number. Even # the article indexes for the New York Times, whether printed or online, # refer only to the date. I ended up having to scan for images of the # front page. There were surprisingly many, but most were of such poor # quality that the issue number could not be read. Patience rewarded # me, though, with data for 1997, then for 2005, then for 2003, then # 2002. Gradually, I began to jokingly assume that the dreaded Year 2000 # catastrophe had somehow hit the New York Times# # # Imagine my shock when a colleague whom I had dragged into the search # with me discovered that this was true in a way. On the front page of # the New York Times for 1 January 2000 was the statement that a mistake # in issue numbering, made in 1898 and never noticed until recently, # was being corrected. The issue numbers had been accidentally "inflated" # by 500 back then, so they were now being "corrected" by dropping 500. # # The ghastly details were: # # Date Issue # ---------------- ------ # 06 February 1898 14,499 # 07 February 1898 15,000 # 31 December 1999 51,753 # 01 January 2000 51,254 # # With this information, it becomes possible to adjust the formula to # be correct for current issues, and back over the "hiccup" in 1898. # The formula, however, obviously becomes more complicated, and, what's # worse, the issue number itself no longer can be used to deduce the # date, since there is now a sequence of 500 issue numbers that were used # twice. Luckily, if we require the Volume number as well, we have # enough information to go back and forth. # # The formula for the New York Times Volume Number is not as simple # as it could be. The Volume started at 1 on 18 September 1851, and # increases by 1 each successive 18 September. To determine the # volume number for a given date, you need to go "backwards" to the # most recent elapsed 18 September, note the year in which that occurred, # subtract 1851 from that, and add 1# # # NYT_VOLUME = Year(Most-recently-elapsed-18-September) - 1851 + 1. # # Now I have to work out the details of the formula to allow for the # two hiccups and the strike, and I should have a start on a usable pair # of formulas. # # This excruciating (and unfinished) effort demonstrates, I hope, that # calendars are human creations, which aspire to mathematical regularity, # but which inevitably acquire the irregularities and ambiguities of all # human creations# # # Surprisingly, computing the correct issue number from the date # is complicated. Here are a few of the misadventures: # # Fri, 2 Jan 1852, no issue. # 6 Jul 1852, no issue # Sat, 2 Jul 1853, no issue, would have been 559. # Mon, 4 Jul 1853, INCORRECT issue number 560 (559 not used). # Tue, 5 Jul 1853, correct issue number 560. # 6 Jul 1854, issue, but same issue number as 5 Jul 1854. # Thu, 5 Jul 1855, issue, but same issue number as 4 Jul 1855 (#1184) # Tue, 25 Sep 1855, issue jumps by 2, from 1253 to 1255# # Sat, 29 Sep 1856, issue, but same issue number as 28 Sep 1855 (#1258). # Fri, 4 Jan 1856, issue, but same issue number as 3 Jan 1856, (#1340). # Mon, 7 Jul 1856, issue, but same issue number as 5 Jul 1856, (#1497). # Sat, 3 Jan 1857, issue, but same issue number as 2 Jan 1857, (#1651). # Sat, 2 Jan 1858, issue, but same issue number as 1 Jan 1858, (#1962). # Tue, 6 Jul 1858, issue, but same issue number as 5 Jul 1858, (#2119). # Tue, 5 Jul 1859, no issue. # Tue, 3 Jan 1860, no issue. # Thu, 5 Jul 1860, no issue. # Wed, 2 Jan 1861, no issue # Sun, 21 Apr 1861, first Sunday issue. First two Sundays get distinct # issue numbers. Thereafter, a "correction" is made. # Fri, 5 Jul 1861, no issue. # Thu, 2 Jan 1862, no issue. # Sat, 5 Jul 1862, no issue. # Fri, 2 Jan 1863, no issue. # Sat, 2 Jan 1864, no issue. # Tue, 5 Jul 1864, no issue. # Wed, 5 Jul 1865, no issue. # Tue, 2 Jan 1866, no issue. # Wed, 2 Jan 1867, no issue. # Sat, 5 Feb 1898, issue 14499. # Mon, 7 Feb 1898, issue 15000 (incremented by 501 instead of by 1) # Sun, 23 Apr 1905, Sunday paper gets distinct issue number. # Wed, 9 Aug 1978, last prestrike issue. Issue numbers halt. # Mon, 6 Nov 1978, first poststrike issue, issue numbers resume. # Sat, 1 Jan 2000, issue numbers "corrected" downwards by 500. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Anonymous, # A Correction Welcome to 51,254, # The New York Times, # 01 January 2000, Volume 149, Issue 51254. # # James Barron, # What's in a Number? 143 Years of News, # The New York Times, # 14 March 1995, Volume 144, Issue 50000. # # The New York Times, # Page One, 1896-1996, A Special Commemorative Edition Celebrating the # 100th Anniversary of the Purchase of the New York Times by Adolph S Ochs, # Galahad Books, 1996, # ISBN: 0-88365-961-1, # LC: D411.P25. # # The New York Times, # The Complete First Pages, 1851-2008, # Black Dog and Leventhal Publishers, 2008, # ISBN13: 978-1-57912-749-7, # LC: D351.N53. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer VOLUME, ISSUE, the New York Times volume and issue. # # # The "epoch" of the NYT calendar is the mythical date when issue "0" # would have been printed, namely, a tad past midnight, 17 September 1851. # # Volume #1, Issue #1 was printed on 18 September 1851. # from math import floor y2 = 1851 m2 = 9 d2 = 17 f2 = 0.0 jed_epoch = ymdf_to_jed_common ( y2, m2, d2, f2 ) # # We start out by computing the number of elapsed days, which is # our initial estimate of the issue number. # issue = floor ( jed - jed_epoch ) # # If the user has given a JED before the epoch, return now. # if ( issue <= 0 ): volume = -1 return volume, issue # # For dates on or after issue #1, the volume computation is easy. # y, m, d, f = jed_to_ymdf_common ( jed ) volume = y - 1851 + 1 if ( ( m == 9 and d < 18 ) or m < 9 ): volume = volume - 1 f = 0.0 # # CORRECTION #1 # Deal with nonissue on Friday, 2 January 1852 # jed_02_01_1852 = ymdf_to_jed_common ( 1852, 1, 2, f ) if ( jed_02_01_1852 <= jed ): issue = issue - 1 # # CORRECTION #2 # Deal with nonissue on Tuesday, 6 July 1852 # jed_07_06_1852 = ymdf_to_jed_common ( 1852, 7, 6, f ) if ( jed_07_06_1852 <= jed ): issue = issue - 1 # # CORRECTION #3 # Deal with nonissue on Saturday, 2 July 1853 # jed_07_02_1853 = ymdf_to_jed_common ( 1853, 7, 2, f ) if ( jed_07_02_1853 <= jed ): issue = issue - 1 # # CORRECTION #4 # Deal with use of single issue number 873 for both # Wednesday, 5 July 1854 and Thursday, 6 July 1854. # jed_07_06_1854 = ymdf_to_jed_common ( 1854, 7, 6, f ) if ( jed_07_06_1854 <= jed ): issue = issue - 1 # # CORRECTION #5 # Deal with use of single issue number 1184 for both # Wednesday, 4 July 1855 and Thursday, 5 July 1855. # jed_07_05_1855 = ymdf_to_jed_common ( 1855, 7, 5, f ) if ( jed_07_05_1855 <= jed ): issue = issue - 1 end # # CORRECTION #6 # They skipped one! # Issue 1253 = 24 September 1855 # Issue 1255 = 25 September 1855 # jed_25_09_1855 = ymdf_to_jed_common ( 1855, 9, 25, f ) if ( jed_25_09_1855 <= jed ): issue = issue + 1 # # CORRECTION #7 # They "fixed” it. # Issue 1258 = 28 September 1855 # Issue 1258 = 29 September 1855 # jed_29_09_1855 = ymdf_to_jed_common ( 1855, 9, 29, f ) if ( jed_29_09_1855 <= jed ): issue = issue - 1 # # CORRECTION #8 # Deal with use of single issue number 1340 for both # Thursday, 3 January 1856 and Friday, 4 January 1856. # jed_04_01_1856 = ymdf_to_jed_common ( 1856, 1, 4, f ) if ( jed_04_01_1856 <= jed ): issue = issue - 1 # # CORRECTION #8 # Deal with use of single issue number 1497 for both # Saturday, 5 July 1856 and Monday, 7 July 1856. # jed_07_07_1856 = ymdf_to_jed_common ( 1856, 7, 7, f ) if ( jed_07_07_1856 <= jed ): issue = issue - 1 # # CORRECTION #9 # Deal with use of single issue number 1651 for both # Friday, 2 January 1857 and Saturday, 3 January 1857. # jed_03_01_1857 = ymdf_to_jed_common ( 1857, 1, 3, f ) if ( jed_03_01_1857 <= jed ): issue = issue - 1 # # CORRECTION #10 # Deal with use of single issue number 1962 for both # Friday, 1 January 1858 and Saturday, 2 January 1858. # jed_02_01_1858 = ymdf_to_jed_common ( 1858, 1, 2, f ) if ( jed_02_01_1858 <= jed ): issue = issue - 1 # # CORRECTION #11 # Deal with use of single issue number 2119 for both # Monday, 5 July 1858 and Tuesday, 6 July 1858. # jed_06_07_1858 = ymdf_to_jed_common ( 1858, 7, 6, f ) if ( jed_06_07_1858 <= jed ): issue = issue - 1 # # CORRECTION #12 # Deal with nonissue on Tuesday, 5 July 1859: # jed_05_07_1859 = ymdf_to_jed_common ( 1859, 7, 5, f ) if ( jed_05_07_1859 <= jed ): issue = issue - 1 # # CORRECTION #13 # Deal with nonissue on Tuesday, 3 January 1860: # jed_03_01_1860 = ymdf_to_jed_common ( 1860, 1, 3, f ) if ( jed_03_01_1860 <= jed ): issue = issue - 1 # # CORRECTION #14 # Deal with nonissue on Thursday, 5 July 1860: # jed_05_07_1860 = ymdf_to_jed_common ( 1860, 7, 5, f ) if ( jed_05_07_1860 <= jed ): issue = issue - 1 # # CORRECTION #15 # Deal with nonissue on Wednesday, 2 January 1861: # jed_02_01_1861 = ymdf_to_jed_common ( 1861, 1, 2, f ) if ( jed_02_01_1861 <= jed ): issue = issue - 1 # # CORRECTION #16 # Sunday issue got its own issue number, 21 April 1861. # jed_04_21_1861 = ymdf_to_jed_common ( 1861, 4, 21, f ) if ( jed_04_21_1861 <= jed ): issue = issue + 1 # # CORRECTION #17 # Sunday issue got its own issue number, 28 April 1861. # jed_04_28_1861 = ymdf_to_jed_common ( 1861, 4, 28, f ) if ( jed_04_28_1861 <= jed ): issue = issue + 1 # # CORRECTION #18 # Two Sunday issues retroactively "corrected" back down, 5 May 1861. # jed_05_05_1861 = ymdf_to_jed_common ( 1861, 5, 5, f ) if ( jed_05_05_1861 <= jed ): issue = issue - 2 # # CORRECTION #19 # Deal with nonissue on Friday, 5 July 1861: # jed_05_07_1861 = ymdf_to_jed_common ( 1861, 7, 5, f ) if ( jed_05_07_1861 <= jed ): issue = issue - 1 # # CORRECTION #20 # Deal with nonissue on Thursday, 2 January 1862: # jed_02_01_1862 = ymdf_to_jed_common ( 1862, 1, 2, f ) if ( jed_02_01_1862 <= jed ): issue = issue - 1 # # CORRECTION #21 # Deal with nonissue on Saturday, 5 July 1862: # jed_05_07_1862 = ymdf_to_jed_common ( 1862, 7, 5, f ) if ( jed_05_07_1862 <= jed ): issue = issue - 1 # # CORRECTION #22 # Deal with nonissue on Friday, 2 January 1863: # jed_02_01_1863 = ymdf_to_jed_common ( 1863, 1, 2, f ) if ( jed_02_01_1863 <= jed ): issue = issue - 1 # # CORRECTION #23 # Deal with failure of issue increment on Monday, 28 September 1863: # jed_28_09_1863 = ymdf_to_jed_common ( 1863, 9, 28, f ) if ( jed_28_09_1863 <= jed ): issue = issue - 1 # # CORRECTION #23 # Deal with double issue increment on Wednesday, 30 September 1863: # jed_30_09_1863 = ymdf_to_jed_common ( 1863, 9, 30, f ) if ( jed_30_09_1863 <= jed ): issue = issue + 1 # # CORRECTION #24 # Deal with nonissue on Saturday, 2 January 1864: # jed_02_01_1864 = ymdf_to_jed_common ( 1864, 1, 2, f ) if ( jed_02_01_1864 <= jed ): issue = issue - 1 # # CORRECTION #25 # Deal with nonissue on Tuesday, 5 July 1864: # jed_05_07_1864 = ymdf_to_jed_common ( 1864, 7, 5, f ) if ( jed_05_07_1864 <= jed ): issue = issue - 1 # # CORRECTION #26 # Deal with nonissue on Monday, 3 January 1865: # jed_03_01_1865 = ymdf_to_jed_common ( 1865, 1, 3, f ) if ( jed_03_01_1865 <= jed ): issue = issue - 1 # # CORRECTION #27 # Deal with nonissue on Wednesday, 5 July 1865: # jed_05_07_1865 = ymdf_to_jed_common ( 1865, 7, 5, f ) if ( jed_05_07_1865 <= jed ): issue = issue - 1 # # CORRECTION #28 # Deal with nonissue on Tuesday, 2 January 1866: # jed_02_01_1866 = ymdf_to_jed_common ( 1866, 1, 2, f ) if ( jed_02_01_1866 <= jed ): issue = issue - 1 # # CORRECTION #29 # Deal with nonissue on Wednesday, 2 January 1867: # jed_02_01_1867 = ymdf_to_jed_common ( 1867, 1, 2, f ) if ( jed_02_01_1867 <= jed ): issue = issue - 1 # # CORRECTION #30 # Deal with the interval from Thursday, 18 September 1851 # to Saturday, 22 April 1905. # # During this period, there were no Sunday issues. # jed_22_04_1905 = ymdf_to_jed_common ( 1905, 4, 22, f ) days = floor ( min ( jed, jed_22_04_1905 ) - jed_epoch ) sundays = floor ( ( days + 3 ) / 7 ) issue = issue - sundays # # CORRECTION #31 # Issues jumped by 500 because of mistake on 7 February 1898. # jed_07_02_1898 = ymdf_to_jed_common ( 1898, 2, 7, f ) if ( jed_07_02_1898 <= jed ): issue = issue + 500 # # CORRECTION #32 # No issues from 10 August 1978 through 5 November 1978. # jed_10_08_1978 = ymdf_to_jed_common ( 1978, 8, 10, f ) jed_05_11_1978 = ymdf_to_jed_common ( 1978, 11, 5, f ) if ( jed_10_08_1978 <= jed ): issue = issue - floor ( min ( jed_05_11_1978, jed ) - jed_10_08_1978 ) - 1 # # CORRECTION #33 # Issues decreased by 500 to correct previous mistake, 1 January 2000. # jed_01_01_2000 = ymdf_to_jed_common ( 2000, 1, 1, f ) if ( jed_01_01_2000 <= jed ): issue = issue - 500 return volume, issue def jed_to_rd ( jed ): #*****************************************************************************80 # ## jed_to_rd() converts a JED to an RD. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Reingold, Nachum Dershowitz, # Calendrical Calculations, the Millennium Edition, # Cambridge, 2002. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # real RD, the RD date. # rd_epoch = epoch_to_jed_rd ( ) rd = jed - rd_epoch return rd def jed_to_ss_unix ( jed ): #*****************************************************************************80 # ## jed_to_ss_unix() converts a JED to a UNIX SS date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # real S, the corresponding UNIX SS date. # jed_epoch = epoch_to_jed_unix ( ) d = jed - jed_epoch s = d * 24.0 * 60.0 * 60.0 return s def jed_to_weekday ( jed ): #*****************************************************************************80 # ## jed_to_weekday() computes the day of the week from a JED. # # Discussion: # # BC 4713/01/01 => JED = 0.0 was noon on a Monday. # # jedmod = mod ( 0.0, 7.0 ) = 0.0 # j = mod ( nint ( 0 ), 7 ) = 0 # f = ( 0.0 + 0.5 ) - real ( j ) = 0.5 # w = i4_wrap ( 0 + 2, 1, 7 ) = 2 = MONDAY # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 July 2017 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Mapping Time, The Calendar and Its History, # Oxford, 1999. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer W, the day of the week of the date. # The days are numbered from Sunday through Saturday, 1 through 7. # # real F, the fractional part of the day. # import numpy as np jedp = jed + 0.5 jedpfrac = ( jedp % 1.0 ) jedpwhole = int ( jedp - jedpfrac ) f = jedpfrac w = i4_wrap ( jedpwhole + 2, 1, 7 ) return w, f def jed_to_weekday_test ( ): #*****************************************************************************80 # ## jed_to_weekday_test() tests jed_to_weekday(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 July 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'jed_to_weekday_test():' ) print ( ' jed_to_weekday() determines the weekday corresponding to a JED.' ) print ( '' ) print ( ' JED W W' ) print ( ' True Computed' ) print ( '' ) n_data = 0 while ( True ): n_data, jed, w = jed_weekday_values ( n_data ) if ( n_data == 0 ): break w2, f = jed_to_weekday ( jed ) print ( ' %14f %4d %8d' % ( jed, w, w2 ) ) return def jed_to_yearcount_bessel ( jed ): #*****************************************************************************80 # ## jed_to_yearcount_bessel() converts a JED to Bessel year count. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # real BESSEL, the Bessel year. # year_length_days = 365.242198781 jed_epoch = epoch_to_jed_bessel ( ) bessel = 1900.0 + ( jed - jed_epoch ) / year_length_days return bessel def jed_to_yearcount_julian ( jed ): #*****************************************************************************80 # ## jed_to_yearcount_julian() converts a JED to a Julian year count. # # Discussion: # # An average year in the Julian calendar is exactly 365.25 days long. # This calculation counts the number of average Julian years from # the beginning of the year 2000. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # real JULIAN, the Julian year. # year_length_days = 365.25 jed_epoch = epoch_to_jed_y2k ( ) julian = 2000.0 + ( jed - jed_epoch ) / year_length_days return julian def jed_to_year_hebrew ( jed ): #*****************************************************************************80 # ## jed_to_year_hebrew(): the year in the Hebrew calendar when a JED occurred. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm H, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 331. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, the year in the Hebrew calendar that # included the JED. If the input JED is less than the epoch of the Hebrew # calendar, then Y is always returned as -1. # from math import floor jed_epoch = epoch_to_jed_hebrew ( ) if ( jed < jed_epoch ): y = -1 return y # # Using integer arithmetic in this computation may cause overflow. # # Compute the number of months elapsed up to the date. # m = 1 + floor ( ( 25920.0 * ( jed - jed_epoch + 2.5 ) ) / 765433.0 ) # # Estimate the number of years represented by these months. # y = 19 * floor ( m / 235 ) + floor ( ( 19 * ( i4_modp ( m, 235 ) - 2 ) ) / 235 ) + 1 y = max ( y, 1 ) # # Determine the JED of the first day of that year. # jed2 = new_year_to_jed_hebrew ( y ) # # We might have been off by 1 year. # if ( jed < jed2 ): y = y - 1 return y def jed_to_yjf_common ( jed ): #*****************************************************************************80 # ## jed_to_yjf_common() converts a JED to a Common YJF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, J, real F, the YJF date. # y1, m1, d1, f1 = jed_to_ymdf_common ( jed ) y, j, f = ymdf_to_yjf_common ( y1, m1, d1, f1 ) return y, j, f def jed_to_yjf_english ( jed ): #*****************************************************************************80 # ## jed_to_yjf_english() converts a JED to an English YJF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, J, real F, the YJF date. # y1, m1, d1, f1 = jed_to_ymdf_english ( jed ) y, j, f = ymdf_to_yjf_english ( y1, m1, d1, f1 ) return y, j, f def jed_to_yjf_gregorian ( jed ): #*****************************************************************************80 # ## jed_to_yjf_gregorian() converts a JED to a Gregorian YJF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, J, real F, the YJF date. # y1, m1, d1, f1 = jed_to_ymdf_gregorian ( jed ) y, j, f = ymdf_to_yjf_gregorian ( y1, m1, d1, f1 ) return y, j, f def jed_to_yjf_hebrew ( jed ): #*****************************************************************************80 # ## jed_to_yjf_hebrew() converts a JED to a Hebrew YJF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, J, real F, the YJF date. # y1, m1, d1, f1 = jed_to_ymdf_hebrew ( jed ) y, j, f = ymdf_to_yjf_hebrew ( y1, m1, d1, f1 ) return y, j, f def jed_to_yjf_islamic_a ( jed ): #*****************************************************************************80 # ## jed_to_yjf_islamic_a() converts a JED to an Islamic-A YJF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, J, real F, the YJF date. # y1, m1, d1, f1 = jed_to_ymdf_islamic_a ( jed ) y, j, f = ymdf_to_yjf_islamic ( y1, m1, d1, f1 ) return y, j, f def jed_to_yjf_islamic_b ( jed ): #*****************************************************************************80 # ## jed_to_yjf_islamic_b() converts a JED to an Islamic-B YJF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, J, real F, the YJF date. # y1, m1, d1, f1 = jed_to_ymdf_islamic_b ( jed ) y, j, f = ymdf_to_yjf_islamic ( y1, m1, d1, f1 ) return y, j, f def jed_to_yjf_julian ( jed ): #*****************************************************************************80 # ## jed_to_yjf_julian() converts a JED to a Julian YJF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, J, real F, the YJF date. # y1, m1, d1, f1 = jed_to_ymdf_julian ( jed ) y, j, f = ymdf_to_yjf_julian ( y1, m1, d1, f1 ) return y, j, f def jed_to_yjf_republican ( jed ): #*****************************************************************************80 # ## jed_to_yjf_republican() converts a JED to a Republican YJF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, J, real F, the YJF date. # y1, m1, d1, f1 = jed_to_ymdf_republican ( jed ) y, j, f = ymdf_to_yjf_republican ( y1, m1, d1, f1 ) return y, j, f def jed_to_yjf_roman ( jed ): #*****************************************************************************80 # ## jed_to_yjf_roman() converts a JED to a Roman YJF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, J, real F, the YJF date. # y1, m1, d1, f1 = jed_to_ymdf_roman ( jed ) y, j, f = ymdf_to_yjf_roman ( y1, m1, d1, f1 ) return y, j, f def jed_to_ymdf_alexandrian ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_alexandrian() converts a JED to an Alexandrian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j j_prime = j + 124 y_prime = floor ( ( 4 * j_prime + 3 ) / 1461 ) t_prime = floor ( ( ( 4 * j_prime + 3 ) % 1461 ) / 4 ) m_prime = floor ( t_prime / 30 ) d_prime = ( t_prime % 30 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( m_prime % 13 ) + 1 y = y_prime - 4690 + floor ( ( 13 - m ) / 13 ) return y, m, d, f def jed_to_ymdf_armenian ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_armenian() converts a JED to an Armenian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j j_prime = j + 317 y_prime = floor ( j_prime / 365 ) t_prime = ( j_prime % 365 ) m_prime = floor ( t_prime / 30 ) d_prime = ( t_prime % 30 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( m_prime % 13 ) + 1 y = y_prime - 5268 + floor ( ( 13 - m ) / 13 ) return y, m, d, f def jed_to_ymdf_bahai ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_bahai() converts a JED to a Bahai YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j g = floor ( ( 4 * j + 274273 ) / 146097 ) g = floor ( ( 3 * g ) / 4 ) - 50 j_prime = j + 1412 + g y_prime = floor ( ( 4 * j_prime + 3 ) / 1461 ) t_prime = floor ( ( ( 4 * j_prime + 3 ) % 1461 ) / 4 ) m_prime = floor ( t_prime / 19 ) d_prime = ( t_prime % 19 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( ( m_prime + 19 ) % 20 ) + 1 y = y_prime - 6560 + floor ( ( 39 - m ) / 20 ) return y, m, d, f def jed_to_ymdf_common ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_common() converts a JED to a Common YMDF date. # # Discussion: # # The "common" calendar is meant to be the calendar which is Julian up to # JED = 2299160.5, and Gregorian thereafter. # # There is no year 0. BC years are specified using a negative value. # # Example: # # JED Y M D # ------- ------------------ # 0 BCE 4713 Jan 1 # 2440000 CE 1968 May 23 # 2446065 CE 1984 Dec 31 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # jed_transition = transition_to_jed_common ( ) if ( jed <= jed_transition ): y, m, d, f = jed_to_ymdf_julian ( jed ) else: y, m, d, f = jed_to_ymdf_gregorian ( jed ) return y, m, d, f def jed_to_ymdf_coptic ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_coptic() converts a JED to a Coptic YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j j_prime = j + 124 y_prime = floor ( ( 4 * j_prime + 3 ) / 1461 ) t_prime = floor ( ( ( 4 * j_prime + 3 ) % 1461 ) / 4 ) m_prime = floor ( t_prime / 30 ) d_prime = ( t_prime % 30 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( m_prime % 13 ) + 1 y = y_prime - 4996 + floor ( ( 13 - m ) / 13 ) return y, m, d, f def jed_to_ymdf_eg_civil ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_eg_civil() converts a JED to an Egyptian Civil YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j j_prime = j + 47 - 1 y_prime = floor ( j_prime / 365 ) t_prime = ( j_prime % 365 ) m_prime = floor ( t_prime / 30 ) d_prime = ( t_prime % 30 ) # # Convert the computational date to calendar date. # d = d_prime + 1 m = ( m_prime % 13 ) + 1 y = y_prime - 3968 + floor ( ( 13 - m ) / 13 ) return y, m, d, f def jed_to_ymdf_eg_lunar ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_eg_lunar() converts a JED to an Egyptian Lunar YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor jed_epoch = epoch_to_jed_eg_lunar ( ) j = floor ( jed - jed_epoch ) f = ( jed - jed_epoch ) - j d = 1 + j m = 1 y = 1 # # Account for the number of 25 year cycles of 9125 days. # ncycle = floor ( d / 9125 ) y = y + 25 * ncycle d = d - ncycle * 9125 while ( year_length_days_eg_lunar ( y ) < d ): d = d - year_length_days_eg_lunar ( y ) y = y + 1 while ( month_length_eg_lunar ( y, m ) < d ): d = d - month_length_eg_lunar ( y, m ) m = m + 1 return y, m, d, f def jed_to_ymdf_english ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_english() converts a JED to an English YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # jed_transition = transition_to_jed_english ( ) if ( jed <= jed_transition ): y, m, d, f = jed_to_ymdf_julian ( jed ) else: y, m, d, f = jed_to_ymdf_gregorian ( jed ) return y, m, d, f def jed_to_ymdf_ethiopian ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_ethiopian() converts a JED to an Ethiopian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j j_prime = j + 124 y_prime = floor ( ( 4 * j_prime + 3 ) / 1461 ) t_prime = floor ( ( ( 4 * j_prime + 3 ) % 1461 ) / 4 ) m_prime = floor ( t_prime / 30 ) d_prime = ( t_prime % 30 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( m_prime % 13 ) + 1 y = y_prime - 4720 + floor ( ( 13 - m ) / 13 ) return y, m, d, f def jed_to_ymdf_gregorian2 ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_gregorian2() converts a JED to a Gregorian YMDF date. # # Discussion: # # The theory behind this routine is very clean. The Gregorian # calendar has cycles of 1, 4, 100 and 400 years, and we can # analyze a date by determining where it lies within these cycles. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Reingold, Nachum Dershowitz, Stewart Clamen, # Calendrical Calculations, II: Three Historical Calendars, # Software - Practice and Experience, # Volume 23, Number 4, pages 383-404, April 1993. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor g1 = 365 g4 = 1461 g100 = 36524 g400 = 146097 jed_epoch = epoch_to_jed_gregorian ( ) j = floor ( jed - jed_epoch ) f1 = ( jed - jed_epoch ) - j d0 = j n400 = 0 while ( d0 < 0 ): d0 = d0 + g400 n400 = n400 - 1 n400 = n400 + floor ( d0 / g400 ) d1 = i4_modp ( d0, g400 ) n100 = floor ( d1 / g100 ) d2 = i4_modp ( d1, g100 ) n4 = floor ( d2 / g4 ) d3 = i4_modp ( d2, g4 ) n1 = floor ( d3 / g1 ) d4 = i4_modp ( d3, g1 ) if ( n100 == 4 or n1 == 4 ): j1 = 366 y1 = 400 * n400 + 100 * n100 + 4 * n4 + n1 else: j1 = d4 + 1 y1 = 400 * n400 + 100 * n100 + 4 * n4 + n1 + 1 # # Any year before 1 AD must be moved one year further back, since # this calendar does not include a year 0. # y1 = y_astronomical_to_common ( y1 ) y, m, d, f = yjf_to_ymdf_gregorian ( y1, j1, f1 ) return y, m, d, f def jed_to_ymdf_gregorian ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_gregorian() converts a JED to a Gregorian YMDF date. # # Discussion: # # This Gregorian calendar is extended backwards in time before # its actual adoption. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j g = floor ( ( 4 * j + 274277 ) / 146097 ) g = floor ( ( 3 * g ) / 4 ) - 38 j_prime = j + 1401 + g y_prime = floor ( ( 4 * j_prime + 3 ) / 1461 ) t_prime = floor ( ( ( 4 * j_prime + 3 ) % 1461 ) / 4 ) m_prime = floor ( ( 5 * t_prime + 2 ) / 153 ) d_prime = floor ( ( ( 5 * t_prime + 2 ) % 153 ) / 5 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( ( m_prime + 2 ) % 12 ) + 1 y = y_prime - 4716 + floor ( ( 14 - m ) / 12 ) # # Any year before 1 AD must be moved one year further back, since # this calendar does not include a year 0. # y = y_astronomical_to_common ( y ) return y, m, d, f def jed_to_ymdf_hebrew ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_hebrew() converts a JED to a Hebrew YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm I, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 334. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor y1 = jed_to_year_hebrew ( jed ) jed2 = new_year_to_jed_hebrew ( y1 ) type = year_to_type_hebrew ( y1 ) j1 = floor ( jed - jed2 ) f1 = ( jed - jed2 ) - j1 j1 = j1 + 1 [ y, m, d, f ] = yjf_to_ymdf_hebrew ( y1, j1, f1 ) return y, m, d, f def jed_to_ymdf_hindu_solar ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_hindu_solar() converts a JED to a Hindu solar YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Reingold, Nachum Dershowitz, Stewart Clamen, # Calendrical Calculations, II: Three Historical Calendars, # Software - Practice and Experience, # Volume 23, Number 4, pages 383-404, April 1993. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Date = JF. # jf = jed # # Date = JED_EPOCH + JF # jed_epoch = epoch_to_jed_hindu_solar ( ) jf = jf - jed_epoch # # Date = JED_EPOCH + Y years + JF # yz = 0 y = floor ( jf / year_length_days_hindu_solar ( yz ) ) jf = jf - floor ( y * year_length_days_hindu_solar ( yz ) ) # # Date = JED_EPOCH + Y years + ( M - 1 ) months + JF # mz = 0 m = 1 + floor ( jf / month_length_hindu_solar ( yz, mz ) ) jf = jf - floor ( ( m - 1 ) * month_length_hindu_solar ( yz, mz ) ) # # Date = JED_EPOCH + Y years + ( M - 1 ) months + ( D - 1 ) days + f # d = floor ( jf ) + 1 f = jf - ( d - 1 ) return y, m, d, f def jed_to_ymdf_islamic_a ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_islamic_a() converts a JED to an Islamic A YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j j_prime = j + 7665 y_prime = floor ( ( 30 * j_prime + 15 ) / 10631 ) t_prime = floor ( ( ( 30 * j_prime + 15 ) % 10631 ) / 30 ) m_prime = floor ( ( 100 * t_prime + 10 ) / 2951 ) d_prime = floor ( ( ( 100 * t_prime + 10 ) % 2951 ) / 100 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( m_prime % 12 ) + 1 y = y_prime - 5519 + floor ( ( 12 - m ) / 12 ) return y, m, d, f def jed_to_ymdf_islamic_b ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_islamic_b() converts a JED to an Islamic B YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j j_prime = j + 7664 y_prime = floor ( ( 30 * j_prime + 15 ) / 10631 ) t_prime = floor ( ( ( 30 * j_prime + 15 ) % 10631 ) / 30 ) m_prime = floor ( ( 100 * t_prime + 10 ) / 2951 ) d_prime = floor ( ( ( 100 * t_prime + 10 ) % 2951 ) / 100 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( m_prime % 12 ) + 1 y = y_prime - 5519 + floor ( ( 12 - m ) / 12 ) return y, m, d, f def jed_to_ymdf_jelali ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_jelali() converts a JED to a Jelali YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor jed_epoch = epoch_to_jed_jelali ( ) j = floor ( jed - jed_epoch ) f = ( jed - jed_epoch ) - j d = 1 + j m = 1 y = 1 # # Account for the number of completed 4 year cycles of 1461 days. # n = floor ( ( d - 1 ) / 1461 ) y = y + 4 * n d = d - n * 1461 # # Account for the number of completed 365 day years. # n = floor ( ( d - 1 ) / 365 ) y = y + n d = d - n * 365 # # Account for the number of completed 30 day months. # n = floor ( ( d - 1 ) / 30 ) m = m + n d = d - n * 30 return y, m, d, f def jed_to_ymdf_julian2 ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_julian2() converts a JED to a Julian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j jd = floor ( ( j + 1524 - 122.1 ) / 365.25 ) je = floor ( 365.25 * jd ) jg = floor ( ( j + 1524 - je ) / 30.6001 ) # # Now compute D, M and Y. # d = j + 1524 - je - floor ( 30.6001 * jg ) if ( jg <= 13 ): m = jg - 1 else: m = jg - 13 if ( 2 < m ): y = jd - 4716 else: y = jd - 4715 # # Any year before 1 AD must be moved one year further back, since # this calendar does not include a year 0. # y = y_astronomical_to_common ( y ) return y, m, d, f def jed_to_ymdf_julian3 ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_julian3() converts a JED to a Julian YMDF date. # # Discussion: # # The theory behind this routine is very clean. The Julian # calendar has cycles of 1 and 4 years, and we can analyze a date # by determining where it lies within these cycles. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Reingold, Nachum Dershowitz, Stewart Clamen, # Calendrical Calculations, II: Three Historical Calendars, # Software - Practice and Experience, # Volume 23, Number 4, pages 383-404, April 1993. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor cycle_length = 1461 year_length_days = 365 jed_epoch = epoch_to_jed_julian ( ) j = floor ( jed - jed_epoch ) f1 = ( jed - jed_epoch ) - j if ( f1 < 0.0 ): f1 = f1 + 1.0 j = j - 1 d0 = j n4 = 0 while ( d0 <= 0 ): d0 = d0 + cycle_length n4 = n4 - 1 n4 = n4 + floor ( d0 / cycle_length ) d1 = i4_modp ( d0, cycle_length ) n1 = floor ( d1 / year_length_days ) d2 = i4_modp ( d1, year_length_days ) if ( n1 == 4 ): j1 = 366 y1 = 4 * n4 + n1 else: j1 = d2 + 1 y1 = 4 * n4 + n1 + 1 # # Any year before 1 AD must be moved one year further back, since # this calendar does not include a year 0. # y1 = y_astronomical_to_common ( y1 ) y, m, d, f = yjf_to_ymdf_julian ( y1, j1, f1 ) return y, m, d, f def jed_to_ymdf_julian ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_julian() converts a JED to a Julian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j j_prime = j + 1401 y_prime = floor ( ( 4 * j_prime + 3 ) / 1461 ) t_prime = floor ( ( ( 4 * j_prime + 3 ) % 1461 ) / 4 ) m_prime = floor ( ( 5 * t_prime + 2 ) / 153 ) d_prime = floor ( ( ( 5 * t_prime + 2 ) % 153 ) / 5 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( ( m_prime + 2 ) % 12 ) + 1 y = y_prime - 4716 + floor ( ( 14 - m ) / 12 ) # # Any year before 1 AD must be moved one year further back, since # this calendar does not include a year 0. # y = y_astronomical_to_common ( y ) return y, m, d, f def jed_to_ymdf_khwarizmian ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_khwarizmian() converts a JED to a Khwarizmian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j j_prime = j + 317 y_prime = floor ( j_prime / 365 ) t_prime = ( j_prime % 365 ) m_prime = floor ( t_prime / 30 ) d_prime = ( t_prime % 30 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( m_prime % 13 ) + 1 y = y_prime - 5348 + floor ( ( 13 - m ) / 13 ) return y, m, d, f def jed_to_ymdf_macedonian ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_macedonian() converts a JED to a Macedonian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j j_prime = j + 1401 y_prime = floor ( ( 4 * j_prime + 3 ) / 1461 ) t_prime = floor ( ( ( 4 * j_prime + 3 ) % 1461 ) / 4 ) m_prime = floor ( ( 5 * t_prime + 2 ) / 153 ) d_prime = floor ( ( ( 5 * t_prime + 2 ) % 153 ) / 5 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( ( m_prime + 6 ) % 12 ) + 1 y = y_prime - 4405 + floor ( ( 18 - m ) / 12 ) return y, m, d, f def jed_to_ymdf_persian ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_persian() converts a JED to a Persian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j j_prime = j + 77 y_prime = floor ( j_prime / 365 ) t_prime = ( j_prime % 365 ) m_prime = floor ( t_prime / 30 ) d_prime = ( t_prime % 30 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( ( m_prime + 9 ) % 13 ) + 1 y = y_prime - 5348 + floor ( ( 22 - m ) / 13 ) return y, m, d, f def jed_to_ymdf_republican ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_republican() converts a JED to a Republican YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j g =floor ( ( 4 * j + 578797 ) / 146097 ) g = floor ( ( 3 * g ) / 4 ) - 51 j_prime = j + 111 + g y_prime = floor ( ( 4 * j_prime + 3 ) / 1461 ) t_prime = floor ( ( ( 4 * j_prime + 3 ) % 1461 ) / 4 ) m_prime = floor ( t_prime / 30 ) d_prime = ( t_prime % 30 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( m_prime % 13 ) + 1 y = y_prime - 6504 + floor ( ( 13 - m ) / 13 ) return y, m, d, f def jed_to_ymdf_roman ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_roman() converts a JED to a Roman YMDF date. # # Discussion: # # The Roman calendar used here is artificial. It is assumed to begin # on the Julian calendar date 1 January 753 BC, and to be simply a # copy of the Julian calendar, shifted by 753 years. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # y, m, d, f = jed_to_ymdf_julian ( jed ) y = y_julian_to_roman ( y ) return y, m, d, f def jed_to_ymdf_saka ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_saka() converts a JED to a Saka YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j g = floor ( ( 4 * j + 274073 ) / 146097 ) g = floor ( ( 3 * g ) / 4 ) - 36 j_prime = j + 1348 + g y_prime = floor ( ( 4 * j_prime + 3 ) / 1461 ) t_prime = floor ( ( ( 4 * j_prime + 3 ) % 1461 ) / 4 ) x = floor ( t_prime / 365 ) z = floor ( t_prime / 185 ) - x s = 31 - z m_prime = floor ( ( t_prime - 5 * z ) / s ) d_prime = 6 * x + ( ( t_prime - 5 * z ) % s ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( ( m_prime + 1 ) % 12 ) + 1 y = y_prime - 4794 + floor ( ( 13 - m ) / 12 ) return y, m, d, f def jed_to_ymdf_soor_san ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_soor_san() converts a JED to a Soor San YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor jed_epoch = epoch_to_jed_soor_san ( ) j = floor ( jed - jed_epoch ) f = ( jed - jed_epoch ) - j d = 1 + j m = 1 y = 1 # # Account for the number of completed 4 year cycles of 1461 days. # n = floor ( ( d - 1 ) / 1461 ) y = y + 4 * n d = d - n * 1461 # # Account for the number of completed 365 day years. # n = floor ( ( d - 1 ) / 365 ) y = y + n d = d - n * 365 # # Account for the number of completed 30 day months. # n = floor ( ( d - 1 ) / 30 ) m = m + n d = d - n * 30 return y, m, d, f def jed_to_ymdf_syrian ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_syrian() converts a JED to a Syrian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm F, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 324-325. # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor # # Determine the computational date (Y'/M'/D'). # j = floor ( jed + 0.5 ) f = ( jed + 0.5 ) - j j_prime = j + 1401 y_prime = floor ( ( 4 * j_prime + 3 ) / 1461 ) t_prime = floor ( ( ( 4 * j_prime + 3 ) % 1461 ) / 4 ) m_prime = floor ( ( 5 * t_prime + 2 ) / 153 ) d_prime = floor ( ( ( 5 * t_prime + 2 ) % 153 ) / 5 ) # # Convert the computational date to a calendar date. # d = d_prime + 1 m = ( ( m_prime + 5 ) % 12 ) + 1 y = y_prime - 4405 + floor ( ( 17 - m ) / 12 ) return y, m, d, f def jed_to_ymdf_zoroastrian ( jed ): #*****************************************************************************80 # ## jed_to_ymdf_zoroastrian() converts a JED to a Zoroastrian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, real F, the YMDF date. # from math import floor jed_epoch = epoch_to_jed_zoroastrian ( ) j = floor ( jed - jed_epoch ) f = ( jed - jed_epoch ) - j d = 1 + j m = 1 y = 1 years = floor ( ( d - 1 ) / 365 ) y = y + years d = d - years * 365 months = floor ( ( d - 1 ) / 30 ) m = m + months d = d - months * 30 return y, m, d, f def jed_to_ymdhms_common ( jed ): #*****************************************************************************80 # ## jed_to_ymdhms_common() converts a JED to a Common YMDHMS date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real JED, the Julian Ephemeris Date. # # Output: # # integer Y, M, D, H, N, S, the YMDHMS date. # jed_transition = transition_to_jed_common ( ) if ( jed <= jed_transition ): y1, m1, d1, f1 = jed_to_ymdf_julian ( jed ) else: y1, m1, d1, f1 = jed_to_ymdf_gregorian ( jed ) y, m, d, h, n, s = ymdf_to_ymdhms_common ( y1, m1, d1, f1 ) return y, m, d, h, n, s def jed_weekday_values ( n_data ): #*****************************************************************************80 # ## jed_weekday_values() returns the day of the week for Julian Ephemeris Dates. # # Discussion: # # The JED (Julian Ephemeris Date) is a calendrical system which counts days, # starting from noon on 1 January 4713 BCE. # # weekdays are numbered as follows: # # 1 Sunday # 2 Monday # 3 Tuesday # 4 Wednesday # 5 Thursday # 6 Friday # 7 Saturday # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 16 February 2015 # # Author: # # John Burkardt # # Reference: # # Edward Reingold and Nachum Dershowitz, # Calendrical Calculations: The Millennium Edition, # Cambridge University Press, 2001, # ISBN: 0 521 77752 6 # # Input: # # integer N_DATA. The user sets N_DATA to 0 before the first call. # # Output: # # integer N_DATA. On each call, the routine increments N_DATA by 1, # and returns the corresponding data; when there is no more data, the # output value of N_DATA will be 0 again. # real JED, the Julian Ephemeris Date. # # integer weekday, the day of the week. # import numpy as np n_max = 33 jed_vec = np.array ( (\ 1507231.5E+00, \ 1660037.5E+00, \ 1746893.5E+00, \ 1770641.5E+00, \ 1892731.5E+00, \ 1931579.5E+00, \ 1974851.5E+00, \ 2091164.5E+00, \ 2121509.5E+00, \ 2155779.5E+00, \ 2174029.5E+00, \ 2191584.5E+00, \ 2195261.5E+00, \ 2229274.5E+00, \ 2245580.5E+00, \ 2266100.5E+00, \ 2288542.5E+00, \ 2290901.5E+00, \ 2323140.5E+00, \ 2334848.5E+00, \ 2348020.5E+00, \ 2366978.5E+00, \ 2385648.5E+00, \ 2392825.5E+00, \ 2416223.5E+00, \ 2425848.5E+00, \ 2430266.5E+00, \ 2430833.5E+00, \ 2431004.5E+00, \ 2448698.5E+00, \ 2450138.5E+00, \ 2465737.5E+00, \ 2486076.5E+00 )) weekday_vec = np.array ( (\ 1, 4, 4, 1, 4, \ 2, 7, 1, 1, 6, \ 7, 6, 1, 1, 4, \ 7, 7, 7, 4, 1, \ 6, 1, 2, 4, 1, \ 1, 2, 2, 5, 3, \ 1, 4, 1 )) if ( n_data < 0 ): n_data = 0 if ( n_max <= n_data ): n_data = 0 jed = 0.0 weekday = 0 else: jed = jed_vec[n_data] weekday = weekday_vec[n_data] n_data = n_data + 1 return n_data, jed, weekday def jed_weekday_values_test ( ): #*****************************************************************************80 # ## jed_weekday_values_test() tests jed_weekday_values(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 16 February 2015 # # Author: # # John Burkardt # print ( '' ) print ( 'jed_weekday_values_test():' ) print ( ' jed_weekday_values() stores values of the weekday for a given JED.' ) print ( '' ) print ( ' JED weekday(JED)' ) print ( '' ) n_data = 0 while ( True ): n_data, jed, weekday = jed_weekday_values ( n_data ) if ( n_data == 0 ): break print ( ' %12f %d' % ( jed, weekday ) ) return def mayan_long_to_jed ( pictun, baktun, katun, tun, uinal, kin, f ): #*****************************************************************************80 # ## mayan_long_to_jed() converts a Mayan long date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm L, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 341. # # Input: # # integer PICTUN, BAKTUN, KATUN, TUN, UINAL, KIN, values # defining the Mayan long date. # # real F, the fractional part of the date. # # Output: # # real JED, the Julian Ephemeris Date. # days = ((((( pictun * 20 + baktun ) * 20 + katun ) * 20 \ + tun ) * 18 + uinal ) * 20 + kin ); jed_epoch = epoch_to_jed_mayan_long ( ) jed = jed_epoch + days + f return jed def mayan_round_to_jed ( y, a, b, c, d, f ): #*****************************************************************************80 # ## mayan_round_to_jed() converts a Mayan round date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm L, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 341. # # Input: # # integer Y, A, B, C, D, values defining the Mayan round date. # # real F, the fractional part of the date. # # Output: # # real JED, the Julian Ephemeris Date. # m = 13 * i4_modp ( 60 + 3 * ( a - b ), 20 ) + a - 1 m = i4_modp ( m + 101, 260 ) n = 20 * d + c n = i4_modp ( n + 17, 365 ) r = 365 * i4_modp ( 364 + m - n, 52 ) + n jed_epoch = epoch_to_jed_mayan_long ( ) jed = jed_epoch + 18980 * y + r + f return jed def minute_borrow_common ( y, m, d, h, n ): #*****************************************************************************80 # ## minute_borrow_common() "borrows" an hour of minutes in a Common date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 July 2012 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, H, N, the year, # month, day, hour and minute representing a date. On N # might be negative. # # Output: # # integer Y, M, D, H, N, the year, month, day, hour and minute # representing a date. H should have decreased by one, and N # gone up by 60. # while ( n < 0 ): n = n + 60 h = h - 1 y, m, d, h = hour_borrow_common ( y, m, d, h ) return y, m, d, h, n def minute_carry_common ( y, m, d, h, n ): #*****************************************************************************80 # ## minute_carry_common(): given a Common YMDHMS date, carries minutes to hours. # # Algorithm: # # While 60 <= N: # # decrease N by the number of minutes in an hour; # increase H by 1; # if necessary, adjust Y, M and D. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, H, N, the date. # # Output: # # integer Y, M, D, H, N, the date, after carrying. # N is between 0 and 59. # while ( 60 <= n ): n = n - 60 h = h + 1 y, m, d, h = hour_carry_common ( y, m, d, h ) return y, m, d, h, n def mjd_to_jed ( mjd ): #*****************************************************************************80 # ## mjd_to_jed() converts a modified JED to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # real MJD, the modified Julian Ephemeris Date. # # Output: # # real JED, the Julian Ephemeris Date. # jed_epoch = epoch_to_jed_mjd ( ) jed = mjd + jed_epoch return jed def month_borrow_alexandrian ( y, m ): #*****************************************************************************80 # ## month_borrow_alexandrian() borrows a year of months on Alexandrian calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after borrowing. # while ( m <= 0 ): months = year_length_months_alexandrian ( y ) m = m + months y = y - 1 return y, m def month_borrow_bahai ( y, m ): #*****************************************************************************80 # ## month_borrow_bahai() borrows a year of months on the Bahai calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after borrowing. # while ( m <= 0 ): months = year_length_months_bahai ( y ) m = m + months y = y - 1 end return y, m def month_borrow_common ( y, m ): #*****************************************************************************80 # ## month_borrow_common() borrows a year of months on the Common calendar. # # Discussion: # # If the month index is legal, nothing is done. If the month index # is too small, then one or more years are "cashed in" to bring the # month index up to a legal value. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, the YM date. M might be negative. # # Output: # # integer Y, M, the YM date after borrowing. # Y should have decreased by one, and M gone up by the number # of months in the year that we "cashed in". # while ( m <= 0 ): months = year_length_months_common ( y ) m = m + months y = y - 1 if ( y == 0 ): y = - 1 return y, m def month_borrow_eg_civil ( y, m ): #*****************************************************************************80 # ## month_borrow_eg_civil() borrows a year of months on Egyptian Civil calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after borrowing. # while ( m <= 0 ): months = year_length_months_eg_civil ( y ) m = m + months y = y - 1 return y, m def month_borrow_english ( y, m ): #*****************************************************************************80 # ## month_borrow_english() borrows a year of months on the English calendar. # # Discussion: # # If the month index is legal, nothing is done. If the month index # is too small, then one or more years are "cashed in" to bring the # month index up to a legal value. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after borrowing. # while ( m <= 0 ): months = year_length_months_english ( y ) m = m + months y = y - 1 if ( y == 0 ): y = - 1 return y, m def month_borrow_gregorian ( y, m ): #*****************************************************************************80 # ## month_borrow_gregorian() borrows a year of months on the Gregorian calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after borrowing. # while ( m <= 0 ): months = year_length_months_gregorian ( y ) m = m + months y = y - 1 if ( y == 0 ): y = - 1 return y, m def month_borrow_hebrew ( y, m ): #*****************************************************************************80 # ## month_borrow_hebrew() borrows a year of months on the Hebrew calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after borrowing. # while ( m <= 0 ): months = year_length_months_hebrew ( y ) m = m + months y = y - 1 return y, m def month_borrow_islamic ( y, m ): #*****************************************************************************80 # ## month_borrow_islamic() borrows a year of months on the Islamic calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after borrowing. # while ( m <= 0 ): months = year_length_months_islamic ( y ) m = m + months y = y - 1 return y, m def month_borrow_julian ( y, m ): #*****************************************************************************80 # ## month_borrow_julian() borrows a year of months on the Julian calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after borrowing. # while ( m <= 0 ): months = year_length_months_julian ( y ) m = m + months y = y - 1 if ( y == 0 ): y = - 1 return y, m def month_borrow_republican ( y, m ): #*****************************************************************************80 # ## month_borrow_republican() borrows a year of months on the Republican calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after borrowing. # while ( m <= 0 ): months = year_length_months_republican ( y ) m = m + months y = y - 1 return y, m def month_borrow_roman ( y, m ): #*****************************************************************************80 # ## month_borrow_roman() borrows a year of months on the Roman calendar. # # Discussion: # # If the month index is legal, nothing is done. If the month index # is too small, then one or more years are "cashed in" to bring the # month index up to a legal value. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after borrowing. # while ( m <= 0 ): months = year_length_months_roman ( y ) m = m + months y = y - 1 if ( y == 0 ): y = - 1 return y, m def month_carry_alexandrian ( y, m ): #*****************************************************************************80 # ## month_carry_alexandrian() carries a year of months on the Alexandrian calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after carrying. # months = year_length_months_alexandrian ( y ) while ( True ): if ( m <= months ): break m = m - months y = y + 1 return y, m def month_carry_bahai ( y, m ): #*****************************************************************************80 # ## month_carry_bahai() carries a year of months on the Bahai calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after carrying. # months = year_length_months_bahai ( y ) while ( True ): if ( m <= months ): break m = m - months y = y + 1 return y, m def month_carry_common ( y, m ): #*****************************************************************************80 # ## month_carry_common() carries a year of months on the Common calendar. # # Algorithm: # # While 12 < M: # # decrease M by 12; # increase Y by 1; # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month. M is no greater than 12. # while ( True ): months = year_length_months_common ( y ) if ( m <= months ): break m = m - months y = y + 1 return y, m def month_carry_eg_civil ( y, m ): #*****************************************************************************80 # ## month_carry_eg_civil() carries a year of months on the Egyptian Civil calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after carrying. # months = year_length_months_eg_civil ( y ) while ( True ): if ( m <= months ): break m = m - months y = y + 1 return y, m def month_carry_english ( y, m ): #*****************************************************************************80 # ## month_carry_english() carries a year of months on the English calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after carrying. # while ( True ): months = year_length_months_english ( y ) if ( m <= months ): break m = m - months y = y + 1 return y, m def month_carry_gregorian ( y, m ): #*****************************************************************************80 # ## month_carry_gregorian() carries a year of months on the Gregorian calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after carrying. # while ( True ): months = year_length_months_gregorian ( y ) if ( m <= months ): break m = m - months y = y + 1 return y, m def month_carry_hebrew ( y, m ): #*****************************************************************************80 # ## month_carry_hebrew() carries a year of months on the Hebrew calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after carrying. # while ( True ): months = year_length_months_hebrew ( y ) if ( m <= months ): break m = m - months y = y + 1 return y, m def month_carry_islamic ( y, m ): #*****************************************************************************80 # ## month_carry_islamic() carries a year of months on the Islamic calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after carrying. # while ( True ): months = year_length_months_islamic ( y ) if ( m <= months ): break m = m - months y = y + 1 return y, m def month_carry_julian ( y, m ): #*****************************************************************************80 # ## month_carry_julian() carries a year of months on the Julian calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after carrying. # while ( True ): months = year_length_months_julian ( y ) if ( m <= months ): break m = m - months y = y + 1 return y, m def month_carry_republican ( y, m ): #*****************************************************************************80 # ## month_carry_republican() carries a year of months on the Republican calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after carrying. # while ( True ): months = year_length_months_republican ( y ) if ( m <= months ): return y, m m = m - months y = y + 1 return y, m def month_carry_roman ( y, m ): #*****************************************************************************80 # ## month_carry_roman() carries a year of months on the Roman calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the year and month. # # Output: # # integer Y, M, the year and month after carrying. # while ( True ): months = year_length_months_roman ( y ) if ( m <= months ): break m = m - months y = y + 1 return y, m def month_length_alexandrian ( y, m ): #*****************************************************************************80 # ## month_length_alexandrian() returns the number of days in an Alexandrian month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer days: the number of days in the month. # mdays = [ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 5 ] # # Copy the input. # m2 = m y2 = y if ( m2 < 1 or 13 < m2 ): days = 0 else: days = mdays[m2-1] if ( m2 == 13 and year_is_leap_alexandrian ( y2 ) ): days = days + 1 return days def month_length_bahai ( y, m ): #*****************************************************************************80 # ## month_length_bahai() returns the number of days in a Bahai month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer DAYS, the number of days in the month. # # # Copy the input. # m2 = m y2 = y # # Check the input. # y2, m2, ierror = ym_check_bahai ( y2, m2 ) if ( ierror ): days = 0 return days if ( m2 <= 18 or m2 == 20 ): days = 19 elif ( year_is_leap_bahai ( y2 ) ): days = 5 else: days = 4 return days def month_length_common ( y, m ): #*****************************************************************************80 # ## month_length_common() returns the number of days in a Common month. # # Discussion: # # The "common" calendar is meant to be the calendar which is Julian up to # day JED = 2299160, and Gregorian from day JED = 2299161 and after. # # The routine knows that February has 28 days, except in leap years, # when it has 29. # # In the Common calendar, October 1582 had only 21 days # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, the year in which the month occurred. # # integer M, the number of the month. # # Output: # # integer DAYS, the number of days # in the month. # import numpy as np mdays = np.array ( [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ] ) # # Check the input. # y2, m2, ierror = ym_check_common ( y, m ) if ( ierror ): days = 0 return days # # Take care of the special case. # if ( y2 == 1582 ): if ( m2 == 10 ): days = 21 return days # # Get the number of days in the month. # days = mdays[m2-1] # # If necessary, add 1 day for February 29. # if ( m2 == 2 and year_is_leap_common ( y2 ) ): days = days + 1 return days def month_length_coptic ( y, m ): #*****************************************************************************80 # ## month_length_coptic() returns the number of days in a Coptic month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer DAYS, the number of days in the month. # mdays = [ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 5 ] # # Copy the input. # m2 = m y2 = y if ( m2 < 1 or 13 < m2 ): days = 0 else: days = mdays[m2-1] if ( m2 == 13 and year_is_leap_coptic ( y2 ) ): days = days + 1 return days def month_length_eg_civil ( y, m ): #*****************************************************************************80 # ## month_length_eg_civil() returns the number of days in an Egyptian Civil month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer DAYS, the number of days in the month. # if ( m < 1 ): days = 0 elif ( m <= 12 ): days = 30 elif ( m == 13 ): days = 5 else: days = 0 return days def month_length_eg_lunar ( y, m ): #*****************************************************************************80 # ## month_length_eg_lunar() returns the number of days in an Egyptian Lunar month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer DAYS, the number of days in the month. # mdays = [ 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 30 ] # # Copy the input. # m2 = m y2 = y last = year_length_months_eg_lunar ( y2 ) if ( m2 < 1 ): days = 0 elif ( m2 <= last ): days = mdays[m2-1] else: days = 0 if ( m2 == last ): if ( year_is_leap_eg_lunar ( y ) ): days = days + 1 return days def month_length_english ( y, m ): #*****************************************************************************80 # ## month_length_english() returns the number of days in an English month. # # Discussion: # # In the English calendar, September 1752 had only 19 days. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer DAYS, the number of days in the month. # mdays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ] # # Copy the input. # m2 = m y2 = y # # Check the input. # y2, m2, ierror = ym_check_english ( y2, m2 ) if ( ierror ): days = 0 return days # # Take care of special cases: # if ( y2 == 1752 ): if ( m2 == 9 ): days = 19 return days # # Get the number of days in the month. # days = mdays[m2-1] # # If necessary, add 1 day for February 29. # if ( m2 == 2 and year_is_leap_english ( y2 ) ): days = days + 1 return days def month_length_ethiopian ( y, m ): #*****************************************************************************80 # ## month_length_ethiopian() returns the number of days in an Ethiopian month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer DAYS, the number of days in the month. # mdays = [ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 5 ] # # Copy the input. # m2 = m y2 = y if ( m2 < 1 or 13 < m2 ): days = 0 else: days = mdays[m2-1] if ( m2 == 13 and year_is_leap_ethiopian ( y2 ) ): days = days + 1 return days def month_length_greek ( y, m ): #*****************************************************************************80 # ## month_length_greek() returns the number of days in a Greek month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer DAYS, the number of days in the month. # mdays = [ 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 29 ] # # Copy the input. # m2 = m y2 = y if ( m2 < 1 ): days = 0 return days # # A 13-month year. # if ( year_is_embolismic_greek ( y2 ) ): if ( 13 < m2 ): days = 0 return days days = mdays[m2-1] if ( m2 == 7 and year_is_leap_greek ( y2 ) ): days = days + 1 # # A 12 month year. # else: if ( m2 <= 6 ): days = mdays[m2-1] elif ( m2 <= 12 ): days = mdays[m2] else: days = 0 return days def month_length_gregorian ( y, m ): #*****************************************************************************80 # ## month_length_gregorian() returns the number of days in a Gregorian month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer DAYS, the number of days in the month. # mdays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ] # # Copy the input. # m2 = m y2 = y # # Check the input. # y2, m2, ierror = ym_check_gregorian ( y2, m2 ) if ( ierror ): days = 0 return days # # Get the number of days in the month. # days = mdays[m2-1] # # If necessary, add 1 day for February 29. # if ( m2 == 2 ): if ( year_is_leap_gregorian ( y2 ) ): days = days + 1 return days def month_length_hebrew ( y, m ): #*****************************************************************************80 # ## month_length_hebrew() returns the number of days in a Hebrew month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 333. # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer DAYS, the number of days in the month. # a = [ \ [ 30, 29, 29, 29, 30, 29, 30, 29, 30, 29, 30, 29, 0 ], \ [ 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 0 ], \ [ 30, 30, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 0 ], \ [ 30, 29, 29, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29 ], \ [ 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29, 20, 29 ], \ [ 30, 30, 30, 29, 30, 30, 30, 29, 29, 30, 29, 30, 20 ] ] # # Copy the input # y2 = y m2 = m # # Check the input. # y2, m2, ierror = ym_check_hebrew ( y2, m2 ) if ( ierror ): days = 0 return days type = year_to_type_hebrew ( y2 ) if ( type < 1 or 6 < type ): print ( '\n' ) print ( 'month_length_hebrew(): Fatal error!\n' ) print ( ' Illegal year TYPE = ', type ) print ( ' Y = ', y2 ) raise Exception ( 'month_length_hebrew(): Fatal error!' ) if ( m2 < 1 or 13 < m2 ): print ( '\n' ) print ( 'month_length_hebrew(): Fatal error!\n' ) print ( ' Illegal MONTH = ', m2 ) raise Exception ( 'month_length_hebrew(): Fatal error!' ) days = a[type-1,m2-1] return days def month_length_hindu_solar ( y, m ): #*****************************************************************************80 # ## month_length_hindu_solar() returns the number of days in a Hindu solar month. # # Discussion: # # DAYS is a REAL quantity, with a fractional part. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # real DAYS, the number of days in the month. # days = year_length_days_hindu_solar ( y ) / 12.0 return days def month_length_iranian ( y, m ): #*****************************************************************************80 # ## month_length_iranian() returns the number of days in an Iranian month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer DAYS, the number of days in the month. # mdays = [ 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 ] # # Copy the input. # m2 = m y2 = y # # Get the number of days in the month. # days = mdays[m2-1] # # If necessary, add 1 day for a leap year.. # if ( m2 == 12 and year_is_leap_iranian ( y2 ) ): days = days + 1 return days def month_length_islamic ( y, m ): #*****************************************************************************80 # ## month_length_islamic() returns the number of days in an Islamic month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer days: the number of days in the month. # mdays = [ 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29 ] # # Copy the input. # m2 = m y2 = y # # Check the input. # y2, m2, ierror = ym_check_islamic ( y2, m2 ) if ( ierror ): days = 0 return days # # Get the number of days in the month. # days = mdays[m2-1] # # If necessary, add 1 day for a leap year. # if ( m2 == 12 and year_is_leap_islamic ( y2 ) ): days = days + 1 return days def month_length_julian ( y, m ): #*****************************************************************************80 # ## month_length_julian() returns the number of days in a Julian month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer days: the number of days in the month. # mdays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ] # # Copy the input. # m2 = m y2 = y # # Check the input. # y2, m2, ierror = ym_check_julian ( y2, m2 ) if ( ierror ): days = 0 return days # # Get the number of days in the month. # days = mdays[m2-1] # # If necessary, add 1 day for February 29. # if ( m2 == 2 and year_is_leap_julian ( y2 ) ): days = days + 1 return days def month_length_lunar ( y, m ): #*****************************************************************************80 # ## month_length_lunar() returns the number of days in a lunar month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # real DAYS, the number of days in the month. # if ( m < 1 or 12 < m ): days = 0.0 else: days = 29.53058 return days def month_length_persian ( y, m ): #*****************************************************************************80 # ## month_length_persian() returns the number of days in a Persian month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer DAYS, the number of days in the month. # mdays = [ 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 ] # # Copy the input. # m2 = m y2 = y # # Get the number of days in the month. # days = mdays[m2-1] # # If necessary, add 1 day for a leap year. # if ( m2 == 12 and year_is_leap_persian ( y2 ) ): days = days + 1 return days def month_length_republican ( y, m ): #*****************************************************************************80 # ## month_length_republican() returns the number of days in a Republican month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer DAYS, the number of days in the month. # # # Copy the input. # m2 = m y2 = y # # Check the input. # y2, m2, ierror = ym_check_republican ( y2, m2 ) if ( ierror ): days = 0 return days # # Get the number of days in the month. # if ( 1 <= m2 and m2 <= 12 ): days = 30 elif ( m2 == 13 ): if ( year_is_leap_republican ( y2 ) ): days = 6 else: days = 5 return days def month_length_roman ( y, m ): #*****************************************************************************80 # ## month_length_roman() returns the number of days in a Roman month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # integer DAYS, the number of days in the month. # mdays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ] # # Copy the input. # m2 = m y2 = y # # Check the input. # y2, m2, ierror = ym_check_roman ( y2, m2 ) if ( ierror ): days = 0 return days days = mdays[m2-1] if ( m2 == 2 and year_is_leap_roman ( y2 ) ): days = days + 1 return days def month_length_synodic ( y, m ): #*****************************************************************************80 # ## month_length_synodic() returns the mean synodic month length. # # Discussion: # # The synodic month is the time from one new moon to the next, that is, # when the moon and Sun are in conjunction. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # integer M, the month. # # Output: # # real DAYS, the number of days in the month. # days = 29.530588853 return days def month_to_ides_roman ( m ): #*****************************************************************************80 # ## month_to_ides_roman() returns the day of the ides of a Roman month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # integer D: the day of the ides of the month. # ides = [ 13, 13, 15, 13, 15, 13, 15, 13, 13, 15, 13, 13 ] if ( m < 1 or 12 < m ): d = -1 else: d = ides[m-1] return d def month_to_month_name_bahai ( m ): #*****************************************************************************80 # ## month_to_month_name_bahai() returns the name of a Bahai month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Baha', 'Jalal', 'Jamal', 'Azamat', \ 'Nur', 'Rahmat', 'Kalimat', 'Kamal', \ 'Asma', 'Izzat', 'Mashiyyat', 'Ilm', \ 'Qudrat', 'Qawl', 'Masail', 'Sharaf', \ 'Sultan', 'Mulk', 'Ayyam-i-Ha', 'Ala' ] if ( m < 1 or 20 < m ): month_name = '?????' else: month_name = name[m-1] return month_name def month_to_month_name_common ( m ): #*****************************************************************************80 # ## month_to_month_name_common() returns the name of a Common month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 22 December 2017 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string month_name, the month name. # if ( m == 1 ): month_name = 'January' elif ( m == 2 ): month_name = 'February' elif ( m == 3 ): month_name = 'March' elif ( m == 4 ): month_name = 'April' elif ( m == 5 ): month_name = 'May' elif ( m == 6 ): month_name = 'June' elif ( m == 7 ): month_name = 'July' elif ( m == 8 ): month_name = 'August' elif ( m == 9 ): month_name = 'September' elif ( m == 10 ): month_name = 'October' elif ( m == 11 ): month_name = 'November' elif ( m == 12 ): month_name = 'December' else: print ( '' ) print ( 'weekday_to_name_common(): Fatal error!' ) print ( ' Index M must be between 1 and 12.' ) raise Exception ( 'weekday_to_name_common(): Fatal error!' ) return month_name def month_to_month_name_common_test ( ): #*****************************************************************************80 # ## month_to_month_name_common_test() tests month_to_month_name_common(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 22 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'month_to_month_name_common_test():' ) print ( ' month_to_month_name_common() names the months.' ) print ( '' ) for m in range ( 1, 13 ): month_name = month_to_month_name_common ( m ) print ( ' %2d %s' % ( m, month_name ) ) return def month_to_month_name_common3 ( m ): #*****************************************************************************80 # ## month_to_month_name_common3() returns an abbreviation of a Common month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 22 December 2017 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string month_name, the month name. # if ( m == 1 ): month_name = 'Jan' elif ( m == 2 ): month_name = 'Feb' elif ( m == 3 ): month_name = 'Mar' elif ( m == 4 ): month_name = 'Apr' elif ( m == 5 ): month_name = 'May' elif ( m == 6 ): month_name = 'Jun' elif ( m == 7 ): month_name = 'Jul' elif ( m == 8 ): month_name = 'Aug' elif ( m == 9 ): month_name = 'Sep' elif ( m == 10 ): month_name = 'Oct' elif ( m == 11 ): month_name = 'Nov' elif ( m == 12 ): month_name = 'Dec' else: print ( '' ) print ( 'weekday_to_name_common3(): Fatal error!' ) print ( ' Index M must be between 1 and 12.' ) raise Exception ( 'weekday_to_name_common3(): Fatal error!' ) return month_name def month_to_month_name_common3_test ( ): #*****************************************************************************80 # ## month_to_month_name_common3_test() tests month_to_month_name_common3(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 22 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'month_to_month_name_common3_test():' ) print ( ' month_to_month_name_common3() names the months.' ) print ( '' ) for m in range ( 1, 13 ): month_name = month_to_month_name_common3 ( m ) print ( ' %2d %s' % ( m, month_name ) ) return def month_to_month_name_coptic ( m ): #*****************************************************************************80 # ## month_to_month_name_coptic() returns the name of a Coptic month. # # Discussion: # # The names are closely related to the month names of the Egyptian # Civil calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Tut', \ 'Babah', \ 'Hatur', \ 'Kiyahk', \ 'Tubah', \ 'Amshir', \ 'Baramhat', \ 'Baramundah', \ 'Bashans', \ 'Ba\'unah', \ 'Abib', \ 'Misra', \ 'al-Nasi' ] if ( m < 1 or 13 < m ): month_name = '?????' else: month_name = name[m-1] return month_name def month_to_month_name_eg_civil ( m ): #*****************************************************************************80 # ## month_to_month_name_eg_civil() returns the name of an Egyptian Civil month. # # Discussion: # # The 13th month had only 5 days, which were treated as the birthdays # of Osiris, Horus, Set, Isis and Nephthys. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # if ( m == 1 ): month_name = 'Thoth' elif ( m == 2 ): month_name = 'Phaophi' elif ( m == 3 ): month_name = 'Hathyr' elif ( m == 4 ): month_name = 'Choiak' elif ( m == 5 ): month_name = 'Tybi' elif ( m == 6 ): month_name = 'Mecheir' elif ( m == 7 ): month_name = 'Phamenoth' elif ( m == 8 ): month_name = 'Pharmouthi' elif ( m == 9 ): month_name = 'Pachon' elif ( m == 10 ): month_name = 'Payni' elif ( m == 11 ): month_name = 'Epeiph' elif ( m == 12 ): month_name = 'Mesore' elif ( m == 13 ): month_name = 'Epagomenai' else: print ( '' ) print ( 'month_to_month_name_eg_civil(): Fatal error!' ) print ( ' Index M must be between 1 and 13.' ) raise Exception ( 'month_to_month_name_eg_civil(): Fatal error!' ) return month_name def month_to_month_name_eg_lunar ( m ): #*****************************************************************************80 # ## month_to_month_name_eg_lunar() returns the name of an Egyptian Lunar month. # # Discussion: # # "Akhet" means "flood", # "Peret" means "going forth" (for planting), # "Shomu" means "deficiency" (the dry season). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Akhet I', \ 'Akhet II', \ 'Akhet III', \ 'Akhet IV', \ 'Peret I', \ 'Peret II', \ 'Peret III', \ 'Peret IV', \ 'Shomu I', \ 'Shomu II', \ 'Shomu III', \ 'Shomu IV', \ 'Shomu V' ] if ( m < 1 or 13 < m ): month_name = '?????' else: month_name = name[m-1] return month_name def month_to_month_name_ethiopian ( m ): #*****************************************************************************80 # ## month_to_month_name_ethiopian() returns the name of an Ethiopian month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Maskaram', \ 'Teqemt', \ 'Khedar', \ 'Takhsas', \ 'Ter', \ 'Yakatit', \ 'Magabit', \ 'Miyazya', \ 'Genbot', \ 'Sane', \ 'Hamle', \ 'Nahase', \ 'Paguemen' ] if ( m < 1 or 13 < m ): month_name = '?????' else: month_name = name[m-1] return month_name def month_to_month_name_greek ( y, m ): #*****************************************************************************80 # ## month_to_month_name_greek() returns the name of a Greek month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Hecatombaeon', \ 'Metageitnion', \ 'Boedromion', \ 'Pyanepsion', \ 'Maemacterion', \ 'Poseidon', \ 'Poseidon II', \ 'Gamelion', \ 'Anthesterion', \ 'Elaphebolion', \ 'Munychion', \ 'Thargelion', \ 'Scirophorion' ] # # 13 month year. # if ( year_is_embolismic_greek ( y ) ): if ( m < 1 or 13 < m ): month_name = '?????' else: month_name = name[m-1] # # 12 month year. # else: if ( m < 1 or 12 < m ): month_name = '?????' elif ( m <= 6 ): month_name = name[m-1] else: month_name = name[m] return month_name def month_to_month_name_hebrew ( y, m ): #*****************************************************************************80 # ## month_to_month_name_hebrew() returns the name of a Hebrew month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Tishri', \ 'Heshvan', \ 'Kislev', \ 'Tebet', \ 'Shebat', \ 'Adar', \ 'Veadar', \ 'Nisan', \ 'Iyar', \ 'Sivan', \ 'Tammuz', \ 'Ab', \ 'Elul' ] if ( year_is_embolismic_hebrew ( y ) ): if ( m < 1 or 13 < m ): month_name = '?????' else: month_name = name[m-1] else: if ( m < 1 or 12 < m ): month_name = '?????' elif ( m <= 6 ): month_name = name[m-1] else: month_name = name[m] return month_name def month_to_month_name_hindu_lunar ( m ): #*****************************************************************************80 # ## month_to_month_name_hindu_lunar() returns the name of a Hindu lunar month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Chaitra', \ 'Vaisakha', \ 'Jyaishtha', \ 'Ashadha', \ 'Sravana', \ 'Bhadrapada', \ 'Asvina', \ 'Karttika', \ 'Margasira', \ 'Pausha', \ 'Magha', \ 'Phalguna' ] if ( m < 1 or 12 < m ): month_name = '??????????' else: month_name = name[m-1] return month_name def month_to_month_name_hindu_solar ( m ): #*****************************************************************************80 # ## month_to_month_name_hindu_solar() returns the name of a Hindu solar month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Mesha', \ 'Vrshabha', \ 'Mithuna', \ 'Karka', \ 'Simha', \ 'Kanya', \ 'Tula', \ 'Vrischika', \ 'Dhanus', \ 'Makara', \ 'Kumbha', \ 'Mina' ] if ( m < 1 or 12 < m ): month_name = '??????????' else: month_name = name[m-1] return month_name def month_to_month_name_iranian ( m ): #*****************************************************************************80 # ## month_to_month_name_iranian() returns the name of an Iranian month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Farvardin', \ 'Ordibehesht', \ 'Xordad', \ 'Tir', \ 'Mordad', \ 'Shahrivar', \ 'Mehr', \ 'Aban', \ 'Azar', \ 'Dey', \ 'Bahman', \ 'Esfand' ] if ( m < 1 or 12 < m ): month_name = '??????????' else: month_name = name[m-1] return month_name def month_to_month_name_islamic ( m ): #*****************************************************************************80 # ## month_to_month_name_islamic() returns the name of an Islamic month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Muharram', \ 'Safar', \ 'Rabi I', \ 'Rabi II', \ 'Jumada I', \ 'Jumada II', \ 'Rajab', \ 'Shaban', \ 'Ramadan', \ 'Shawwal', \ 'Dhul-quda', \ 'Dhul-hejji' ] if ( m < 1 or 12 < m ): month_name = '??????????' else: month_name = name[m-1] return month_name def month_to_month_name_persian ( m ): #*****************************************************************************80 # ## month_to_month_name_persian() returns the name of a Persian month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Farvardin', \ 'Ordibehesht', \ 'Khordad', \ 'Tir', \ 'Mordad', \ 'Shahrivar', \ 'Mehr', \ 'Aban', \ 'Azar', \ 'Dey', \ 'Bahman', \ 'Esfand' ] if ( m < 1 or 12 < m ): month_name = '???????????' else: month_name = name[m-1] return month_name def month_to_month_name_republican2 ( m ): #*****************************************************************************80 # ## month_to_month_name_republican2() returns the mock name of a Republican month. # # Discussion: # # The mock names were devised by George Ellis, were only provided for the # 12 main months, and begin with a translation of Nivose, which is roughly # January. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Snowy', \ 'Flowy', \ 'Blowy', \ 'Showery', \ 'Flowery', \ 'Bowery', \ 'Hoppy', \ 'Croppy', \ 'Droppy', \ 'Breezy', \ 'Sneezy', \ 'Freezy' ] if ( m < 1 or 12 < m ): month_name = '???????' else: month_name = name[m-1] return month_name def month_to_month_name_republican ( m ): #*****************************************************************************80 # ## month_to_month_name_republican() returns the name of a Republican month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Vendemaire', \ 'Brumaire', \ 'Frimaire', \ 'Nivose', \ 'Pluviose', \ 'Ventose', \ 'Germinal', \ 'Floreal', \ 'Prairial', \ 'Messidor', \ 'Thermidor', \ 'Fructidor', \ 'Sansculottides' ] if ( m < 1 or 13 < m ): month_name = '??????????????' else: month_name = name[m-1] return month_name def month_to_month_name_roman ( m ): #*****************************************************************************80 # ## month_to_month_name_roman() returns the name of a Roman month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Januarius', \ 'Februarius', \ 'Martius', \ 'Aprilis', \ 'Maius', \ 'Junius', \ 'Julius', \ 'Augustus', \ 'September', \ 'October', \ 'November', \ 'December' ] if ( m < 1 or 12 < m ): month_name = '??????????' else: month_name = name[m-1] return month_name def month_to_month_name_zoroastrian ( m ): #*****************************************************************************80 # ## month_to_month_name_zoroastrian() returns the name of a Zoroastrian month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # string MONTH_NAME, the month name. # name = [ \ 'Furvurdeen', \ 'Ardibehest', \ 'Khordad', \ 'Tir', \ 'Amerdad', \ 'Sherever', \ 'Moher', \ 'Aban', \ 'Adur', \ 'Deh', \ 'Bahman', \ 'Aspendadmad' ] if ( m < 1 or 12 < m ): month_name = '?????' else: month_name = name[m-1] return month_name def month_to_nones_roman ( m ): #*****************************************************************************80 # ## month_to_nones_roman() returns the day of the nones of a Roman month. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer M, the month index. # # Output: # # integer D, the day of the nones of the month. # nones = [ 5, 5, 7, 5, 7, 5, 7, 5, 5, 7, 5, 5 ] if ( m < 1 or 12 < m ): d = -1 else: d = nones[m-1] return d def moon_phase_to_jed ( n, phase ): #*****************************************************************************80 # ## moon_phase_to_jed() calculates the JED of a moon phase. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Reference: # # William Press, Brian Flannery, Saul Teukolsky, William Vetterling, # Numerical Recipes: The Art of Scientific Computing, # Cambridge University Press. # # Input: # # integer N, specifies that the N-th such phase # of the moon since January 1900 is to be computed. # # integer PHASE, specifies which phase is to be computed. # 0=new moon, # 1=first quarter, # 2=full, # 3=last quarter. # # Output: # # real JED, the Julian Ephemeris Date on which the # requested phase occurs. # import numpy as np degrees_to_radians = np.pi / 180.0; # # First estimate. # j = 2415020 + 28 * n + 7 * phase; # # Compute a correction term. # c = n + phase / 4.0; t = c / 1236.85; xtra = 0.75933 + 1.53058868 * c + ( 0.0001178 - 0.000000155 * t ) * t * t ast = degrees_to_radians * ( 359.2242 + 29.105356 * c ) am = degrees_to_radians * ( 306.0253 + 385.816918 * c + 0.010730 * t * t ) if ( phase == 0 or phase == 2 ): xtra = xtra + ( 0.1734 - 0.000393 * t ) * np.sin ( ast ) - 0.4068 * np.sin ( am ) elif ( phase == 1 or phase == 3 ): xtra = xtra + ( 0.1721 - 0.0004 * t ) * np.sin ( ast ) - 0.6280 * np.sin ( am ) else: print ( '' ) print ( 'moon_phase_to_jed(): Fatal error!' ) print ( ' Illegal PHASE option = ', phase ) raise Exception ( 'moon_phase_to_jed(): Fatal error!' ) jed = j + xtra; return jed def mothers_day ( y ): #*****************************************************************************80 # ## mothers_day() computes the date of Mother's Day (US) for a Common year. # # Discussion: # # Mother's Day occurs on the second Sunday in May. # # Example: # # Input: # # Y = 2003 # # Output: # # M = 5 # D = 11 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer M, D, the month and day of Mother's Day. # # # Determine the day of the week for 8 May, the earliest day # that Mother's day can occur. # m = 5 d = 8 f = 0.0 w = ymdf_to_weekday_common ( y, m, d, f ) # # W = 1 means this day is Sunday, and day D is Mother's day. # Otherwise, figure out how to increment W to 8 (Sunday again); # The same increment makes D the correct day number. # if ( w != 1 ): d = d + 8 - w return d def new_year_to_jed_hebrew ( y ): #*****************************************************************************80 # ## new_year_to_jed_hebrew() returns the JED of the beginning of a Hebrew year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm G, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 330. # # Input: # # integer Y, the Hebrew year. # # Output: # # real JED, the Julian Ephemeris Date. # from math import floor mu = floor ( ( 235 * y - 234 ) / 19 ) tc = 204 + 793 * mu th = 5 + 12 * mu + floor ( tc / 1080 ) d = 1 + 29 * mu + floor ( th / 24 ) t_prime = ( tc % 1080 ) + 1080 * ( th % 24 ) w = i4_wrap ( d + 1, 1, 7 ) e = floor ( ( ( 7 * y + 13 ) % 19 ) / 12 ) e_prime = floor ( ( ( 7 * y + 6 ) % 19 ) / 12 ) if ( 19940 <= t_prime or \ ( 9924 <= t_prime and w == 3 and e == 0 ) or \ ( 16788 <= t_prime and w == 2 and e == 0 and e_prime == 1 ) ): d = d + 1 jed_epoch = epoch_to_jed_hebrew ( ) jed = jed_epoch - 1 + d + ( ( ( d + 5 ) % 7 ) % 2 ) return jed def now_to_jed ( ): #*****************************************************************************80 # ## now_to_jed() expresses the current date as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the JED for the current date. # import time c = time.localtime ( ); y = c[0]; m = c[1]; d = c[2]; h = c[3]; n = c[4]; s = c[5]; jed = ymdhms_to_jed_common ( y, m, d, h, n, s ); return jed def r8_mod ( x, y ): #*****************************************************************************80 # ## r8_mod() returns the remainder of R8 division. # # Formula: # # If # REM = r8_mod ( X, Y ) # RMULT = ( X - REM ) / Y # then # X = Y * RMULT + REM # where REM has the same sign as X, and abs ( REM ) < Y. # # Example: # # X Y r8_mod r8_mod Factorization # # 107 50 7 107 = 2 * 50 + 7 # 107 -50 7 107 = -2 * -50 + 7 # -107 50 -7 -107 = -2 * 50 - 7 # -107 -50 -7 -107 = 2 * -50 - 7 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 25 July 2014 # # Author: # # John Burkardt # # Input: # # real X, the number to be divided. # # real Y, the number that divides X. # # Output: # # real VALUE, the remainder when X is divided by Y. # if ( y == 0.0 ): print ( '' ) print ( 'r8_mod(): Fatal error!' ) print ( ' r8_mod ( X, Y ) called with Y = 0.' ) raise Exception ( 'r8_mod(): Fatal error!' ) value = x - int ( x / y ) * y if ( x < 0.0 and 0.0 < value ): value = value - abs ( y ) elif ( 0.0 < x and value < 0.0 ): value = value + abs ( y ) return value def r8_mod_test ( ): #*****************************************************************************80 # ## r8_mod_test() tests r8_mod(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 25 July 2014 # # Author: # # John Burkardt # from numpy.random import default_rng import numpy as np rng = default_rng ( ) test_num = 10 print ( '' ) print ( 'r8_mod_test():' ) print ( ' r8_mod() returns the remainder after division.' ) print ( '' ) print ( ' X Y (X%Y) r8_mod(X,Y)' ) print ( '' ) x_lo = -10.0 x_hi = +10.0 for test in range ( 0, test_num ): x = - 10.0 + 20.0 * rng.random ( ) y = - 10.0 + 20.0 * rng.random ( ) z1 = x % y z2 = r8_mod ( x, y ) print ( ' %12f %12f %12f %12f' % ( x, y, z1, z2 ) ) return def rd_to_jed ( rd ): #*****************************************************************************80 # ## rd_to_jed() converts an RD to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # real RD, the RD Date. # # Output: # # real JED, the Julian Ephemeris Date. # rd_epoch = epoch_to_jed_rd ( ) jed = rd_epoch + rd return jed def second_borrow_common ( y, m, d, h, n, s ): #*****************************************************************************80 # ## second_borrow_common() "borrows" a minute of seconds in a common date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, H, N, S, the YMDHMS date. # # Output: # # integer Y, M, D, H, N, S, the YMDHMS date after borrowing. # while ( s < 0 ): s = s + 60 n = n - 1 y, m, d, h, n = minute_borrow_common ( y, m, d, h, n ) return y, m, d, h, n, s def second_carry_common ( y, m, d, h, n, s ): #*****************************************************************************80 # ## second_carry_common(): given a Common YMDHMS date, carries seconds to minutes. # # Algorithm: # # While 60 <= S: # # decrease S by 60; # increase N by 1; # if necessary, adjust H, D, M and Y. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 Deember 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, H, N, S, the year, month, day, hours, minutes, seconds. # # Output: # # integer Y, M, D, H, N, S, the updated information after carrying. # S is between 0 and 59. # while ( 60 <= s ): s = s - 60 n = n + 1 y, m, d, h, n = minute_carry_common ( y, m, d, h, n ) return y, m, d, h, n, s def ss_to_jed_unix ( s ): #*****************************************************************************80 # ## ss_to_jed_unix() converts a UNIX SS date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # real S, the UNIX date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # jed_epoch = epoch_to_jed_unix ( ) d = s / ( 24.0 * 60.0 * 60.0 ) jed = jed_epoch + d return jed def thanksgiving_canada ( y ): #*****************************************************************************80 # ## thanksgiving_canada() computes Canadian Thanksgiving for a Common year. # # Discussion: # # Canadian Thanksgiving occurs on the second Monday in October. # # Example: # # Input: # # Y = 2002 # # Output: # # M = 11 # D = 28 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer M, D, the month and day of Thanksgiving. # # # Determine the day of the week for 8 October, the earliest day # that Thanksgiving can occur. # m = 10 d = 8 f = 0.0 w = ymdf_to_weekday_common ( y, m, d, f ) # # If W = 2 means this day is Monday, and day D is Thanksgiving. # Otherwise, figure out how to increment W to 2; # The same increment makes D the correct day number. # if ( w < 2 ): d = d + 2 - w elif ( 2 < w ): d = d + 2 + 7 - w return m, d def thanksgiving_us ( y ): #*****************************************************************************80 # ## thanksgiving_us() computes the date of Thanksgiving (US) for a Common year. # # Discussion: # # Thanksgiving (US) occurs on the fourth Thursday in November. # # Example: # # Input: # # Y = 2002 # # Output: # # M = 11 # D = 28 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer M, D, the month and day of Thanksgiving. # # # Determine the day of the week for 22 November, the earliest day # that Thanksgiving can occur. # m = 11 d = 22 f = 0.0 w = ymdf_to_weekday_common ( y, m, d, f ) # # W = 5 means this day is Thursday, and day D is Thanksgiving. # Otherwise, figure out how to increment W to 5; # The same increment makes D the correct day number. # if ( w < 5 ): d = d + 5 - w elif ( 5 < w ): d = d + 12 - w return m, d def timestamp ( ): #*****************************************************************************80 # ## timestamp() prints the date as a timestamp. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 April 2013 # # Author: # # John Burkardt # import time t = time.time ( ) print ( time.ctime ( t ) ) return def transition_to_jed_common ( ): #*****************************************************************************80 # ## transition_to_jed_common() returns the Common calendar transition as a JED. # # Discussion: # # In the Common calendar, the last moment of the Julian calendar was # 11:59 pm, 4 October 1582 Julian/CE, # 11:59 pm, 14 October 1582 Gregorian. # The first minute of the Gregorian calendar ended at # 12:01 am, 5 October 1582 Julian, # 12:01 am, 15 October 1582 Gregorian/CE. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 25 December 2017 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the date. # jed = 2299160.5 return jed def transition_to_jed_english ( ): #*****************************************************************************80 # ## transition_to_jed_english() returns the English calendar transition as a JED. # # Discussion: # # In the English calendar, the last moment of the Julian calendar was # 11:59 pm, 2 September 1752 Julian/English, # 11:59 pm, 13 September 1752 Gregorian/CE. # The first minute of the Gregorian calendar ended at # 12:01 am, 3 September 1752 Julian, # 12:01 am, 15 September 1752 Gregorian/CE/English. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 04 September 2024 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the date. # jed = 2361221.5 return jed def transition_to_jed_jed ( ): #*****************************************************************************80 # ## transition_to_jed_jed() returns the JED calendar transition as a JED. # # Discussion: # # In Scaliger's design of the JED, three cycles with different periods # began on JED = 0. These three cycles coincide once more on the # transition day. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the date. # jed = 2913943.0 return jed def transition_to_jed_mayan_long ( ): #*****************************************************************************80 # ## transition_to_jed_mayan_long(): Mayan long count calendar transition as a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Output: # # real JED, the Julian Ephemeris Date of the date. # jed = 2456282.5 return jed def weekday_check_common ( w ): #*****************************************************************************80 # ## weekday_check_common() makes sure the Common weekday number is between 1 and 7. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer W, the weekday index. # # Output: # # integer W, the weekday index after wrapping. # w = i4_wrap ( w, 1, 7 ) return w def weekday_to_name_bahai ( w ): #*****************************************************************************80 # ## weekday_to_name_bahai() returns the name of a Bahai weekday. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer W, the weekday index. # # Output: # # string S, the weekday name. # weekday_name = [ \ 'Jalal', \ 'Jamal', \ 'Kamal', \ 'Fidal', \ 'Idal ', \ 'Istijlal', \ 'Istiqlal' ] # # Make a local copy of the weekday number. # w2 = w # # Check the weekday number. # weekday_check_common ( w2 ) # # Return the weekday name. # s = weekday_name[w2-1] return s def weekday_to_name_common ( w ): #*****************************************************************************80 # ## weekday_to_name_common() returns the name of a Common weekday. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 28 August 1999 # # Author: # # John Burkardt # # Input: # # integer W, the weekday index. # # Output: # # string S, the weekday name. # if ( w == 1 ): s = 'Sunday' elif ( w == 2 ): s = 'Monday' elif ( w == 3 ): s = 'Tuesday' elif ( w == 4 ): s = 'Wednesday' elif ( w == 5 ): s = 'Thursday' elif ( w == 6 ): s = 'Friday' elif ( w == 7 ): s = 'Saturday' else: print ( '' ) print ( 'weekday_to_name_common(): Fatal error!' ) print ( ' Index W must be between 1 and 7.' ) raise Exception ( 'weekday_to_name_common(): Fatal error!' ) return s def weekday_to_name_common_test ( ): #*****************************************************************************80 # ## weekday_to_name_common_test() tests weekday_to_name_common(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 July 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'weekday_to_name_common_test():' ) print ( ' weekday_to_name_common() is given a weekday index between 1 and 7' ) print ( ' and returns the corresponding name of the weekday.' ) print ( '' ) print ( ' Index Name' ) print ( '' ) for w in range ( 1, 8 ): s = weekday_to_name_common ( w ) print ( ' %5d %s' % ( w, s ) ) return def weekday_to_name_common2 ( w ): #*****************************************************************************80 # ## weekday_to_name_common2() returns the name of a Common weekday. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 22 December 2017 # # Author: # # John Burkardt # # Input: # # integer W, the weekday index. # # Output: # # string S, the weekday name. # if ( w == 1 ): s = 'Su' elif ( w == 2 ): s = 'M ' elif ( w == 3 ): s = 'Tu' elif ( w == 4 ): s = 'W ' elif ( w == 5 ): s = 'Th' elif ( w == 6 ): s = 'F ' elif ( w == 7 ): s = 'Sa' else: print ( '' ) print ( 'weekday_to_name_common2(): Fatal error!' ) print ( ' Index W must be between 1 and 7.' ) raise Exception ( 'weekday_to_name_common2(): Fatal error!' ) return s def weekday_to_name_common2_test ( ): #*****************************************************************************80 # ## weekday_to_name_common2_test() tests weekday_to_name_common2(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 22 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'weekday_to_name_common2_test():' ) print ( ' weekday_to_name_common2() is given a weekday index between 1 and 7' ) print ( ' and returns the corresponding name of the weekday.' ) print ( '' ) print ( ' Index Name' ) print ( '' ) for w in range ( 1, 8 ): s = weekday_to_name_common2 ( w ) print ( ' %5d %s' % ( w, s ) ) return def weekday_to_name_common3 ( w ): #*****************************************************************************80 # ## weekday_to_name_common3() returns the name of a Common weekday. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 22 September 2017 # # Author: # # John Burkardt # # Input: # # integer W, the weekday index. # # Output: # # string S, the weekday name. # if ( w == 1 ): s = 'Sun' elif ( w == 2 ): s = 'Mon' elif ( w == 3 ): s = 'Tue' elif ( w == 4 ): s = 'Wed' elif ( w == 5 ): s = 'Thu' elif ( w == 6 ): s = 'Fri' elif ( w == 7 ): s = 'Sat' else: print ( '' ) print ( 'weekday_to_name_common3(): Fatal error!' ) print ( ' Index W must be between 1 and 7.' ) raise Exception ( 'weekday_to_name_common3(): Fatal error!' ) return s def weekday_to_name_common3_test ( ): #*****************************************************************************80 # ## weekday_to_name_common3_test() tests weekday_to_name_common3(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 22 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'weekday_to_name_common3_test():' ) print ( ' weekday_to_name_common3() is given a weekday index between 1 and 7' ) print ( ' and returns the corresponding name of the weekday.' ) print ( '' ) print ( ' Index Name' ) print ( '' ) for w in range ( 1, 8 ): s = weekday_to_name_common3 ( w ) print ( ' %5d %s' % ( w, s ) ) return def weekday_to_name_french ( w ): #*****************************************************************************80 # ## weekday_to_name_french() returns the name of a French weekday. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer W, the weekday index. # # Output: # # string S, the weekday name. # weekday_name = [ \ 'Dimanche', \ 'Lundi', \ 'Mardi', \ 'Mercredi', \ 'Jeudi', \ 'Vendredi', \ 'Samedi' ] # # Make a local copy of the weekday number. # w2 = w # # Check the weekday number. # weekday_check_common ( w2 ) # # Return the weekday name. # s = weekday_name[w2-1] return s def weekday_to_name_german ( w ): #*****************************************************************************80 # ## weekday_to_name_german() returns the name of a German weekday. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer W, the weekday index. # # Output: # # string S, the weekday name. # weekday_name = [ \ 'Sonntag', \ 'Montag', \ 'Dienstag', \ 'Mittwoch', \ 'Donnerstag', \ 'Freitag', \ 'Samstag' ] # # Make a local copy of the weekday number. # w2 = w # # Check the weekday number. # weekday_check_common ( w2 ) # # Return the weekday name. # s = weekday_name[w2-1] return s def weekday_to_name_hebrew ( w ): #*****************************************************************************80 # ## weekday_to_name_hebrew() returns the name of a Hebrew weekday. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer W, the weekday index. # # Output: # # string S, the weekday name. # weekday_name = [ \ 'Yom rishon,' \ 'Yom sheni,' \ 'Yom shelishi,' \ 'Yom revii,' \ 'Yom hamishi,' \ 'Yom shishi,' \ 'Sabbath' ] # # Make a local copy of the weekday number. # w2 = w # # Check the weekday number. # weekday_check_common ( w2 ) # # Return the weekday name. # s = weekday_name[w2-1] return s def weekday_to_name_islamic ( w ): #*****************************************************************************80 # ## weekday_to_name_islamic() returns the name of an Islamic weekday. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer W, the weekday index. # # Output: # # string S, the weekday name. # weekday_name = [ \ 'Yom ilHadd', \ 'Yom litneen', \ 'Yom ittalat', \ 'Yom larba', \ 'Yom ilkhamiis', \ 'Yom ilguma', \ 'Yom issabt '] # # Make a local copy of the weekday number. # w2 = w # # Check the weekday number. # weekday_check_common ( w2 ) # # Return the weekday name. # s = weekday_name[w2-1] return s def weekday_to_name_republican ( w ): #*****************************************************************************80 # ## weekday_to_name_republican() returns the name of a Republican weekday. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer W, the weekday index. # # Output: # # string S, the weekday name. # weekday_name = [ \ 'Primedi', \ 'Duodi', \ 'Tridi', \ 'Quartidi', \ 'Quintidi', \ 'Sextidi', \ 'Septidi', \ 'Octidi', \ 'Nonidi', \ 'Decadi' ] if ( w < 1 or 10 < w ): s = '?????' else: s = weekday_name[w-1] return s def weekday_to_name_roman ( w ): #*****************************************************************************80 # ## weekday_to_name_roman() returns the name of a Roman weekday. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer W, the weekday index. # # Output: # # string S, the weekday name. # weekday_name = [ \ 'Dies Solis', \ 'Dies Lunae', \ 'Dies Martis', \ 'Dies Mercurii', \ 'Dies Iovis', \ 'Dies Veneris', \ 'Dies Saturni' ] # # Make a local copy of the weekday number. # w2 = w # # Check the weekday number. # weekday_check_common ( w2 ) # # Return the weekday name. # s = weekday_name[w2-1] return s def weekday_values ( n_data ): #*****************************************************************************80 # ## weekday_values() returns the day of the week for various dates. # # Discussion: # # The CE or Common Era calendar is used, under the # hybrid Julian/Gregorian Calendar, with a transition from Julian # to Gregorian. The day after 04 October 1582 was 15 October 1582. # # The year before 1 AD or CE is 1 BC or BCE. In this data set, # years BC/BCE are indicated by a negative year value. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 22 February 2015 # # Author: # # John Burkardt # # Reference: # # Edward Reingold, Nachum Dershowitz, # Calendrical Calculations: The Millennium Edition, # Cambridge University Press, 2001, # ISBN: 0 521 77752 6 # LC: CE12.R45. # # Input: # # integer N_DATA. The user sets N_DATA to 0 before the first call. # # Output: # # integer N_DATA. On each call, the routine increments N_DATA by 1, # and returns the corresponding data; when there is no more data, the # output value of N_DATA will be 0 again. # integer Y, M, D, the Common Era date. # # integer W, the day of the week. Sunday = 1. # import numpy as np n_max = 34 d_vec = np.array ( ( \ 30, \ 8, \ 26, \ 3, \ 7, \ 18, \ 7, \ 19, \ 14, \ 18, \ 16, \ 3, \ 26, \ 20, \ 4, \ 25, \ 31, \ 9, \ 24, \ 10, \ 30, \ 24, \ 19, \ 2, \ 27, \ 19, \ 25, \ 29, \ 19, \ 7, \ 17, \ 25, \ 10, \ 18 )) m_vec = np.array ( ( \ 7, \ 12, \ 9, \ 10, \ 1, \ 5, \ 11, \ 4, \ 10, \ 5, \ 3, \ 3, \ 3, \ 4, \ 6, \ 1, \ 3, \ 9, \ 2, \ 6, \ 6, \ 7, \ 6, \ 8, \ 3, \ 4, \ 8, \ 9, \ 4, \ 10, \ 3, \ 2, \ 11, \ 7 )) w_vec = np.array ( ( \ 1, \ 4, \ 4, \ 1, \ 4, \ 2, \ 7, \ 1, \ 7, \ 1, \ 6, \ 7, \ 6, \ 1, \ 1, \ 4, \ 7, \ 7, \ 7, \ 4, \ 1, \ 6, \ 1, \ 2, \ 4, \ 1, \ 1, \ 2, \ 2, \ 5, \ 3, \ 1, \ 4, \ 1 )) y_vec = np.array ( ( \ - 587, \ - 169, \ 70, \ 135, \ 470, \ 576, \ 694, \ 1013, \ 1066, \ 1096, \ 1190, \ 1240, \ 1288, \ 1298, \ 1391, \ 1436, \ 1492, \ 1553, \ 1560, \ 1648, \ 1680, \ 1716, \ 1768, \ 1819, \ 1839, \ 1903, \ 1929, \ 1941, \ 1943, \ 1943, \ 1992, \ 1996, \ 2038, \ 2094 )) if ( n_data < 0 ): n_data = 0 if ( n_max <= n_data ): n_data = 0 y = 0 m = 0 d = 0 w = 0 else: y = y_vec[n_data] m = m_vec[n_data] d = d_vec[n_data] w = w_vec[n_data] n_data = n_data + 1 return n_data, y, m, d, w def weekday_values_test ( ): #*****************************************************************************80 # ## weekday_values_test() tests weekday_values(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 22 February 2015 # # Author: # # John Burkardt # print ( '' ) print ( 'weekday_values_test():' ) print ( ' weekday_values() stores values of' ) print ( ' the weekday for a given Y/M/D date' ) print ( '' ) print ( ' Y M D W' ) print ( '' ) n_data = 0 while ( True ): n_data, y, m, d, w = weekday_values ( n_data ) if ( n_data == 0 ): break print ( ' %6d %6d %6d %6d' % ( y, m, d, w ) ) return def y_astronomical_to_common ( y ): #*****************************************************************************80 # ## y_astronomical_to_common() converts an Astronomical year to a Common year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 25 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, the astronomical year. # # Output: # # integer Y2, the Common year. # if ( y <= 0 ): y2 = y - 1 else: y2 = y return y2 def y_check_alexandrian ( y ): #*****************************************************************************80 # ## y_check_alexandrian() checks an Alexandrian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 November 2019 # # Author: # # John Burkardt # # Input: # # integer Y, the year, which must not be 0. # # Output: # # logical ierror: True if an error was found. # if ( y != 0 ): ierror = False else: ierror = True return ierror def y_check_bahai ( y ): #*****************************************************************************80 # ## y_check_bahai() checks a Bahai year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 November 2019 # # Author: # # John Burkardt # # Input: # # integer Y, the year, which must not be 0. # # Output: # # logical ierror: True if an error was found. # if ( y != 0 ): ierror = False else: ierror = True return ierror def y_check_common ( y ): #*****************************************************************************80 # ## y_check_common() checks a Common year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, the year, which must not be 0. # # Output: # # logical ierror: True if an error was found. # if ( y != 0 ): ierror = False else: ierror = True return ierror def y_check_eg_civil ( y ): #*****************************************************************************80 # ## y_check_eg_civil() checks an Egyptian Civil year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 November 2019 # # Author: # # John Burkardt # # Input: # # integer Y, the year, which must not be 0. # # Output: # # logical ierror: True if an error was found. # if ( y != 0 ): ierror = False else: ierror = True return ierror def y_check_english ( y ): #*****************************************************************************80 # ## y_check_english() checks an English year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 November 2019 # # Author: # # John Burkardt # # Input: # # integer Y, the year, which must not be 0. # # Output: # # logical ierror: True if an error was found. # if ( y != 0 ): ierror = False else: ierror = True return ierror def y_check_greek ( y ): #*****************************************************************************80 # ## y_check_greek() checks a Greek year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 November 2019 # # Author: # # John Burkardt # # Input: # # integer Y, the year, which must not be 0. # # Output: # # logical ierror: True if an error was found. # if ( y != 0 ): ierror = False else: ierror = True return ierror def y_check_gregorian ( y ): #*****************************************************************************80 # ## y_check_gregorian() checks a Gregorian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 November 2019 # # Author: # # John Burkardt # # Input: # # integer Y, the year, which must not be 0. # # Output: # # logical ierror: True if an error was found. # if ( y != 0 ): ierror = False else: ierror = True return ierror def y_check_hebrew ( y ): #*****************************************************************************80 # ## y_check_hebrew() checks a Hebrew year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 November 2019 # # Author: # # John Burkardt # # Input: # # integer Y, the year, which must not be 0. # # Output: # # logical ierror: True if an error was found. # if ( y != 0 ): ierror = False else: ierror = True return ierror def y_check_islamic ( y ): #*****************************************************************************80 # ## y_check_islamic() checks an Islamic year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 November 2019 # # Author: # # John Burkardt # # Input: # # integer Y, the year, which must not be 0. # # Output: # # logical ierror: True if an error was found. # if ( y != 0 ): ierror = False else: ierror = True return ierror def y_check_julian ( y ): #*****************************************************************************80 # ## y_check_julian() checks a Julian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 November 2019 # # Author: # # John Burkardt # # Input: # # integer Y, the year, which must not be 0. # # Output: # # logical ierror: True if an error was found. # if ( y != 0 ): ierror = False else: ierror = True return ierror def y_check_republican ( y ): #*****************************************************************************80 # ## y_check_republican() checks a Republican year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 November 2019 # # Author: # # John Burkardt # # Input: # # integer Y, the year, which must not be 0. # # Output: # # logical ierror: True if an error was found. # if ( y != 0 ): ierror = False else: ierror = True return ierror def y_check_roman ( y ): #*****************************************************************************80 # ## y_check_roman() checks a Roman year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 November 2019 # # Author: # # John Burkardt # # Input: # # integer Y, the year, which must not be 0. # # Output: # # logical ierror: True if an error was found. # if ( y != 0 ): ierror = False else: ierror = True return ierror def y_common_to_astronomical ( y ): #*****************************************************************************80 # ## y_common_to_astronomical() converts a Common year to an Astronomical year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 July 2017 # # Author: # # John Burkardt # # Input: # # integer Y, the Common year. # # Output: # # integer Y2, the Astronomical year. # if ( y < 0 ): y2 = y + 1 elif ( y == 0 ): print ( '' ) print ( 'y_common_to_astronomical(): Fatal error!' ) print ( ' COMMON calendar does not have a year 0.' ) raise Exception ( 'y_common_to_astronomical(): Fatal error!' ) else: y2 = y return y2 def y_common_to_astronomical_test ( ): #*****************************************************************************80 # ## y_common_to_astronomical_test() tests y_common_to_astronomical(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 July 2017 # # Author: # # John Burkardt # # Input: # # integer Y, the Common year. # # Output: # # integer Y2, the Astronomical year. # print ( '' ) print ( 'y_common_to_astronomical_test():' ) print ( ' y_common_to_astronomical() converts a common year to an' ) print ( ' "astronomical" year.' ) print ( '' ) print ( ' y_common y_astronomical' ) print ( '' ) for y in range ( -10, 11 ): if ( y != 0 ): y2 = y_common_to_astronomical ( y ) print ( ' %8d %14d' % ( y, y2 ) ) return def y_julian_to_roman ( y ): #*****************************************************************************80 # ## y_julian_to_roman() converts a Julian year to a Roman year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the Julian year. # # Output: # # integer Y2, the corresponding Roman year. # ierror = y_check_julian ( y ) if ( ierror ): y2 = -1 return y2 if ( y < 0 ): y = y + 1 y2 = y + 753 return y2 def y_roman_to_julian ( y ): #*****************************************************************************80 # ## y_roman_to_julian() converts a Roman year to a Julian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the Roman year. # # Output: # # integer Y2, the corresponding Julian year. # y2 = y - 753 if ( y2 <= 0 ): y2 = y2 - 1 return y2 def y_to_s_alexandrian ( y ): #*****************************************************************************80 # ## y_to_s_alexandrian() writes an Alexandrian year into a string. # # Format: # # AX YearNumber # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # s = ( 'AX %d' % ( y ) ) return s def y_to_s_bahai ( y ): #*****************************************************************************80 # ## y_to_s_bahai() writes a Bahai year into a string. # # Format: # # Bahai YearNumber # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # s = ( 'Bahai %d' % ( y ) ) return s def y_to_s_common ( y ): #*****************************************************************************80 # ## y_to_s_common() writes a Common Y date into a string. # # Format: # # CE YYYY # BCE YYYY # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 23 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, the Y date. # # Output: # # string S, a representation of the date. # if ( 0 <= y ): s1 = 'CE' else: s1 = 'BCE' if ( 0 <= y ): s2 = str ( y ) else: s2 = str ( -y ) s = s1 + ' ' + s2 return s def y_to_s_common_test ( ): #*****************************************************************************80 # ## y_to_s_common_test() tests y_to_s_common(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 23 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'y_to_s_common_test():' ) print ( ' y_to_s_common() converts a year Y to a string S.' ) print ( '' ) print ( ' Y "S"' ) print ( '' ) mu = 0.0 sigma = 1000.0 for i in range ( 0, 10 ): y = i4_normal_ab ( mu, sigma ) s = y_to_s_common ( y ) print ( ' %6d "%s"' % ( y, s ) ) return def y_to_s_coptic ( y ): #*****************************************************************************80 # ## y_to_s_coptic() writes a Coptic year into a string. # # Format: # # Coptic YearNumber # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # s = ( 'Coptic %d' % ( y ) ) return s def y_to_s_eg_civil ( y ): #*****************************************************************************80 # ## y_to_s_eg_civil() writes an Egyptian Civil year into a string. # # Format: # # EN YearNumber # # Licensing: # # This code is distributed under the MIT license. # # Discussion: # # "EN" stands for the Era of Nabonassar, a Babylonian king who # acceded in 747 BC, used by the astronomer Ptolemy to assign # an artificial starting year for the Egyptian calendar. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # s = ( 'EN %d' % ( y ) ) return s def y_to_s_eg_lunar ( y ): #*****************************************************************************80 # ## y_to_s_eg_lunar() writes an Egyptian Lunar year into a string. # # Format: # # EL YearNumber # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # s = ( 'EL %d' % ( y ) ) return s def y_to_s_english ( y ): #*****************************************************************************80 # ## y_to_s_english() writes an English year into a string. # # Format: # # YearNumber BC OS # YearNumber AD OS # YearNumber AD NS # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # ierror = y_check_english ( y ) if ( ierror ): print ( '' ) print ( 'y_to_s_english(): Fatal error!' ) print ( ' Illegal year.' ) raise Exception ( 'y_to_s_english(): Fatal error!' ) if ( y < 0 ): s = ( 'BC OS %d' % ( - y ) ) elif ( y <= 1752 ): s = ( 'AD OS %d' % ( y ) ) elif ( 1752 < y ): s = ( 'AD NS %d' % ( y ) ) return s def y_to_s_ethiopian ( y ): #*****************************************************************************80 # ## y_to_s_ethiopian() writes an Ethiopian year into a string. # # Format: # # Ethiopian YearNumber # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # s = ( 'Ethiopian %d' % ( y ) ) return s def y_to_s_greek ( y ): #*****************************************************************************80 # ## y_to_s_greek() writes a Greek year into a string. # # Format: # # OL 87.1 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # from math import floor o = 1 + floor ( ( y - 1 ) / 4 ) yy = i4_wrap ( y, 1, 4 ) s = ( 'OL %d.%d' % ( o, yy ) ) return s def y_to_s_gregorian ( y ): #*****************************************************************************80 # ## y_to_s_gregorian() writes a Gregorian year into a string. # # Format: # # YearNumber BC # YearNumber AD # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # if ( y < 0 ): s = ( 'BC %d' % ( -y ) ) elif ( 0 < y ): s = ( 'AD %d' % ( y ) ) return s def y_to_s_hebrew ( y ): #*****************************************************************************80 # ## y_to_s_hebrew() writes a Hebrew year into a string. # # Format: # # YearNumber AM # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # ierror = y_check_hebrew ( y ) if ( ierror ): printf ( '' ) printf ( 'y_to_s_hebrew(): Fatal error!' ) printf ( ' Illegal year Y = ', y ) raise Exception ( 'y_to_s_hebrew(): Fatal error!' ) s = ( '%d AM' % ( y ) ) return s def y_to_s_islamic ( y ): #*****************************************************************************80 # ## y_to_s_islamic() writes an Islamic year into a string. # # Format: # # YearNumber AH # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # s = ( 'AH %d' % ( y ) ) return s def y_to_s_julian ( y ): #*****************************************************************************80 # ## y_to_s_julian() writes a Julian year into a string. # # Format: # # YearNumber BC # YearNumber AD # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # if ( y < 0 ): s = ( 'BC %d' % ( -y ) ) elif ( 0 < y ): s = ( 'AD %d' % ( y ) ) return s def y_to_s ( y ): #*****************************************************************************80 # ## y_to_s() writes a year into a string. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # s = ( '%d' % ( y ) ) return s def y_to_s_persian ( y ): #*****************************************************************************80 # ## y_to_s_persian() writes a Persian year into a string. # # Format: # # AP YearNumber # # Discussion: # # "AP" stands for "anno Persico". # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # s = ( 'AP %d' % ( y ) ) return s def y_to_s_republican ( y, s ): #*****************************************************************************80 # ## y_to_s_republican() writes a Republican year into a string. # # Format: # # YearNumber ER # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # s = ( '%d ER' % ( y ) ) return s def y_to_s_roman ( y ): #*****************************************************************************80 # ## y_to_s_roman() writes a Roman year into a string. # # Format: # # YearNumber AUC # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # string S, a representation of the year. # s = ( '%d AUC' % ( y ) ) return def year_is_embolismic_eg_lunar ( y ): #*****************************************************************************80 # ## year_is_embolismic_eg_lunar(): TRUE if the Egyptian Lunar year was embolismic. # # Discussion: # # This is just a "fake" function, which does repeat every 25 years, # and has 9 embolismic and 16 common years in that cycle, but with # a pattern I just made up for now. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # logical VALUE, TRUE if the year was embolismic. # y2 = ( y - 1 ) % 25 if ( ( y2 % 3 ) == 0 ): value = True else: value = False return value def year_is_embolismic_greek ( y ): #*****************************************************************************80 # ## year_is_embolismic_greek() returns TRUE if the Greek year was embolismic. # # Discussion: # # Apparently, the Greek calendar was emended haphazardly. This # routine does not attempt to follow that historical pattern, and # just uses the Hebrew calendar pattern for now. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # logical VALUE, TRUE if the year was embolismic. # if ( 12 <= i4_modp ( 7 * y + 13, 19 ) ): value = True else: value = False return value def year_is_embolismic_hebrew ( y ): #*****************************************************************************80 # ## year_is_embolismic_hebrew() returns TRUE if the Hebrew year was embolismic. # # Discussion: # # In a 19 year cycle, there are 7 embolismic years. During these years, # an extra month, "Adar II", (sometimes called "Veadar") is inserted after # the month of Adar. Nonembolismic years are called "common" years. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # logical VALUE, TRUE if the year was embolismic. # if ( 12 <= i4_modp ( 7 * y + 13, 19 ) ): value = True else: value = False return value def year_is_leap_alexandrian ( y ): #*****************************************************************************80 # ## year_is_leap_alexandrian(): TRUE if the Alexandrian year was a leap year. # # Discussion: # # The Alexandrian year, which started on the 29th of August of the Julian # year, was a leap year if it included the bissextile day of the Julian # calendar. In other words, if the Alexandrian year BEGAN in a Julian year # that preceded a Julian leap year, then the Alexandrian year was a leap # year. # # We deem year AX 1 to have begun in Julian 23 BC. Julian 21 BC was # theoretically a leap year, so AX 2 was a leap year, as was AX 6, AX 10, # and so on. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # Output, logical VALUE, TRUE if the year was a leap year. # if ( ( y % 4 ) == 2 ): value = True else: value = False return value def year_is_leap_bahai ( y ): #*****************************************************************************80 # ## year_is_leap_bahai() returns TRUE if the Bahai year was a leap year. # # Discussion: # # The leap year rules are the same as those used in the Gregorian # calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # Output, logical VALUE, TRUE if the year was a leap year. # if ( y <= 0 ): value = False return value if ( ( y % 400 ) == 0 ): value = True elif ( ( y % 100 ) == 0 ): value = False elif ( ( y % 4 ) == 0 ): value = True else: value = False return value def year_is_leap_common ( y ): #*****************************************************************************80 # ## year_is_leap_common() returns TRUE if the Common year was a leap year. # # Discussion: # # The "common" calendar is meant to be the calendar which is Julian up to # day JED = 2299160, and Gregorian from day JED = 2299161 and after. # # Algorithm: # # If ( the year is less than 0 ) then # # if the year+1 is divisible by 4 then # the year is a leap year. # # else if ( the year is 0 ) then # # the year is not a leap year ( in fact, it's illegal ) # # else if ( the year is no greater than 1582 ) then # # if the year is divisible by 4 then # the year is a leap year. # # else if ( # the year is divisible by 4 and # ( the year is not divisible by 100 # or # the year is divisible by 400 ) # ) then # the year is a leap year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 15 June 2012 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # logical VALUE, TRUE if the year was a leap year, # FALSE otherwise. # if ( y == 0 ): print ( '' ) print ( 'year_is_leap_common(): Fatal error!' ) print ( ' Year 0 is illegal.' ) raise Exception ( 'year_is_leap_common(): Fatal error!' ) # # BC years have to have 1 added to them to make a proper leap year evaluation. # y2 = y_common_to_astronomical ( y ) if ( y2 <= 1582 ): if ( i4_modp ( y2, 4 ) == 0 ): value = True else: value = False else: if ( i4_modp ( y2, 400 ) == 0 ): value = True elif ( i4_modp ( y2, 100 ) == 0 ): value = False elif ( i4_modp ( y2, 4 ) == 0 ): value = True else: value = False return value def year_is_leap_coptic ( y ): #*****************************************************************************80 # ## year_is_leap_coptic() returns TRUE if the Coptic year was a leap year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Reference: # # Nachum Dershowitz, Edward Reingold, # Calendrical Calculations, # Cambridge, 1997, page 58. # # Input: # # integer Y, the year. # # Output: # # Output, logical VALUE, TRUE if the year was a leap year. # if ( y <= 0 ): value = 0 return value if ( ( y % 4 ) == 3 ): value = True else: value = False return value def year_is_leap_eg_lunar ( y ): #*****************************************************************************80 # ## year_is_leap_eg_lunar(): TRUE if the Egyptian Lunar year was a leap year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # Output, logical VALUE, TRUE if the year was a leap year. # if ( y <= 0 ): value = False return value if ( ( y % 5 ) == 0 ): value = True else: value = False return value def year_is_leap_english ( y ): #*****************************************************************************80 # ## year_is_leap_english() returns TRUE if the English year was a leap year. # # Algorithm: # # If ( the year is less than 0 ) then # # if the year+1 is divisible by 4 then # the year is a leap year. # # else if ( the year is 0 ) then # # the year is not a leap year ( in fact, it's illegal ) # # else if ( the year is no greater than 1752 ) then # # if the year is divisible by 4 then # the year is a leap year. # # else if ( # the year is divisible by 4 and # ( the year is not divisible by 100 # or # the year is divisible by 400 ) # ) then # the year is a leap year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # Output, logical VALUE, TRUE if the year was a leap year. # if ( y == 0 ): value = False return value # # BC years have to have 1 added to them to make a proper leap year evaluation. # y2 = y_common_to_astronomical ( y ) if ( y2 <= 1752 ): if ( i4_modp ( y2, 4 ) == 0 ): value = True else: value = False else: if ( i4_modp ( y2, 400 ) == 0 ): value = True elif ( i4_modp ( y2, 100 ) == 0 ): value = False elif ( i4_modp ( y2, 4 ) == 0 ): value = True else: value = False return value def year_is_leap_ethiopian ( y ): #*****************************************************************************80 # ## year_is_leap_ethiopian() returns TRUE if the Ethiopian year was a leap year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Reference: # # Nachum Dershowitz, Edward Reingold, # Calendrical Calculations, # Cambridge, 1997, page 58. # # Input: # # integer Y, the year. # # Output: # # Output, logical VALUE, TRUE if the year was a leap year. # if ( y <= 0 ): value = False return value if ( ( y % 4 ) == 3 ): value = True else: value = False return value def year_is_leap_greek ( y ): #*****************************************************************************80 # ## year_is_leap_greek() returns TRUE if the Greek year was a leap year. # # Discussion: # # The actual practice of adding the extra day to the Greek calendar # seems to have been unmethodical. Here, we simply make up a rule # as a placeholder for now. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # Output, logical VALUE, TRUE if the year was a leap year. # if ( year_is_embolismic_greek ( y ) and ( ( y % 3 ) == 0 ) ): value = True else: value = False return value def year_is_leap_gregorian ( y ): #*****************************************************************************80 # ## year_is_leap_gregorian() returns TRUE if the Gregorian year was a leap year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 19 August 2015 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # bool year_is_leap_gregorian, TRUE if the year was a leap year, # FALSE otherwise. # if ( y <= 0 ): print ( '' ) print ( 'year_is_leap_gregorian(): Fatal error!' ) print ( ' This function will not accept nonpositive years.' ) raise Exception ( 'year_is_leap_gregorian(): Fatal error!' ) if ( ( y % 400 ) == 0 ): value = True elif ( ( y % 100 ) == 0 ): value = False elif ( ( y % 4 ) == 0 ): value = True else: value = False return value def year_is_leap_gregorian_test ( ): #*****************************************************************************80 # ## year_is_leap_gregorian_test() tests year_is_leap_gregorian(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 19 August 2015 # # Author: # # John Burkardt # from numpy.random import default_rng import numpy as np rng = default_rng ( ) print ( '' ) print ( 'year_is_leap_gregorian_test():' ) print ( ' year_is_leap_gregorian() reports leap years in the Gregorian calendar.' ) print ( '' ) print ( ' Year Leap?' ) print ( '' ) for i in range ( 0, 20 ): y = rng.integers ( low = 1, high = 2100, endpoint = True ) is_leap = year_is_leap_gregorian ( y ) print ( ' %4d %s' % ( y, is_leap ) ) return def year_is_leap_iranian ( y ): #*****************************************************************************80 # ## year_is_leap_iranian() returns TRUE if the Iranian year was a leap year. # # Discussion: # # I don't know the rule for this, so I'm just setting it FALSE for now. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # Output, logical VALUE, TRUE if the year was a leap year. # value = False return value def year_is_leap_islamic ( y ): #*****************************************************************************80 # ## year_is_leap_islamic() returns TRUE if the Islamic year was a leap year. # # Discussion: # # In a 30 year cycle, there are 11 leap years, years 2, 5, 7, 10, 13, # 16, 18, 21, 24, 26 and 29. During these years, the 12th month has # 30 days instead of 29. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # Output, logical VALUE, TRUE if the year was a leap year. # if ( i4_modp ( 11 * y + 14, 30 ) < 11 ): value = True else: value = False return value def year_is_leap_julian ( y ): #*****************************************************************************80 # ## year_is_leap_julian() returns TRUE if the Julian year was a leap year. # # Algorithm: # # If ( Y < 0 and Y+1 is divisible by 4 ) then # the year is a leap year. # else if ( Y == 0 ) then # the year is illegal # else if ( 0 < Y and Y is divisible by 4 ) then # the year is a leap year. # else # the year is NOT a leap year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # Output, logical VALUE, TRUE if the year was a leap year. # if ( y == 0 ): value = False return value y2 = y_common_to_astronomical ( y ) if ( i4_modp ( y2, 4 ) == 0 ): value = True else: value = False return value def year_is_leap_persian ( y ): #*****************************************************************************80 # ## year_is_leap_persian() returns TRUE if the Persian year was a leap year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 30 March 2013 # # Author: # # John Burkardt # # Reference: # # Nachum Dershowitz, Edward Reingold, # Calendrical Calculations, # Cambridge, 1997, page 58. # # Input: # # integer Y, the year. # # Output: # # Output, logical VALUE, TRUE if the year was a leap year. # if ( y <= 0 ): y2 = y - 473 else: y2 = y - 474 y3 = 474 + ( y2 % 2820 ) if ( ( ( 682 * ( y3 + 38 ) ) % 2816 ) < 682 ): value = True else: value = False return value def year_is_leap_republican ( y ): #*****************************************************************************80 # ## year_is_leap_republican() returns TRUE if the Republican year was a leap year. # # Discussion: # # The French Republican calendar was in use for 14 years. # In that time, years 3, 7 and 11 were designated as leap years. # The easiest way to harmonize the rules and history is to apply # the leap year rules to Y+1. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # logical VALUE, TRUE if the year was a leap year. # ierror = y_check_republican ( y ) if ( ierror ): value = False return value value = False if ( ( y + 1 ) % 4 == 0 ): value = True if ( ( y + 1 ) % 100 == 0 ): value = False if ( ( y + 1 ) % 400 == 0 ): value = True if ( ( y + 1 ) % 4000 == 0 ): value = False return value def year_is_leap_roman ( y ): #*****************************************************************************80 # ## year_is_leap_roman() returns TRUE if the Roman year was a leap year. # # Discussion: # # For our unrealistic and idealized Roman calendar, we are going to # take a year to have been a leap year if the corresponding year in # the idealized Julian calendar was a leap year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 23 September 2012 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # logical VALUE, TRUE if the year was a leap year. # ierror = y_check_roman ( y ) if ( ierror ): value = False return value y2 = y_roman_to_julian ( y ) value = year_is_leap_julian ( y2 ) return value def year_length_days_alexandrian ( y ): #*****************************************************************************80 # ## year_length_days_alexandrian() returns the number of days in an Alexandrian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( year_is_leap_alexandrian ( y ) ): value = 366 else: value = 365 return value def year_length_days_bahai ( y ): #*****************************************************************************80 # ## year_length_days_bahai() returns the number of days in a Bahai year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( year_is_leap_bahai ( y ) ): value = 366 else: value = 365 return value def year_length_days_common ( y ): #*****************************************************************************80 # ## year_length_days_common() returns the number of days in a Common year. # # Discussion: # # The "common" calendar is meant to be the calendar which is Julian up to # day JED = 2299160, and Gregorian from day JED = 2299161 and after. # # If Y is 0, then the routine returns 0, reflecting the fact that # there was officially no year 0. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 23 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of # days in the year. # if ( y == 0 ): value = 0 elif ( y == 1582 ): value = 355 elif ( year_is_leap_common ( y ) ): value = 366 else: value = 365 return value def year_length_days_common_test ( ): #*****************************************************************************80 # ## year_length_days_common_test() tests year_length_days_common(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 23 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'year_length_days_common_test():' ) print ( ' year_length_days_common() determines the length of a year.' ) print ( '' ) print ( ' Year Length' ) print ( '' ) for y in range ( 1580, 1586 ): sy = y_to_s_common ( y ) print ( ' %10s %d' % ( sy, year_length_days_common ( y ) ) ) for y in range ( 1750, 1755 ): sy = y_to_s_common ( y ) print ( ' %10s %d' % ( sy, year_length_days_common ( y ) ) ) for y in range ( 1000, 2100, 100 ): sy = y_to_s_common ( y ) print ( ' %10s %d' % ( sy, year_length_days_common ( y ) ) ) return def year_length_days_coptic ( y ): #*****************************************************************************80 # ## year_length_days_coptic() returns the number of days in a Coptic year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( year_is_leap_coptic ( y ) ): value = 366 else: value = 365 return value def year_length_days_eg_civil ( y ): #*****************************************************************************80 # ## year_length_days_eg_civil() returns the number of days in an Egyptian Civil year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # value = 365 return value def year_length_days_eg_lunar ( y ): #*****************************************************************************80 # ## year_length_days_eg_lunar() returns the number of days in an Egyptian Lunar year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( not year_is_embolismic_eg_lunar ( y ) ): value = 354 else: value = 384 if ( year_is_leap_eg_lunar ( y ) ): value = value + 1 return value def year_length_days_english ( y ): #*****************************************************************************80 # ## year_length_days_english() returns the number of days in an English year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( y == 0 ): print ( '' ) print ( 'year_length_days_english(): Fatal error!' ) print ( ' Illegal Y = 0.' ) raise Exception ( 'year_length_days_english(): Fatal error!' ) if ( y == 1752 ): value = 355 elif ( year_is_leap_english ( y ) ): value = 366 else: value = 365 return value def year_length_days_ethiopian ( y ): #*****************************************************************************80 # ## year_length_days_ethiopian() returns the number of days in an Ethiopian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( year_is_leap_ethiopian ( y ) ): value = 366 else: value = 365 return value def year_length_days_greek ( y ): #*****************************************************************************80 # ## year_length_days_greek() returns the number of days in a Greek year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( year_is_embolismic_greek ( y ) ): value = 386 if ( year_is_leap_greek ( y ) ): value = value + 1 else: value = 357 return value def year_length_days_gregorian ( y ): #*****************************************************************************80 # ## year_length_days_gregorian() returns the number of days in a Gregorian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( y == 0 ): print ( '' ) print ( 'year_length_days_gregorian(): Fatal error!' ) print ( ' Illegal Y = 0.' ) raise Exception ( 'year_length_days_gregorian(): Fatal error!' ) if ( year_is_leap_gregorian ( y ) ): value = 366 else: value = 365 return value def year_length_days_hebrew ( y ): #*****************************************************************************80 # ## year_length_days_hebrew() returns the number of days in a Hebrew year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # jed = new_year_to_jed_hebrew ( y ) y2 = y + 1 jed2 = new_year_to_jed_hebrew ( y2 ) value = round ( jed2 - jed ) return value def year_length_days_hindu_solar ( y ): #*****************************************************************************80 # ## year_length_days_hindu_solar() returns the number of days in a Hindu solar year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # real VALUE, the number of days in the year. # value = 1577917828 / 4320000 return value def year_length_days_islamic ( y ): #*****************************************************************************80 # ## year_length_days_islamic() returns the number of days in an Islamic year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( year_is_leap_islamic ( y ) ): value = 355 else: value = 354 return value def year_length_days_julian ( y ): #*****************************************************************************80 # ## year_length_days_julian() returns the number of days in a Julian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( y == 0 ): value = 0 elif ( year_is_leap_julian ( y ) ): value = 366 else: value = 365 return value def year_length_days_lunar ( y ): #*****************************************************************************80 # ## year_length_days_lunar() returns the number of days in a "lunar year". # # Discussion: # # The "lunar year" is taken to be the length of 12 mean lunations. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # real VALUE, the number of days in the year. # value = 354.3671 return value def year_length_days_persian ( y ): #*****************************************************************************80 # ## year_length_days_persian() returns the number of days in a Persian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( year_is_leap_persian ( y ) ): value = 366 else: value = 365 return value def year_length_days_republican ( y ): #*****************************************************************************80 # ## year_length_days_republican() returns the number of days in a Republican year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( year_is_leap_republican ( y ) ): value = 366 else: value = 365 return value def year_length_days_roman ( y ): #*****************************************************************************80 # ## year_length_days_roman() returns the number of days in a Roman year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( year_is_leap_roman ( y ) ): value = 366 else: value = 365 return value def year_length_days_solar ( y ): #*****************************************************************************80 # ## year_length_days_solar() returns the number of days in a "solar" year. # # Discussion: # # The "solar" year is taken to be the mean tropical year. # The number of days in a mean tropical year has varied from # 365.2424992 in 4000 BC to 365.2421897 in 2000 AD. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of days in the year. # if ( y < 1 ): y2 = y + 1 else: y2 = y if ( y2 < - 4000 ): value = 365.2424992 elif ( y2 <= 2000 ): value = \ ( ( 2000 - y2 ) * 365.2424992 \ + ( 4000 + y2 ) * 365.2421897 ) \ / 6000.0 else: value = 365.2421897 return value def year_length_months_alexandrian ( y ): #*****************************************************************************80 # ## year_length_months_alexandrian() returns the number of months in an Alexandrian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of months in the year. # value = 13 return value def year_length_months_bahai ( y ): #*****************************************************************************80 # ## year_length_months_bahai() returns the number of months in a Bahai year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of months in the year. # value = 20; return value def year_length_months_common ( y ): #*****************************************************************************80 # ## year_length_months_common() returns the number of months in a Common year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 15 July 2012 # # Author: # # John Burkardt # # Input: # # integer Y, the year to be checked. # # Output: # # integer VALUE, the number of months in the year. # value = 12 return value def year_length_months_coptic ( y ): #*****************************************************************************80 # ## year_length_months_coptic() returns the number of months in a Coptic year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # value = 12 return value def year_length_months_eg_civil ( y ): #*****************************************************************************80 # ## year_length_months_eg_civil() returns the number of months in an Egyptian Civil year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # value = 13 return value def year_length_months_eg_lunar ( y ): #*****************************************************************************80 # ## year_length_months_eg_lunar() returns the number of months in an Egyptian Lunar year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # if ( year_is_embolismic_eg_lunar ( y ) ): value = 13 else: value = 12 return value def year_length_months_english ( y ): #*****************************************************************************80 # ## year_length_months_english() returns the number of months in an English year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 23 September 2012 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # value = 12 return value def year_length_months_ethiopian ( y ): #*****************************************************************************80 # ## year_length_months_ethiopian() returns the number of months in an Ethiopian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 23 September 2012 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # value = 13 return value def year_length_months_greek ( y ): #*****************************************************************************80 # ## year_length_months_greek() returns the number of months in a Greek year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 23 September 2012 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # if ( year_is_embolismic_greek ( y ) ): value = 13 else: value = 12 return value def year_length_months_gregorian ( y ): #*****************************************************************************80 # ## year_length_months_gregorian(): number of months in a Gregorian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 16 June 2012 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # value = 12 return value def year_length_months_hebrew ( y ): #*****************************************************************************80 # ## year_length_months_hebrew() returns the number of months in a Hebrew year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # if ( year_is_embolismic_hebrew ( y ) ): value = 13 else: value = 12 return value def year_length_months_hindu_lunar ( y ): #*****************************************************************************80 # ## year_length_months_hindu_lunar() returns the number of months in a Hindu Lunar year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # value = 12 return value def year_length_months_hindu_solar ( y ): #*****************************************************************************80 # ## year_length_months_hindu_solar() returns the number of months in a Hindu Solar year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # value = 12 return value def year_length_months_islamic ( y ): #*****************************************************************************80 # ## year_length_months_islamic() returns the number of months in an Islamic year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # value = 12 return value def year_length_months_julian ( y ): #*****************************************************************************80 # ## year_length_months_julian() returns the number of months in a Julian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # value = 12 return value def year_length_months_persian ( y ): #*****************************************************************************80 # ## year_length_months_persian() returns the number of months in a Persian year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # value = 12 return value def year_length_months_republican ( y ): #*****************************************************************************80 # ## year_length_months_republican() returns the number of months in a Republican year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # value = 13 return value def year_length_months_roman ( y ): #*****************************************************************************80 # ## year_length_months_roman() returns the number of months in a Roman year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer VALUE, the number of months in the year. # value = 12 return value def year_to_dominical_common ( y ): #*****************************************************************************80 # ## year_to_dominical_common(): dominical numbers, Common calendar. # # Discussion: # # The Julian calendar calculations are used through the year 1582, # and the Gregorian thereafter. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer N1, N2, the dominical numbers for the year. # If Y is a leap year, then N1 applies before March 1, and N2 after. # If Y is not a leap year, then N1 applies throughout the year, # and N2 is returned as N1. # if ( y <= 1582 ): n1, n2 = year_to_dominical_julian ( y ) else: n1, n2 = year_to_dominical_gregorian ( y ) return n1, n2 def year_to_dominical_gregorian ( y ): #*****************************************************************************80 # ## year_to_dominical_gregorian(): dominical numbers, Gregorian calendar. # # Discussion: # # The days of each year are numbered with "calendar letters", with # January 1 having letter 'A', January 7 having letter 'G', and # the cycle then repeating with January 8 having letter 'A'. # # This cycle is independent of the weekday cycle. If a year is # not a leap year, then all Sundays have the same calendar letter. # This is called the dominical letter of the year. If a year is # a leap year, then all Sundays before March 1 have one calendar # letter, and all Sundays after have another (namely, the calendar # letter one position earlier in the cycle). # # Using the correspondence A = 1, B = 2, ..., we may speak of # the dominical number of a year, or dominical numbers for a leap year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer N1, N2, the dominical numbers for the year. # If Y is a leap year, then N1 applies before March 1, and N2 after. # If Y is not a leap year, then N1 applies throughout the year, # and N2 is returned as N1. # if ( y == 0 ): print ( '' ) print ( 'year_to_dominical_gregorian(): Fatal error!' ) print ( ' Illegal input Y = 0.' ) raise Exception ( 'year_to_dominical_gregorian(): Fatal error!' ) y2 = y_common_to_astronomical ( y ) p1 = y2 + floor ( y2 / 4 ) - floor ( y2 / 100 ) + floor ( y2 / 400 ) - 1 n1 = 7 - i4_modp ( p1, 7 ) if ( year_is_leap_gregorian ( y2 ) ): n2 = n1 p1 = p1 - 1 n1 = 7 - i4_modp ( p1, 7 ) else: n2 = n1 return n1, n2 def year_to_dominical_julian ( y ): #*****************************************************************************80 # ## year_to_dominical_julian(): dominical numbers, Julian calendar. # # Discussion: # # The days of each year are numbered with "calendar letters", with # January 1 having letter 'A', January 7 having letter 'G', and # the cycle then repeating with January 8 having letter 'A'. # # This cycle is independent of the weekday cycle. If a year is # not a leap year, then all Sundays have the same calendar letter. # This is called the dominical letter of the year. If a year is # a leap year, then all Sundays before March 1 have one calendar # letter, and all Sundays after have another (namely, the calendar # letter one position earlier in the cycle). # # Using the correspondence A = 1, B = 2, ..., we may speak of # the dominical number of a year, or dominical numbers for a leap year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer N1, N2, the dominical numbers for the year. # If Y is a leap year, then N1 applies before March 1, and N2 after. # If Y is not a leap year, then N1 applies throughout the year, # and N2 is returned as N1. # from math import floor if ( y == 0 ): print ( '' ) print ( 'year_to_dominical_julian(): Fatal error!' ) print ( ' Illegal input Y = 0.' ) raise Exception ( 'year_to_dominical_julian(): Fatal error!' ) y2 = y_common_to_astronomical ( y ) p1 = y2 + floor ( y2 / 4 ) + 4 n1 = 7 - i4_modp ( p1, 7 ) if ( year_is_leap_julian ( y2 ) ): n2 = n1 p1 = p1 - 1 n1 = 7 - i4_modp ( p1, 7 ) else: n2 = n1 return n1, n2 def year_to_epact_gregorian ( y ): #*****************************************************************************80 # ## year_to_epact_gregorian() returns the epact of a Gregorian year. # # Discussion: # # The epact of a year is the age in days of the notional moon on # the first day of the year. If the year begins with a new moon, # the epact is zero. If the new moon occurred the day before, # the epact is 1. There is a unique epact for every golden number. # # The Gregorian epact calculation is an adjustment to the Julian # calculation that takes into account the shift of the calendar # to restore the vernal equinox to March 21, and the adjustment to # the average length of the year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Mapping Time, The Calendar and Its History, # Oxford, 1999. # # Input: # # integer Y, the year. # # Output: # # integer E, the epact, between 0 and 28. # from math import floor if ( y == 0 ): print ( '' ) print ( 'year_to_epact_gregorian(): Fatal error!' ) print ( ' Illegal input Y = 0.' ) raise Exception ( 'year_to_epact_gregorian(): Fatal error!' ) y2 = y_common_to_astronomical ( y ) g = year_to_golden_number ( y ) h = floor ( y2 / 100 ) q = h - floor ( h / 4 ) e = ( ( 57 + 11 * g - q + floor ( ( h - floor ( ( h - 17 ) / 25 ) ) / 3 ) ) % 30 ) e = floor ( e ) if ( e == 24 or ( e == 25 and 12 <= g ) ): e = e + 1 return e def year_to_epact_julian ( y ): #*****************************************************************************80 # ## year_to_epact_julian() returns the epact of a Julian year. # # Discussion: # # The epact of a year is the age in days of the notional moon on # the first day of the year. If the year begins with a new moon, # the epact is zero. If the new moon occurred the day before, # the epact is 1. There is a unique epact for every golden number. # # Bear in mind that the notional moon is not the one in the sky, # but a theoretical one that satisfactorily approximates the behavior # of the real one, but which is tame enough to be described by a formula. # # Example: # # Year Golden Number Epact # # 1 BC 1 8 # 1 AD 2 19 # 2 AD 3 0 # 3 AD 4 11 # 4 AD 5 22 # 5 AD 6 3 # 6 AD 7 14 # 7 AD 8 25 # 8 AD 9 6 # 9 AD 10 17 # 10 AD 11 28 # 11 AD 12 9 # 12 AD 13 20 # 13 AD 14 1 # 14 AD 15 12 # 15 AD 16 23 # 16 AD 17 4 # 17 AD 18 15 # 18 AD 19 26 # 19 AD 1 8 # 20 AD 2 19 # 1066 AD 3 0 # 1900 AD 1 8 # 1919 AD 1 8 # 1938 AD 1 8 # 1957 AD 1 8 # 1976 AD 1 8 # 1995 AD 1 8 # 2014 AD 1 8 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 January 2018 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Mapping Time, The Calendar and Its History, # Oxford, 1999. # # Input: # # integer Y, the year. The year 0 is illegal input. # # Output: # # integer E, the epact, between 0 and 28. # if ( y == 0 ): print ( '' ) print ( 'year_to_epact_julian(): Fatal error!' ) print ( ' Illegal input Y = 0.' ) raise Exception ( 'year_to_epact_julian(): Fatal error!' ) g = year_to_golden_number ( y ) e = i4_wrap ( 11 * g - 3, 0, 29 ) return e def year_to_golden_number ( y ): #*****************************************************************************80 # ## year_to_golden_number() returns the golden number of a Common year. # # Discussion: # # Nineteen solar years are very close to 235 lunations. Calendars # that try to keep track of both the sun and moon often make use of # this fact, ascribed to the Greek astronomer Meton. # # While trying to determine a formula for Easter, Dionysus Exiguus # symbolized the place of each year in its Metonic cycle by a # "golden number" between 1 and 19. The numbering began with the # year 1 BC, assigned the golden number of 1. The following year, # 1 AD, got the golden number of 2, and after that it gets easier. # # The same golden year calculation is done for years in the Julian # or Gregorian calendar. # # Example: # # Year Golden Number # # 1 BC 1 # 1 AD 2 # 2 AD 3 # 18 AD 19 # 19 AD 1 # 20 AD 2 # 1066 AD 3 # 1900 AD 1 # 1919 AD 1 # 1938 AD 1 # 1957 AD 1 # 1976 AD 1 # 1995 AD 1 # 2014 AD 1 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 24 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer G, the golden number, between 1 and 19. This # records the position of the year in the 19 year Metonic cycle. # if ( y == 0 ): print ( '' ) print ( 'year_to_golden_number(): Fatal error!' ) print ( ' Illegal input Y = 0.' ) raise Exception ( 'year_to_golden_number)(: Fatal error!' ) # # We assume that BC years come in as negative numbers, and that # the year before 1 AD is 1 BC. So add 1 to any negative value # so that the arithmetic works. # y2 = y_common_to_astronomical ( y ) g = i4_wrap ( y2 + 1, 1, 19 ) return g def year_to_golden_number_test ( ): #*****************************************************************************80 # ## year_to_golden_number_test() tests year_to_golden_number(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 25 December 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'year_to_golden_number_test():' ) print ( ' year_to_golden_number() determines the golden' ) print ( ' number of a year.' ) print ( '' ) print ( ' Year Golden Number' ) print ( '' ) for y in range ( -2, 21 ): if ( y != 0 ): s = y_to_s_common ( y ) g = year_to_golden_number ( y ) print ( ' %10s %d' % ( s, g ) ) return def year_to_indiction_common ( y ): #*****************************************************************************80 # ## year_to_indiction_common() returns the indiction number of a Common year. # # Discussion: # # The Roman empire had a taxation cycle that, at one time, comprised # 15 years. As is typical in calendrical matters, the actual length # of this cycle and the time that the cycle began varied from place # to place and time to time, and historians even disagree about the # indiction cycle given a specific place and time. Nonetheless, # it is customary to retrospectively impose a uniform and regular # indiction cycle on the ancient world. (The 15 year indiction cycle, # in fact, was factored into Scaliger's determination of an appropriate # starting point for the Julian Ephemeris Date.) # # Example: # # Year Indiction Number # # 3 BC 1 # 2 BC 2 # 1 BC 3 # 1 AD 4 # 10 AD 13 # 11 AD 14 # 12 AD 15 # 13 AD 1 # 14 AD 2 # 15 AD 3 # 26 AD 14 # 27 AD 15 # 28 AD 1 # 1900 AD 13 # 2000 AD 8 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer I, the indiction number, between 1 and 15. # if ( y == 0 ): print ( '' ) print ( 'year_to_indiction_common(): Fatal error!' ) print ( ' Illegal input Y = 0.' ) raise Exception ( 'year_to_indiction_common(): Fatal error!' ) # # We assume that BC years come in as negative numbers, and that # the year before 1 AD is 1 BC. So add 1 to any negative value # so that the arithmetic works. # y2 = y_common_to_astronomical ( y ) i = i4_wrap ( y2 + 3, 1, 15 ) return i def year_to_scaliger_common ( y ): #*****************************************************************************80 # ## year_to_scaliger_common() converts a Common year to its Scaliger indices. # # Discussion: # # The year 4713 BCE was chosen by Joseph Scaliger for the start of # his Julian Ephemeris Date system, because three cycles coincided # in that year, the 28 year Julian calendar cycle, the 19 year Metonic # cycle, and the 15 year Roman Indiction cycle. Thus, the year # 4713 BCE has Scaliger index (1,1,1). Each subsequent year has a distinct # set of Scaliger indices until 7980 years later, when the year # 3266 CE will again have the Scaliger index (1,1,1). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, the year. # # Output: # # integer C1, C2, C3, the number of completed # Julian, Metonic and Indiction cycles. # # integer R1, R2, R3, the Julian, Metonic and # Indiction cycle numbers that make up the Scaliger index. # from math import floor if ( y == 0 ): print ( '' ) print ( 'year_to_scaliger_common(): Fatal error!' ) print ( ' Illegal input Y = 0.' ) raise Exception ( 'year_to_scaliger_common(): Fatal error!' ) # # Adjust for missing year 0. # if ( y < 0 ): y2 = y + 1 else: y2 = y # # Now shift so 4713 BC becomes the year 1. # y2 = y2 + 4713 c1 = floor ( ( y2 - 1 ) / 28 ) c2 = floor ( ( y2 - 1 ) / 19 ) c3 = floor ( ( y2 - 1 ) / 15 ) r1 = i4_wrap ( y2, 1, 28 ) r2 = i4_wrap ( y2, 1, 19 ) r3 = i4_wrap ( y2, 1, 15 ) return c1, c2, c3, r1, r2, r3 def year_to_type_hebrew ( y ): #*****************************************************************************80 # ## year_to_type_hebrew() returns the type of a Hebrew year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 332. # # Input: # # integer Y, the year. # # Output: # # integer TYPE, the year type. # 1, Common, Deficient, 12 months, 353 days # 2, Common, Regular, 12 months, 354 days # 3, Common, Abundant, 12 months, 355 days # 4, Embolismic, Deficient, 13 months, 383 days # 5, Embolismic, Regular, 13 months, 384 days # 6, Embolismic, Abundant, 13 months, 385 days. # if ( y <= 0 ): print ( '' ) print ( 'year_to_type_hebrew(): Fatal error!' ) print ( ' Illegal input Y = 0.' ) raise Exception ( 'year_to_type_hebrew(): Fatal error!' ) jed = new_year_to_jed_hebrew ( y ) jed2 = new_year_to_jed_hebrew ( y + 1 ) year_length_days = round ( jed2 - jed ) if ( year_length_days == 353 ): type = 1 elif ( year_length_days == 354 ): type = 2 elif ( year_length_days == 355 ): type = 3 elif ( year_length_days == 383 ): type = 4 elif ( year_length_days == 384 ): type = 5 elif ( year_length_days == 385 ): type = 6 else: type = 0 print ( '' ) print ( 'year_to_type_hebrew(): Fatal error!' ) print ( ' Computed an illegal type = ', type ) raise Exception ( 'year_to_type_hebrew(): Fatal error!' ) return type def yj_check_common ( y, j ): #*****************************************************************************80 # ## yj_check_common() checks a Common YJ date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date, possibly corrected. # # logical ierror: True if an error was found. # # # Check the year. # ierror = y_check_common ( y ) if ( ierror ): return y, j, ierror # # Make sure J is not too small or too big. # y, j = j_borrow_common ( y, j ) y, j = j_carry_common ( y, j ) return y, j, ierror def yj_check_english ( y, j ): #*****************************************************************************80 # ## yj_check_english() checks an English YJ date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date, possibly corrected. # # logical ierror: True if an error was found. # # # Check the year. # ierror = y_check_english ( y ) if ( ierror ): return y, j, ierror # # Make sure J is not too small or too big. # y, j = j_borrow_english ( y, j ) y, j = j_carry_english ( y, j ) return y, j, ierror def yj_check_gregorian ( y, j ): #*****************************************************************************80 # ## yj_check_gregorian() checks a Gregorian YJ date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date, possibly corrected. # # logical ierror: True if an error was found. # # # Check the year. # ierror = y_check_gregorian ( y ) if ( ierror ): return y, j, ierror # # Make sure J is not too small or too big. # y, j = j_borrow_gregorian ( y, j ) y, j = j_carry_gregorian ( y, j ) return y, j, ierror def yj_check_hebrew ( y, j ): #*****************************************************************************80 # ## yj_check_hebrew() checks a Hebrew YJ date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date, possibly corrected. # # logical ierror: True if an error was found. # # # Check the year. # ierror = y_check_hebrew ( y ) if ( ierror ): return y, j, ierror # # Make sure J is not too small or too big. # y, j = j_borrow_hebrew ( y, j ) y, j = j_carry_hebrew ( y, j ) return y, j, ierror def yj_check_islamic ( y, j ): #*****************************************************************************80 # ## yj_check_islamic() checks an Islamic YJ date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date, possibly corrected. # # logical ierror: True if an error was found. # # # Check the year. # ierror = y_check_islamic ( y ) if ( ierror ): return y, j, ierror # # Make sure J is not too small or too big. # y, j = j_borrow_islamic ( y, j ) y, j = j_carry_islamic ( y, j ) return y, j, ierror def yj_check_julian ( y, j ): #*****************************************************************************80 # ## yj_check_julian() checks a Julian YJ date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date, possibly corrected. # # logical ierror: True if an error was found. # # # Check the year. # ierror = y_check_julian ( y ) if ( ierror ): return y, j, ierror # # Make sure J is not too small or too big. # y, j = j_borrow_julian ( y, j ) y, j = j_carry_julian ( y, j ) return y, j, ierror def yj_check_republican ( y, j ): #*****************************************************************************80 # ## yj_check_republican() checks a Republican YJ date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date, possibly corrected. # # logical ierror: True if an error was found. # # # Check the year. # ierror = y_check_republican ( y ) if ( ierror ): return y, j, ierror # # Make sure J is not too small or too big. # y, j = j_borrow_republican ( y, j ) y, j = j_carry_republican ( y, j ) return y, j, ierror def yj_check_roman ( y, j ): #*****************************************************************************80 # ## yj_check_roman() checks a Roman YJ date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, the YJ date. # # Output: # # integer Y, J, the YJ date, possibly corrected. # # logical ierror: True if an error was found. # # # Check the year. # ierror = y_check_roman ( y ) if ( ierror ): return y, j, ierror # # Make sure J is not too small or too big. # y, j = j_borrow_roman ( y, j ) y, j = j_carry_roman ( y, j ) return y, j, ierror def yjf_to_jed_common ( y, j, f ): #*****************************************************************************80 # ## yjf_to_jed_common() converts a Common YJF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, real F, the YJF date. # # Output: # # real JED, the Julian Ephemeris Date. # # # Copy the input. # y1 = y j1 = j f1 = f # # Check the input. # y1, j1, f1, ierror = yjf_check_common ( y1, j1, f1 ) if ( ierror ): jed = -1.0 return jed # # Convert the input. # y2, m2, d2, f2 = yjf_to_ymdf_common ( y1, j1, f1 ) jed = ymdf_to_jed_common ( y2, m2, d2, f2 ) return jed def yjf_to_jed_english ( y, j, f ): #*****************************************************************************80 # ## yjf_to_jed_english() converts an English YJF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, real F, the YJF date. # # Output: # # real JED, the Julian Ephemeris Date. # # # Copy the input. # y1 = y j1 = j f1 = f # # Check the input. # y1, j1, ierror = yj_check_english ( y1, j1 ) if ( ierror ): jed = -1.0 return jed # # Convert the input. # y2, m2, d2, f2 = yjf_to_ymdf_english ( y1, j1, f1 ) jed = ymdf_to_jed_english ( y2, m2, d2, f2 ) return jed def yjf_to_jed_gregorian ( y, j, f ): #*****************************************************************************80 # ## yjf_to_jed_gregorian() converts a Gregorian YJF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, real F, the YJF date. # # Output: # # real JED, the Julian Ephemeris Date. # # # Copy the input. # y1 = y j1 = j f1 = f # # Check the input. # y1, j1, ierror = yj_check_gregorian ( y1, j1 ) if ( ierror ): jed = -1.0 return jed # # Convert the input. # y2, m2, d2, f2 = yjf_to_ymdf_gregorian ( y1, j1, f1 ) jed = ymdf_to_jed_gregorian ( y2, m2, d2, f2 ) return jed def yjf_to_jed_hebrew ( y, j, f ): #*****************************************************************************80 # ## yjf_to_jed_hebrew() converts a Hebrew YJF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, real F, the YJF date. # # Output: # # real JED, the Julian Ephemeris Date. # # # Copy the input. # y1 = y j1 = j f1 = f # # Check the input. # y1, j1, ierror = yj_check_hebrew ( y1, j1 ) if ( ierror ): jed = -1.0 return jed # # Convert the input. # y2, m2, d2, f2 = yjf_to_ymdf_hebrew ( y1, j1, f1 ) jed = ymdf_to_jed_hebrew ( y2, m2, d2, f2 ) return jed def yjf_to_jed_islamic_a ( y, j, f ): #*****************************************************************************80 # ## yjf_to_jed_islamic_a() converts an Islamic-A YJF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, real F, the YJF date. # # Output: # # real JED, the Julian Ephemeris Date. # # # Copy the input. # y1 = y j1 = j f1 = f # # Check the input. # y1, j1, ierror = yj_check_islamic ( y1, j1 ) if ( ierror ): jed = -1.0 return jed # # Convert the input. # y2, m2, d2, f2 = yjf_to_ymdf_islamic ( y1, j1, f1 ) jed = ymdf_to_jed_islamic_a ( y2, m2, d2, f2 ) return jed def yjf_to_jed_islamic_b ( y, j, f ): #*****************************************************************************80 # ## yjf_to_jed_islamic_b() converts an Islamic-B YJF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, real F, the YJF date. # # Output: # # real JED, the Julian Ephemeris Date. # # # Copy the input. # y1 = y j1 = j f1 = f # # Check the input. # y1, j1, ierror = yj_check_islamic ( y1, j1 ) if ( ierror ): jed = -1.0 return jed # # Convert the input. # y2, m2, d2, f2 = yjf_to_ymdf_islamic ( y1, j1, f1 ) jed = ymdf_to_jed_islamic_b ( y2, m2, d2, f2 ) return jed def yjf_to_jed_julian ( y, j, f ): #****************************************************************************** # ## yjf_to_jed_julian() converts a Julian YJF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, real F, the YJF date. # # Output: # # real JED, the Julian Ephemeris Date. # # # Copy the input. # y1 = y j1 = j f1 = f # # Check the input. # y1, j1, ierror = yj_check_julian ( y1, j1 ) if ( ierror ): jed = -1.0 return jed # # Convert the input. # y2, m2, d2, f2 = yjf_to_ymdf_julian ( y1, j1, f1 ) jed = ymdf_to_jed_julian ( y2, m2, d2, f2 ) return jed def yjf_to_jed_republican ( y, j, f ): #*****************************************************************************80 # ## yjf_to_jed_republican() converts a Republican YJF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, real F, the YJF date. # # Output: # # real JED, the Julian Ephemeris Date. # # # Copy the input. # y1 = y j1 = j f1 = f # # Check the input. # y1, j1, ierror = yj_check_republican ( y1, j1 ) if ( ierror ): jed = -1.0 return jed # # Convert the input. # y2, m2, d2, f2 = yjf_to_ymdf_republican ( y1, j1, f1 ) jed = ymdf_to_jed_republican ( y2, m2, d2, f2 ) return jed def yjf_to_jed_roman ( y, j, f ): #*****************************************************************************80 # ## yjf_to_jed_roman() converts a Roman YJF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, J, real F, the YJF date. # # Output: # # real JED, the Julian Ephemeris Date. # # # Copy the input. # y1 = y j1 = j f1 = f # # Check the input. # y1, j1, ierror = yj_check_roman ( y1, j1 ) if ( ierror ): jed = -1.0 return jed # # Convert the input. # y2, m2, d2, f2 = yjf_to_ymdf_roman ( y1, j1, f1 ) jed = ymdf_to_jed_roman ( y2, m2, d2, f2 ) return jed def yjf_to_ymdf_common ( y1, j1, f1 ): #*****************************************************************************80 # ## yjf_to_ymdf_common() converts a Common date from YJF to YMDF format. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, J1, real F1, the YJF date. # # Output: # # integer Y2, M2, D2, real F2, the YMDF date. # # # Copy the input. # y2 = y1 j2 = j1 f2 = f1 # # Check the input. # y2, j2, f2, ierror = yjf_check_common ( y2, j2, f2 ) if ( ierror ): y2 = 0 m2 = 0 d2 = 0 f2 = 0.0 return y2, m2, d2, f2 # # Convert the input. # d2 = j2 m2 = 1 y2, m2, d2 = day_borrow_common ( y2, m2, d2 ) y2, m2, d2 = day_carry_common ( y2, m2, d2 ) return y2, m2, d2, f2 def yjf_to_ymdf_english ( y1, j1, f1 ): #*****************************************************************************80 # ## yjf_to_ymdf_english() converts an English date from YJF to YMDF format. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, J1, real F1, the YJF date. # # Output: # # integer Y2, M2, D2, real F2, the YMDF date. # # # Copy the input. # y2 = y1 j2 = j1 f2 = f1 # # Check the input. # y2, j2, ierror = yj_check_english ( y2, j2 ) if ( ierror ): y2 = 0 m2 = 0 d2 = 0 f2 = 0.0 return y2, m2, d2, f2 # # Convert the input. # m2 = 1 d2 = j2 y2, m2, d2 = day_borrow_english ( y2, m2, d2 ) y2, m2, d2 = day_carry_english ( y2, m2, d2 ) return y2, m2, d2, f2 def yjf_to_ymdf_gregorian ( y1, j1, f1 ): #*****************************************************************************80 # ## yjf_to_ymdf_gregorian() converts a Gregorian date from YJF to YMDF format. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, J1, real F1, the YJF date. # # Output: # # integer Y2, M2, D2, real F2, the YMDF date. # # # Copy the input. # y2 = y1 j2 = j1 f2 = f1 # # Check the input. # y2, j2, ierror = yj_check_gregorian ( y2, j2 ) if ( ierror ): y2 = 0 m2 = 0 d2 = 0 f2 = 0.0 return y2, m2, d2, f2 # # Convert the input. # m2 = 1 d2 = j2 y2, m2, d2 = day_borrow_gregorian ( y2, m2, d2 ) y2, m2, d2 = day_carry_gregorian ( y2, m2, d2 ) return y2, m2, d2, f2 def yjf_to_ymdf_hebrew ( y1, j1, f1 ): #*****************************************************************************80 # ## yjf_to_ymdf_hebrew() converts a YJF to YMDF date, both in the Hebrew calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, J1, real F1, the YJF date. # # Output: # # integer Y2, M2, D2, real F2, the YMDF date. # # # Copy the input. # y2 = y1 j2 = j1 f2 = f1 # # Check the input. # y2, j2, ierror = yj_check_hebrew ( y2, j2 ) if ( ierror ): y2 = 0 m2 = 0 d2 = 0 f2 = 0.0 return y2, m2, d2, f2 # # Convert the input. # m2 = 1 d2 = j2 y2, m2, d2 = day_borrow_hebrew ( y2, m2, d2 ) y2, m2, d2 = day_carry_hebrew ( y2, m2, d2 ) return y2, m2, d2, f2 def yjf_to_ymdf_islamic ( y1, j1, f1 ): #*****************************************************************************80 # ## yjf_to_ymdf_islamic(): YJF to YMDF date, both in the Islamic calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, J1, real F1, the YJF date. # # Output: # # integer Y2, M2, D2, real F2, the YMDF date. # # # Copy the input. # y2 = y1 j2 = j1 f2 = f1 # # Check the input. # y2, j2, ierror = yj_check_islamic ( y2, j2 ) if ( ierror ): y2 = 0 m2 = 0 d2 = 0 f2 = 0.0 return y2, m2, d2, f2 # # Convert the input. # m2 = 1 d2 = j2 y2, m2, d2 = day_borrow_islamic ( y2, m2, d2 ) y2, m2, d2 = day_carry_islamic ( y2, m2, d2 ) return y2, m2, d2, f2 def yjf_to_ymdf_julian ( y1, j1, f1 ): #*****************************************************************************80 # ## yjf_to_ymdf_julian() converts a YJF to YMDF date, both in the Julian calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, J1, real F1, the YJF date. # # Output: # # integer Y2, M2, D2, real F2, the YMDF date. # # # Copy the input. # y2 = y1 j2 = j1 f2 = f1 # # Check the input. # y2, j2, ierror = yj_check_julian ( y2, j2 ) if ( ierror ): y2 = 0 m2 = 0 d2 = 0 f2 = 0.0 return y2, m2, d2, f2 # # Convert the input. # m2 = 1 d2 = j2 y2, m2, d2 = day_borrow_julian ( y2, m2, d2 ) y2, m2, d2 = day_carry_julian ( y2, m2, d2 ) return y2, m2, d2, f2 def yjf_to_ymdf_republican ( y1, j1, f1 ): #*****************************************************************************80 # ## yjf_to_ymdf_republican(): YJF to YMDF date in the Republican calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, J1, real F1, the YJF date. # # Output: # # integer Y2, M2, D2, real F2, the YMDF date. # # # Copy the input. # y2 = y1 j2 = j1 f2 = f1 # # Check the input. # y2, j2, ierror = yj_check_republican ( y2, j2 ) if ( ierror ): y2 = 0 m2 = 0 d2 = 0 f2 = 0.0 return y2, m2, d2, f2 # # Convert the input. # m2 = 1 d2 = j2 y2, m2, d2 = day_borrow_republican ( y2, m2, d2 ) y2, m2, d2 = day_carry_republican ( y2, m2, d2 ) return y2, m2, d2, f2 def yjf_to_ymdf_roman ( y1, j1, f1 ): #*****************************************************************************80 # ## yjf_to_ymdf_roman() converts a YJF to YMDF date in the Roman calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, J1, real F1, the YJF date. # # Output: # # integer Y2, M2, D2, real F2, the YMDF date. # # # Copy the input. # y2 = y1 j2 = j1 f2 = f1 # # Check the input. # y2, j2, ierror = yj_check_roman ( y2, j2 ) if ( ierror ): y2 = 0 m2 = 0 d2 = 0 f2 = 0.0 return y2, m2, d2, f2 # # Convert the input. # m2 = 1 d2 = j2 y2, m2, d2 = day_borrow_roman ( y2, m2, d2 ) y2, m2, d2 = day_carry_roman ( y2, m2, d2 ) return y2, m2, d2, f2 def ym_check_alexandrian ( y, m ): #*****************************************************************************80 # ## ym_check_alexandrian() checks an Alexandrian YM date. # # Discussion: # # If the month is less than 1, then the month is incremented # by the number of months in the PREVIOUS year, and the year is # decremented by 1. # # If the month is greater than the number of months in the CURRENT year, # then the month is decremented by the number of months in the CURRENT year, # and the year incremented by 1. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the YM date. # # Output: # # integer Y, M, the YM date, possibly corrected. # # logical IERROR: True if an error was found. # # # Check the year. # ierror = y_check_alexandrian ( y ) if ( ierror ): return y, m, ierror # # Make sure the month isn't too small or too big. # y, m = month_borrow_alexandrian ( y, m ) y, m = month_carry_alexandrian ( y, m ) return y, m, ierror def ym_check_bahai ( y, m ): #*****************************************************************************80 # ## ym_check_bahai() checks a Bahai YM date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the YM date. # # Output: # # integer Y, M, the YM date, possibly corrected. # # logical IERROR: True if an error was detected. # # # Check the year. # ierror = y_check_bahai ( y ); if ( ierror ): return y, m, ierror if ( m < 1 or year_length_months_bahai ( y ) < m ): ierror = True return y, m, ierror return y, m, ierror def ym_check_common ( y, m ): #*****************************************************************************80 # ## ym_check_common() checks a Common YM date. # # Discussion: # # If the month is less than 1, then the month is incremented # by 12, and the year decremented by 1, repeatedly, until # the month is greater than or equal to 1. # # If the month is greater than 12, then the month is decremented # by 12, and the year incremented by 1, repeatedly, until the # month is less than or equal to 12. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, the YM date. # # Output: # # integer Y, M, the YM date, after normalization. # # logical ierror: True if an error was found. # # # Check the year. # ierror = y_check_common ( y ) if ( ierror ): return y, m, ierror # # Make sure the month isn't too small or too big. # y, m = month_borrow_common ( y, m ) y, m = month_carry_common ( y, m ) return y, m, ierror def ym_check_eg_civil ( y, m ): #*****************************************************************************80 # ## ym_check_eg_civil() checks an Egyptian Civil YM date. # # Discussion: # # If the month is less than 1, then the month is incremented # by the number of months in the PREVIOUS year, and the year is # decremented by 1. # # If the month is greater than the number of months in the CURRENT year, # then the month is decremented by the number of months in the CURRENT year, # and the year incremented by 1. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the YM date. # # Output: # # integer Y, M, the YM date, possibly corrected. # # logical ierror: True if an error was detected. # # # Check the year. # ierror = y_check_eg_civil ( y ) if ( ierror ): return y, m, ierror # # Make sure the month isn't too small or too big. # y, m = month_borrow_eg_civil ( y, m ) y, m = month_carry_eg_civil ( y, m ) return y, m, ierror def ym_check_english ( y, m ): #*****************************************************************************80 # ## ym_check_english() checks an English YM date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the YM date. # # Output: # # integer Y, M, the YM date, possibly corrected. # # logical ierror: True if an error was detected. # # # Check the year. # ierror = y_check_english ( y ) if ( ierror ): return y, m, ierror # # Make sure the month isn't too small or too big. # y, m = month_borrow_english ( y, m ) y, m = month_carry_english ( y, m ) return y, m, ierror def ym_check_gregorian ( y, m ): #*****************************************************************************80 # ## ym_check_gregorian() checks a Gregorian YM date. # # Discussion: # # If the month is less than 1, then the month is incremented # by 12, and the year decremented by 1, repeatedly, until # the month is greater than or equal to 1. # # If the month is greater than 12, then the month is decremented # by 12, and the year incremented by 1, repeatedly, until the # month is less than or equal to 12. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the YM date. # # Output: # # integer Y, M, the YM date, possibly corrected. # # logical ierror: True if an error was detected. # # # Check the year. # ierror = y_check_gregorian ( y ) if ( ierror ): return y, m, ierror # # Make sure the month isn't too small or too big. # y, m = month_borrow_gregorian ( y, m ) y, m = month_carry_gregorian ( y, m ) return y, m, ierror def ym_check_hebrew ( y, m ): #*****************************************************************************80 # ## ym_check_hebrew() checks a Hebrew YM date. # # Discussion: # # If the month is less than 1, then the month is incremented # by the number of months in the PREVIOUS year, and the year is # decremented by 1. # # If the month is greater than the number of months in the CURRENT year, # then the month is decremented by the number of months in the CURRENT year, # and the year incremented by 1. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the YM date. # # Output: # # integer Y, M, the YM date, possibly corrected. # # logical ierror: True if an error was detected. # # # Check the year. # ierror = y_check_hebrew ( y ) if ( ierror ): return y, m, ierror # # Make sure the month isn't too small or too big. # y, m = month_borrow_hebrew ( y, m ) y, m = month_carry_hebrew ( y, m ) return y, m, ierror def ym_check_islamic ( y, m ): #*****************************************************************************80 # ## ym_check_islamic() checks an Islamic YM date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the YM date. # # Output: # # integer Y, M, the YM date, possibly corrected. # # logical ierror: True if an error was detected. # # # Check the year. # ierror = y_check_islamic ( y ) if ( ierror ): return y, m, ierror # # Make sure the month isn't too small or too big. # y, m = month_borrow_islamic ( y, m ) y, m = month_carry_islamic ( y, m ) return y, m, ierror def ym_check_julian ( y, m ): #*****************************************************************************80 # ## ym_check_julian() checks a Julian YM date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the YM date. # # Output: # # integer Y, M, the YM date, possibly corrected. # # logical ierror: True if an error was detected. # # # Check the year. # ierror = y_check_julian ( y ) if ( ierror ): return y, m, ierror # # Make sure the month isn't too small or too big. # y, m = month_borrow_julian ( y, m ) y, m = month_carry_julian ( y, m ) return y, m, ierror def ym_check_republican ( y, m ): #*****************************************************************************80 # ## ym_check_republican() checks a Republican YM date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the YM date. # # Output: # # integer Y, M, the YM date, possibly corrected. # # logical ierror: True if an error was detected. # # # Check the year. # ierror = y_check_republican ( y ) if ( ierror ): return y, m, ierror # # Make sure the month isn't too small or too big. # y, m = month_borrow_republican ( y, m ) y, m = month_carry_republican ( y, m ) return y, m, ierror def ym_check_roman ( y, m ): #*****************************************************************************80 # ## ym_check_roman() checks a Roman YM date. # # Discussion: # # If the month is less than 1, then the month is incremented # by the number of months in the PREVIOUS year, and the year is # decremented by 1. # # If the month is greater than the number of months in the CURRENT year, # then the month is decremented by the number of months in the CURRENT year, # and the year incremented by 1. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the YM date. # # Output: # # integer Y, M, the YM date, possibly corrected. # # logical ierror: True if an error was detected. # # # Check the year. # ierror = y_check_roman ( y ) if ( ierror ): return y, m, ierror # # Make sure the month isn't too small or too big. # y, m = month_borrow_roman ( y, m ) y, m = month_carry_roman ( y, m ) return y, m, ierror def ym_to_decimal ( y, m ): #*****************************************************************************80 # ## ym_to_decimal() converts a Y/M date to a Decimal Y.F date. # # Discussion: # # Each month is take to be 1/12 of a year long, and the decimal value # is returned for the middle of the month. # # 1980 January => 1980.04 # 1980 February => 1980.12 # 1980 March => 1980.21 # 1980 December => 1980.96 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, the YM date. # # Output: # # real YF, the Decimal date. # yf = y + ( 2 * m - 1 ) / 24.0 return yf def ymd_check_alexandrian ( y, m, d ): #*****************************************************************************80 # ## ymd_check_alexandrian() checks an Alexandrian YMD date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date, which may be corrected if necessary. # # logical ierror: True if an error was found. # ierror = False # # Check the year. # if ( y <= 0 ): ierror = True return y, m, d, ierror # # Check the month. # y, m, ierror = ym_check_alexandrian ( y, m ) if ( ierror ): return y, m, d, ierror # # Check the day. # y, m, d = day_borrow_alexandrian ( y, m, d ) y, m, d = day_carry_alexandrian ( y, m, d ) return y, m, d, ierror def ymd_check_common ( y, m, d ): #*****************************************************************************80 # ## ymd_check_common() checks a Common YMD date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date after normalization. # # logical ierror: True if an error was found. # # # Check the year. # ierror = y_check_common ( y ) if ( ierror ): return y, m, d, ierror # # Make sure the month isn't too small or too big. # y, m = month_borrow_common ( y, m ) y, m = month_carry_common ( y, m ) # # Make sure the day isn't too small or too big. # y, m, d = day_borrow_common ( y, m, d ) y, m, d = day_carry_common ( y, m, d ) return y, m, d, ierror def ymd_check_eg_civil ( y, m, d ): #*****************************************************************************80 # ## ymd_check_eg_civil() checks an Egyptian Civil YMD date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date, which may be corrected if necessary. # # logical ierror: True if an error was detected. # # # Check the year. # if ( y <= 0 ): ierror = True return y, m, d, ierror # # Check the month. # y, m, ierror = ym_check_eg_civil ( y, m ) if ( ierror ): return y, m, d, ierror # # Check the day. # y, m, d = day_borrow_eg_civil ( y, m, d ) y, m, d = day_carry_eg_civil ( y, m, d ) return y, m, d, ierror def ymd_check_english ( y, m, d ): #*****************************************************************************80 # ## ymd_check_english() checks an English YMD date. # # Discussion: # # Certain simple errors in dates will be corrected, such as # "31 September 1996" # which will become # "1 October 1996". # # The routine also knows that in the English calendar, the dates # 3 September 1752 through 13 September 1752 are illegal. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date, which may be corrected if necessary. # # logical ierror: True if an error was detected. # # # Check the month. # y, m, ierror = ym_check_english ( y, m ) if ( ierror ): return y, m, d, ierror # # Check the day. # y, m, d = day_borrow_english ( y, m, d ) y, m, d = day_carry_english ( y, m, d ) # # Now make sure that the date does not fall in the # Julian-to-Gregorian calendar switchover limbo. # if ( y == 1752 ): if ( m == 9 ): if ( 3 <= d and d <= 13 ): ierror = True print ( '' ) print ( 'ymd_check_english(): Warning!' ) print ( ' Illegal date.' ) s = ymd_to_s_numeric ( y, m, d ) print ( s ) return y, m, d, ierror def ymd_check_gregorian ( y, m, d ): #*****************************************************************************80 # ## ymd_check_gregorian() checks a Gregorian YMD date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date, which may be corrected if necessary. # # logical ierror: True if an error was detected. # # # Check the month. # y, m, ierror = ym_check_gregorian ( y, m ) if ( ierror ): return y, m, d, ierror # # Check the day. # y, m, d = day_borrow_gregorian ( y, m, d ) y, m, d = day_carry_gregorian ( y, m, d ) return y, m, d, ierror def ymd_check_hebrew ( y, m, d ): #*****************************************************************************80 # ## ymd_check_hebrew() checks a Hebrew YMD date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date, which may be corrected if necessary. # # logical ierror: True if an error was detected. # # # Check the year. # if ( y <= 0 ): ierror = True return y, m, d, ierror # # Check the month. # y, m, ierror = ym_check_hebrew ( y, m ) if ( ierror ): return y, m, d, ierror # # Check the day. # y, m, d = day_borrow_hebrew ( y, m, d ) y, m, d = day_carry_hebrew ( y, m, d ) return y, m, d, ierror def ymd_check_islamic ( y, m, d ): #*****************************************************************************80 # ## ymd_check_islamic() checks an Islamic YMD date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date, which may be corrected if necessary. # # logical ierror: True if an error was detected. # # # Check the year. # if ( y <= 0 ): ierror = True return y, m, d, ierror # # Check the month. # y, m, ierror = ym_check_islamic ( y, m ) if ( ierror ): return y, m, d, ierror # # Check the day. # y, m, d = day_borrow_islamic ( y, m, d ) y, m, d = day_carry_islamic ( y, m, d ) return y, m, d, ierror def ymd_check_julian ( y, m, d ): #*****************************************************************************80 # ## ymd_check_julian() checks a Julian YMD date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date, which may be corrected if necessary. # # logical ierror: True if an error was detected. # # # Check the month. # y, m, ierror = ym_check_julian ( y, m ) if ( ierror ): return y, m, d, ierror # # Check the day. # y, m, d = day_borrow_julian ( y, m, d ) y, m, d = day_carry_julian ( y, m, d ) return y, m, d, ierror def ymd_check_republican ( y, m, d ): #*****************************************************************************80 # ## ymd_check_republican() checks a Republican YMD date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date, which may be corrected if necessary. # # logical ierror: True if an error was detected. # # # Check the year. # if ( y <= 0 ): ierror = True return y, m, d, ierror # # Check the month. # y, m, ierror = ym_check_republican ( y, m ) if ( ierror ): return y, m, d, ierror # # Check the day. # y, m, d = day_borrow_republican ( y, m, d ) y, m, d = day_carry_republican ( y, m, d ) return y, m, d, ierror def ymd_check_roman ( y, m, d ): #*****************************************************************************80 # ## ymd_check_roman() checks a Roman YMD date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer Y, M, D, the YMD date, which may be corrected if necessary. # # logical ierror: True if an error was detected. # ierror = 0 # # Check the year. # if ( y <= 0 ): ierror = True return y, m, d, ierror # # Check the month. # y, m = month_borrow_roman ( y, m ) y, m = month_carry_roman ( y, m ) # # Check the day. # y, m, d = day_borrow_roman ( y, m, d ) y, m, d = day_carry_roman ( y, m, d ) return y, m, d, ierror def ymd_compare ( y1, m1, d1, y2, m2, d2 ): #*****************************************************************************80 # ## ymd_compare() compares two YMD dates. # # Discussion: # # The comparison should work for a pair of dates in any calendar. # # No check is made that the dates are actually legitimate. It is # assumed that the calling routine has already ensured that the # dates are properly "normalized". # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, the first YMD date. # # integer Y2, M2, D2, the second YMD date. # # Output: # # character CMP: # '<' if date 1 precedes date 2; # '=' if date 1 equals date 2; # '>' if date 1 follows date 2; # cmp = '?' # # Compare years... # if ( y1 < y2 ): cmp = '<' elif ( y1 > y2 ): cmp = '>' else: # # ...if necessary, compare months in equal years... # if ( m1 < m2 ): cmp = '<' elif ( m1 > m2 ): cmp = '>' else: # # ...if necessary, compare days in equal months... # if ( d1 < d2 ): cmp = '<' elif ( d1 > d2 ): cmp = '>' else: cmp = '=' end return cmp def ymd_dif_common ( y1, m1, d1, y2, m2, d2 ): #*****************************************************************************80 # ## ymd_dif_common() gets the day difference between two Common YMD dates. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, the first YMD date. # # integer Y2, M2, D2, the second YMD date. # # Output: # # integer DAYS, the number of days between the dates. # days = 0 # # Check the dates. # y1, m1, d1, ierror = ymd_check_common ( y1, m1, d1 ) if ( ierror ): print ( '' ) print ( 'ymd_dif_common(): Fatal error!' ) print ( ' Y1/M1/D1 is illegal.' ) raise Exception ( 'ymd_dif_common(): Fatal error!' ) y2, m2, d2, ierror = ymd_check_common ( y2, m2, d2 ) if ( ierror ): print ( '' ) print ( 'ymd_dif_common(): Fatal error!' ) print ( ' Y2/M2/D2 is illegal.' ) raise Exception ( 'ymd_dif_common(): Fatal error!' ) jed1 = ymd_to_jed_common ( y1, m1, d1 ) jed2 = ymd_to_jed_common ( y2, m2, d2 ) days = round ( jed2 - jed1 ) return days def ymd_inc_ymd_common ( y1, m1, d1, yn, mn, dn ): #*****************************************************************************80 # ## ymd_inc_ymd_common() increments a Common YMD date by a YMD increment. # # Discussion: # # You often see on old gravestones statements like # # "Joe Blow died on May 8 1784 aged 38 Years, 7 Months and 5 Days." # # It's not exactly clear how to interpret such a statement, since # we can't actually convert 38 Years, 7 Months and 5 Days to a number # of days. (Years and months vary in their day length). However, # we can assume that what was meant was, if you take the year, month # and day of Joe Blow's birthday, and you: # # add 38 to the year, # add 7 to the month, and if you go past December, subtract 12 and # increment the year, # add 5 to the day, and if you go past the length of the month, # increment the month and decrement the day appropriately. # # Notice, in particular, that if you do the operations in the reverse # order, you may get a different answer, since what you do with a large # day value depends on the month you assume you are working in. # # Just warning you that this is a poorly posed problem. # # Thanks to Charlie Cullen for pointing out this little problem to me. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, the YMD date. # # integer YN, MN, DN, the increment to the YMD date. # # Output: # # integer Y2, M2, D2, the incremented YMD date. # # # TEMPORARY # f1 = 0.0 fn = 0.0 y2 = y1 + yn m2 = m1 + mn d2 = d1 + dn f2 = f1 + fn y2, m2, d2, f2, ierror = ymdf_check_common ( y2, m2, d2, f2 ) if ( ierror ): y2 = 0 m2 = 0 d2 = 0 f2 = 0.0 return y2, m2, d2 return y2, m2, d2 def ymd_to_decimal ( y, m, d ): #*****************************************************************************80 # ## ymd_to_decimal() converts a Y/M/D date to a Decimal Y.F date. # # Discussion: # # The day is assumed to be at noon. In other words, 1983 January 1st has # a decimal value of 1983 + 0.5 / 365. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # real YMD, the Decimal date. # # # How many days between January 1st and day D? # day_min = 1 days = ymd_dif_common ( y, m, day_min, y, m, d ) # # How many days in this year total? # day_max = year_length_days_common ( y ) # # The decimal part of the year is ( D + 0.5 ) / DMAX. # f = ( days + 0.5 ) / day_max yf = y + f return yf def ymd_to_jed_common ( y, m, d ): #*****************************************************************************80 # ## ymd_to_jed_common() converts a Common YMD date to a JED. # # Discussion: # # The "common" calendar is meant to be the calendar which is Julian up to # day JED = 2299160, and Gregorian from day JED = 2299161 and after. # # The Julian Ephemeris Date is essentially a count of the number # of days that have elapsed since noon, 1 January 4713 BC, at # Greenwich, England. Strictly speaking, the Julian Ephemeris Date # is counted from noon, and thus day "0" began at noon on 1 January 4713 BC, # and ended at noon on 2 January 4713 BC. # # The Julian Ephemeris Date was devised by Joseph Scaliger in 1583. # # The Julian Ephemeris Date has been adopted by astronomers as # a convenient reference for dates. # # Example: # # Y M D JED # -------------- ------- # BC 4713 Jan 1 0 # AD 1968 May 23 2440000 # AD 1984 Dec 31 2446065 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # real JED, the Julian Ephemeris Date. # # # Copy the month and year. # y2 = 1582 m2 = 10 d2 = 4+1 cmp = ymd_compare ( y, m, d, y2, m2, d2 ) if ( cmp == '<' ): jed = ymd_to_jed_julian ( y, m, d ); return jed # # Use the Gregorian calendar for dates strictly after 1752/9/13. # y2 = 1582 m2 = 10 d2 = 15-1 cmp = ymd_compare ( y, m, d, y2, m2, d2 ) if ( cmp == '>' ): jed = ymd_to_jed_gregorian ( y, m, d ); return jed print ( '' ) print ( 'ymd_to_jed_common(): Fatal error!' ) print ( ' Illegal date!' ) raise Exception ( 'ymd_to_jed_common(): Fatal error!' ) return jed def ymd_to_jed_gregorian ( y, m, d ): #*****************************************************************************80 # ## ymd_to_jed_gregorian() converts a Gregorian YMD date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, the YMD date. # # Output: # # real JED, the corresponding JED. # from math import floor # # Check the date. # y, m, d, ierror = ymd_check_gregorian ( y, m, d ) if ( ierror ): jed = -1.0 return jed # # Account for the missing year 0 by moving negative years up one. # y2 = y_common_to_astronomical ( y ) # # Convert the calendar date to a computational date. # y_prime = y2 + 4716 - floor ( ( 14 - m ) / 12 ) m_prime = ( ( m + 9 ) % 12 ) d_prime = d - 1 # # Convert the computational date to a JED. # j1 = floor ( ( 1461 * y_prime ) / 4 ) j2 = floor ( ( 153 * m_prime + 2 ) / 5 ) g = floor ( ( y_prime + 184 ) / 100 ) g = floor ( 3 * g / 4 ) - 38 jed = j1 + j2 + d_prime - 1401 - g - 0.5 return jed def ymd_to_jed_julian ( y, m, d ): #*****************************************************************************80 # ## ymd_to_jed_julian() converts a Julian YMD date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, the YMD date. # # Output: # # real JED, the Julian Ephemeris Date. # from math import floor # # Check the date. # y, m, d, ierror = ymd_check_julian ( y, m, d ) if ( ierror ): jed = -1.0; return jed # # Account for the missing year 0 by moving negative years up one. # y2 = y_common_to_astronomical ( y ) # # Convert the calendar date to a computational date. # y_prime = y2 + 4716 - floor ( ( 14 - m ) / 12 ) m_prime = ( ( m + 9 ) % 12 ) d_prime = d - 1 # # Convert the computational date to a JED. # j1 = floor ( ( 1461 * y_prime ) / 4 ) j2 = floor ( ( 153 * m_prime + 2 ) / 5 ) jed = j1 + j2 + d_prime - 1401 - 0.5 return jed def ymd_to_nyt ( y, m, d ): #*****************************************************************************80 # ## ymd_to_nyt() converts a YMD date to an NYT date. # # Discussion: # # The New York Times began publication with Volume 1, Issue 1 on # Thursday, 18 September 1851. # # The Volume number is incremented annually, on 18 September. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Reference: # # Anonymous, # A Correction; Welcome to 51,254, # The New York Times, # 01 January 2000, Volume 149, Issue 51254. # # James Barron, # What's in a Number? 143 Years of News, # The New York Times, # 14 March 1995, Volume 144, Issue 50000. # # The New York Times, # Page One, 1896-1996, A Special Commemorative Edition Celebrating the # 100th Anniversary of the Purchase of the New York Times by Adolph S Ochs, # Galahad Books, 1996, # ISBN: 0-88365-961-1, # LC: D411.P25. # # The New York Times, # The Complete First Pages, 1851-2008, # Black Dog and Leventhal Publishers, 2008, # ISBN13: 978-1-57912-749-7, # LC: D351.N53. # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer VOLUME, ISSUE, the New York Times volume and issue. # f = 0.0 jed = ymdf_to_jed_common ( y, m, d, f ) volume, issue = jed_to_nyt ( jed ) return volume, issue def ymd_to_s_alexandrian ( y, m, d ): #*****************************************************************************80 # ## ymd_to_s_alexandrian() "prints" an Alexandrian YMD date into a string. # # Format: # # DayNumber MonthName YearNumber AX # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # string S, a representation of the date. # sm = month_to_month_name_eg_civil ( m ) s = ( '%d %s %d AX' % ( d, sm, y ) ) return def ymd_to_s_common ( y, m, d ): #*****************************************************************************80 # ## ymd_to_s_common() writes a Common YMD date into a string. # # Format: # # CE YYYY/MM/DD # BCE YYYY/MM/DD # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 July 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # string S, a representation of the date. # if ( 0 <= y ): s1 = 'CE' else: s1 = 'BCE' if ( 0 <= y ): s2 = str ( y ) else: s2 = str ( -y ) s3 = str ( m ) s4 = str ( d ) s = s1 + ' ' + s2 + '/' + s3 + '/' + s4 return s def ymd_to_s_eg_civil ( y, m, d ): #*****************************************************************************80 # ## ymd_to_s_eg_civil() "prints" an Egyptian Civil YMD date into a string. # # Format: # # DayNumber MonthName YearNumber EN # # Discussion: # # "EN" stands for the Era of Nabonassar, a Babylonian king who # acceded in 747 BC, used by the astronomer Ptolemy to assign # an artificial starting year for the Egyptian calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # string S, a representation of the date. # sm = month_to_month_name_eg_civil ( m ) s = ( '%02d %s %04d EN' % ( d, sm, y ) ) return s def ymd_to_s_eg_lunar ( y, m, d ): #*****************************************************************************80 # ## ymd_to_s_eg_lunar() "prints" an Egyptian Lunar YMD date into a string. # # Format: # # DayNumber MonthName YearNumber EL # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # string S, a representation of the date. # sm = month_to_month_name_eg_lunar ( m ) s = ( '%02d %s %04d EL' % ( d, sm, y ) ) return s def ymd_to_s_gregorian ( y, m, d ): #*****************************************************************************80 # ## ymd_to_s_gregorian() writes a Gregorian YMD date into a string. # # Format: # # AD YYYY/MM/DD # BC YYYY/MM/DD # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 24 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # string S, a representation of the date. # if ( 0 <= y ): s1 = 'AD' else: s1 = 'BC' if ( 0 <= y ): s2 = str ( y ) else: s2 = str ( -y ) s3 = str ( m ) s4 = str ( d ) s = s1 + ' ' + s2 + '/' + s3 + '/' + s4 return s def ymd_to_s_julian ( y, m, d ): #*****************************************************************************80 # ## ymd_to_s_julian() writes a Julian YMD date into a string. # # Format: # # AD YYYY/MM/DD # BC YYYY/MM/DD # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 January 2018 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # string S, a representation of the date. # if ( 0 <= y ): s1 = 'AD' else: s1 = 'BC' if ( 0 <= y ): s2 = str ( y ) else: s2 = str ( -y ) s3 = str ( m ) s4 = str ( d ) s = s1 + ' ' + s2 + '/' + s3 + '/' + s4 return s def ymd_to_s_numeric ( y, m, d ): #*****************************************************************************80 # ## ymd_to_s_numeric() writes a YMD date into a string. # # Format: # # YYYY/MM/DD # or # -YYYY/MM/DD # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 06 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # string S, a representation of the date. # s = ( '%d/%02d/%02d' % ( y, m, d ) ) return s def ymd_to_weekday_common ( y, m, d ): #*****************************************************************************80 # ## ymd_to_weekday_common() returns the weekday of a Common YMD date. # # Discussion: # # The "common" calendar is meant to be the calendar which is Julian up to # day JED = 2299160, and Gregorian from day JED = 2299161 and after. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 28 April 2010 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, the YMD date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # f = 0.5 jed = ymdf_to_jed_common ( y, m, d, f ) w, f2 = jed_to_weekday ( jed ) return w def ymd_to_weekday_common_test ( ): #*****************************************************************************80 # ## ymd_to_weekday_common_test() tests ymd_to_weekday_common(). # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 July 2017 # # Author: # # John Burkardt # print ( '' ) print ( 'ymd_to_weekday_common_test():' ) print ( ' ymd_to_weekday_common() returns the day of the week' ) print ( ' for Y/M/D dates in the Common calendar.' ) print ( '' ) print ( ' YMD weekday weekday' ) print ( ' Tabulated Computed' ) print ( '' ) n_data = 0 while ( True ): n_data, y, m, d, w1 = weekday_values ( n_data ) if ( n_data == 0 ): break s3 = ymd_to_s_common ( y, m, d ) w2 = ymd_to_weekday_common ( y, m, d ) s1 = weekday_to_name_common ( w1 ) s2 = weekday_to_name_common ( w2 ) print ( ' %20s %9s %9s' % ( s3, s1, s2 ) ) return def ymdf_check_common ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_check_common() checks a Common YMDF date. # # Discussion: # # Certain simple errors in dates will be corrected, such as # "31 September 1996" # which will become # "1 October 1996". # # The routine also knows that in the Common calendar, the dates # 5 October 1582 through 14 October 1582 are illegal. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date, which may be corrected. # # integer IERROR, is 0 if the date is legal. # y, m, d, ierror = ymd_check_common ( y, m, d ) if ( ierror ): return y, m, d, f, ierror y, m, d, f = frac_borrow_common ( y, m, d, f ) y, m, d, f = frac_carry_common ( y, m, d, f ) return y, m, d, f, ierror def ymdf_check_english ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_check_english() checks an English YMDF date. # # Discussion: # # Certain simple errors in dates will be corrected, such as # "31 September 1996" # which will become # "1 October 1996". # # The routine also knows that in the English calendar, the dates # 3 September 1752 through 13 September 1752 are illegal. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date, which may be corrected. # # integer IERROR, is 0 if the date is legal. # y, m, d, ierror = ymd_check_english ( y, m, d ) if ( ierror ): return y, m, d, f, ierror y, m, d, f = frac_borrow_english ( y, m, d, f ) y, m, d, f = frac_carry_english ( y, m, d, f ) return y, m, d, f, ierror def ymdf_check_gregorian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_check_gregorian() checks a Gregorian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date, which may be corrected. # # integer IERROR, is 0 if the date is legal. # y, m, d, ierror = ymd_check_gregorian ( y, m, d ) if ( ierror ): return y, m, d, f, ierror y, m, d, f = frac_borrow_gregorian ( y, m, d, f ) y, m, d, f = frac_carry_gregorian ( y, m, d, f ) return y, m, d, f, ierror def ymdf_check_hebrew ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_check_hebrew() checks a Hebrew YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date, which may be corrected. # # integer IERROR, is 0 if the date is legal. # ierror = 0 y, m, d, ierror = ymd_check_hebrew ( y, m, d ) if ( ierror ): return y, m, d, f, ierror y, m, d, f = frac_borrow_hebrew ( y, m, d, f ) y, m, d, f = frac_carry_hebrew ( y, m, d, f ) return y, m, d, f, ierror def ymdf_check_islamic ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_check_islamic() checks an Islamic YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date, which may be corrected. # # integer IERROR, is 0 if the date is legal. # ierror = 0 y, m, d, ierror = ymd_check_islamic ( y, m, d ) if ( ierror ): return y, m, d, f, ierror y, m, d, f = frac_borrow_islamic ( y, m, d, f ) y, m, d, f = frac_carry_islamic ( y, m, d, f ) return y, m, d, f, ierror def ymdf_check_julian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_check_julian() checks a Julian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date, which may be corrected. # # integer IERROR, is 0 if the date is legal. # ierror = 0 y, m, d, ierror = ymd_check_julian ( y, m, d ) if ( ierror ): return y, m, d, f, ierror y, m, d, f = frac_borrow_julian ( y, m, d, f ) y, m, d, f = frac_carry_julian ( y, m, d, f ) return y, m, d, f, ierror def ymdf_check_republican ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_check_republican() checks a Republican YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date, which may be corrected. # # integer IERROR, is 0 if the date is legal. # ierror = 0 y, m, d, ierror = ymd_check_republican ( y, m, d ) if ( ierror ): return y, m, d, f, ierror y, m, d, f = frac_borrow_republican ( y, m, d, f ) y, m, d, f = frac_carry_republican ( y, m, d, f ) return y, m, d, f, ierror def ymdf_check_roman ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_check_roman() checks a Roman YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer Y, M, D, real F, the YMDF date, which may be corrected. # # integer IERROR, is 0 if the date is legal. # y, m, d, ierror = ymd_check_roman ( y, m, d ) if ( ierror ): return y, m, d, f, ierror y, m, d, f = frac_borrow_roman ( y, m, d, f ) y, m, d, f = frac_carry_roman ( y, m, d, f ) return y, m, d, f, ierror def ymdf_compare ( y1, m1, d1, f1, y2, m2, d2, f2 ): #*****************************************************************************80 # ## ymdf_compare() compares two YMDF dates. # # Discussion: # # The comparison should work for a pair of dates in any calendar. # # No check is made that the dates are actually legitimate. It is # assumed that the calling routine has already ensured that the # dates are properly "normalized". # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 16 March 2001 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the # first YMDF date. # # integer Y2, M2, D2, real F2, the # second YMDF date. # # Output: # # character CMP: # '<' if date 1 precedes date 2 # '=' if date 1 equals date 2 # '>' if date 1 follows date 2 # cmp = '?' # # Compare years... # if ( y1 < y2 ): cmp = '<' elif ( y1 > y2 ): cmp = '>' else: # # ...if necessary, compare months in equal years... # if ( m1 < m2 ): cmp = '<' elif ( m1 > m2 ): cmp = '>' else: # # ...if necessary, compare days in equal months... # if ( d1 < d2 ): cmp = '<' elif ( d1 > d2 ): cmp = '>' else: # # ...if necessary, compare fractional parts. # if ( f1 < f2 ): cmp = '<' elif ( f1 > f2 ): cmp = '>' else: cmp = '=' return cmp def ymdf_dif_common ( y1, m1, d1, f1, y2, m2, d2, f2 ): #*****************************************************************************80 # ## ymdf_dif_common() gets the day difference between two Common YMDF dates. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the first YMDF date. # # integer Y2, M2, D2, real F2, the second YMDF date. # # Output: # # real DAYS, the number of days between the two dates. # # integer IERROR, is 1 if either date is illegal, 0 otherwise. # days = 0.0 # # Check the dates. # y1, m1, d1, f1, ierror = ymdf_check_common ( y1, m1, d1, f1 ) if ( ierror ): return days, ierror y2, m2, d2, f2, ierror = ymdf_check_common ( y2, m2, d2, f2 ) if ( ierror ): return days, ierror jed1 = ymdf_to_jed_common ( y1, m1, d1, f1 ) jed2 = ymdf_to_jed_common ( y2, m2, d2, f2 ) days = jed2 - jed1 return days, ierror def ymdf_dif_english ( y1, m1, d1, f1, y2, m2, d2, f2, d ): #*****************************************************************************80 # ## ymdf_dif_english() gets the day difference between two English YMDF dates. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the first YMDF date. # # integer Y2, M2, D2, real F2, the second YMDF date. # # Output: # # real DAYS, the number of days between the two dates. # # integer IERROR, is 1 if either date is illegal, 0 otherwise. # days = 0.0 # # Check the dates. # y1, m1, d1, f1, ierror = ymdf_check_english ( y1, m1, d1, f1 ) if ( ierror ): return days, ierror y2, m2, d2, f2, ierror = ymdf_check_english ( y2, m2, d2, f2 ) if ( ierror != 0 ): return days, ierror jed1 = ymdf_to_jed_english ( y1, m1, d1, f1 ) jed2 = ymdf_to_jed_english ( y2, m2, d2, f2 ) days = jed2 - jed1 return days, ierror def ymdf_dif_ymdf_common ( y1, m1, d1, f1, y2, m2, d2, f2, yn, mn, dn, fn, ierror ): #*****************************************************************************80 # ## ymdf_dif_ymdf_common() gets the YMDF difference between two Common YMDF dates. # # Discussion: # # This difference is not well defined. A reasonable way to define this # difference is: # # Use Y1, M1, D1, F1 as a base, # # Increment Y1 by 1 repeatedly, until your date is less than # a year before Y2/M2/D2/F2. # # Increment M1 by 1 repeatedly, until your date is less than a # month before Y2/M2/D2/F2. # # Increment D1 by 1 repeatedly, until your data is less than a # day before Y2/M2/D2/F2. # # Measure the fractional day difference. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the first YMDF date. # # integer Y2, M2, D2, real F2, the second YMDF date. # # Output: # # integer YN, MN, DN, real FN, # the difference in years, months, days, and fractional days from the # first date to the second. # # integer IERROR, is 1 if either date is illegal, # 0 otherwise. # # # Check the dates. # y1, m1, d1, f1, ierror = ymdf_check_common ( y1, m1, d1, f1 ) if ( ierror ): return yn, mn, dn, fn, ierror y2, m2, d2, f2, ierror = ymdf_check_common ( y2, m2, d2, f2 ) if ( ierror ): return yn, mn, dn, fn, ierror # # Compare the dates. # cmp = ymdf_compare ( y1, m1, d1, f1, y2, m2, d2, f2 ) # # We swap dates, if necessary, so that date 1 is never greater than date 2. # if ( cmp == '=' ): yn = 0 mn = 0 dn = 0 fn = 0.0 return yn, mn, dn, fn, ierror elif ( cmp == '>' ): y1, m1, d1, f1, y2, m2, d2, f2 = ymdf_swap ( y1, m1, d1, f1, y2, m2, d2, f2 ) # # Year difference. # yn = y2 - y1 # # Month difference. # y3 = y2 if ( m2 < m1 ): yn = yn - 1 mn = m2 - m1 + 12 y3 = y2 - 1 else: mn = m2 - m1 m3 = m2 # # Day difference. # if ( d2 < d1 ): mn = mn - 1 m3 = m2 - 1 if ( m3 == 0 ): m3 = 12 y3 = y3 - 1 dn = d2 - d1 + month_length_common ( y3, m3 ) else: dn = d2 - d1 # # Fractional difference. # THERE'S MORE TO THIS CODE, AFTER ALL, WHAT IF DN < 0? # if ( f2 < f1 ): dn = dn - 1 fn = f2 - f1 return yn, mn, dn, fn, ierror def ymdf_inc_common ( y1, m1, d1, f1, days ): #*****************************************************************************80 # ## ymdf_inc_common() increments a Common YMDF date by DAYS days. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # real DAYS, the number of days to advance the date. # # Output: # # integer Y2, M2, D2, real F2, the incremented YMDF date. # # # Copy the parameters. # y2 = y1 m2 = m1 d2 = d1 f2 = f1 + days # # Check the parameters. # y2, m2, d2, f2, ierror = ymdf_check_common ( y2, m2, d2, f2 ) return y2, m2, d2, f2 def ymdf_inc_english ( y1, m1, d1, f1, days ): #*****************************************************************************80 # ## ymdf_inc_english() increments an English YMDF date by DAYS days. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # real DAYS, the number of days to advance the date. # # Output: # # integer Y2, M2, D2, real F2, the incremented YMDF date. # # # Copy the parameters. # y2 = y1 m2 = m1 d2 = d1 f2 = f1 + days # # Check the parameters. # y2, m2, d2, f2, ierror = ymdf_check_english ( y2, m2, d2, f2 ) return y2, m2, d2, f2 def ymdf_inc_gregorian ( y1, m1, d1, f1, days ): #*****************************************************************************80 # ## ymdf_inc_gregorian() increments a Gregorian YMDF date by DAYS days. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # real DAYS, the number of days to advance the date. # # Output: # # integer Y2, M2, D2, real F2, the incremented YMDF date. # # # Copy the parameters. # y2 = y1 m2 = m1 d2 = d1 f2 = f1 + days # # Check the parameters. # y2, m2, d2, f2, ierror = ymdf_check_gregorian ( y2, m2, d2, f2 ) return y2, m2, d2, f2 def ymdf_inc_hebrew ( y1, m1, d1, f1, days ): #*****************************************************************************80 # ## ymdf_inc_hebrew() increments a Hebrew YMDF date by DAYS days. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # real DAYS, the number of days to advance the date. # # Output: # # integer Y2, M2, D2, real F2, the incremented YMDF date. # # # Copy the parameters. # y2 = y1 m2 = m1 d2 = d1 f2 = f1 + days # # Check the parameters. # y2, m2, d2, f2, ierror = ymdf_check_hebrew ( y2, m2, d2, f2 ) return y2, m2, d2, f2 def ymdf_inc_islamic ( y1, m1, d1, f1, days ): #*****************************************************************************80 # ## ymdf_inc_islamic() increments an Islamic YMDF date by DAYS days. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # real DAYS, the number of days to advance the date. # # Output: # # integer Y2, M2, D2, real F2, the incremented YMDF date. # # # Copy the parameters. # y2 = y1 m2 = m1 d2 = d1 f2 = f1 + days # # Check the parameters. # y2, m2, d2, f2, ierror = ymdf_check_islamic ( y2, m2, d2, f2 ) return y2, m2, d2, f2 def ymdf_inc_julian ( y1, m1, d1, f1, days ): #*****************************************************************************80 # ## ymdf_inc_julian() increments a Julian YMDF date by DAYS days. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # real DAYS, the number of days to advance the date. # # Output: # # integer Y2, M2, D2, real F2, the incremented YMDF date. # # # Copy the parameters. # y2 = y1 m2 = m1 d2 = d1 f2 = f1 + days # # Check the parameters. # y2, m2, d2, f2, ierror = ymdf_check_julian ( y2, m2, d2, f2 ) return y2, m2, d2, f2 def ymdf_inc_republican ( y1, m1, d1, f1, days ): #*****************************************************************************80 # ## ymdf_inc_republican() increments a Republican YMDF date by DAYS days. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # real DAYS, the number of days to advance the date. # # Output: # # integer Y2, M2, D2, real F2, the incremented YMDF date. # # # Copy the parameters. # y2 = y1 m2 = m1 d2 = d1 f2 = f1 + days # # Check the parameters. # y2, m2, d2, f2, ierror = ymdf_check_republican ( y2, m2, d2, f2 ) return y2, m2, d2, f2 def ymdf_inc_roman ( y1, m1, d1, f1, days ): #*****************************************************************************80 # ## ymdf_inc_roman() increments a Roman YMDF date by a DAYS days. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # real DAYS, the number of days to advance the date. # # Output: # # integer Y2, M2, D2, real F2, the incremented YMDF date. # # # Copy the parameters. # y2 = y1 m2 = m1 d2 = d1 f2 = f1 + days # # Check the parameters. # y2, m2, d2, f2, ierror = ymdf_check_roman ( y2, m2, d2, f2 ) return y2, m2, d2, f2 def ymdf_next_common ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_next_common() returns the Common YMDF date of the next day. # # Discussion: # # The routine knows that in the Common calendar, the day after # 4 October 1582 was 15 October 1582. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, tomorrow's YMDF date. # y2 = y1 m2 = m1 d2 = d1 + 1 f2 = f1 y2, m2, d2 = day_carry_common ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_next_english ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_next_english() returns the English YMD date of the next day. # # Discussion: # # The routine knows that in the English calendar, # the day after 2 September 1752 was 14 September 1752. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, tomorrow's YMDF date. # y2 = y1 m2 = m1 d2 = d1 + 1 f2 = f1 y2, m2, d2 = day_carry_english ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_next_gregorian ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_next_gregorian() returns the Gregorian YMDF date of the next day. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, tomorrow's YMDF date. # y2 = y1 m2 = m1 d2 = d1 + 1 f2 = f1 y2, m2, d2 = day_carry_gregorian ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_next_hebrew ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_next_hebrew() returns the Hebrew YMDF date of the next day. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, tomorrow's YMDF date. # y2 = y1 m2 = m1 d2 = d1 + 1 f2 = f1 y2, m2, d2 = day_carry_hebrew ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_next_islamic ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_next_islamic() returns the Islamic YMDF date of the next day. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, tomorrow's YMDF date. # y2 = y1 m2 = m1 d2 = d1 + 1 f2 = f1 y2, m2, d2 = day_carry_islamic ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_next_julian ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_next_julian() returns the Julian YMDF date of the next day. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, tomorrow's YMDF date. # y2 = y1 m2 = m1 d2 = d1 + 1 f2 = f1 y2, m2, d2 = day_carry_julian ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_next_republican ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_next_republican() returns the Republican YMD date of the next day. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, tomorrow's YMDF date. # y2 = y1 m2 = m1 d2 = d1 + 1 f2 = f1 y2, m2, d2 = day_carry_republican ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_next_roman ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_next_roman() returns the Roman YMDF date of the next day. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, tomorrow's YMDF date. # y2 = y1 m2 = m1 d2 = d1 + 1 f2 = f1 y2, m2, d2 = day_carry_roman ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_prev_common ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_prev_common() returns the Common YMDF date of the previous day. # # Discussion: # # The routine knows that in the Common calendar, the day before # 15 October 1582 was 4 October 1582. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, yesterday's YMDF date. # y2 = y1 m2 = m1 d2 = d1 - 1 f2 = f1 y2, m2, d2 = day_borrow_common ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_prev_english ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_prev_english() returns the English YMDF date of the previous day. # # Discussion: # # The routine knows that in the English calendar, # the day before 14 September 1752 was 2 September 1752. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, yesterday's YMDF date. # # y2 = y1 m2 = m1 d2 = d1 - 1 f2 = f1 y2, m2, d2 = day_borrow_english ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_prev_gregorian ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_prev_gregorian() returns the Gregorian YMDF date of the previous day. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, yesterday's YMDF date. # y2 = y1 m2 = m1 d2 = d1 - 1 f2 = f1 y2, m2, d2 = day_borrow_gregorian ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_prev_hebrew ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_prev_hebrew() returns the Hebrew YMDF date of the previous day. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, yesterday's YMDF date. # y2 = y1 m2 = m1 d2 = d1 - 1 f2 = f1 y2, m2, d2 = day_borrow_hebrew ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_prev_islamic ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_prev_islamic() returns the Islamic YMDF date of the previous day. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, yesterday's YMDF date. # y2 = y1 m2 = m1 d2 = d1 - 1 f2 = f1 y2, m2, d2 = day_borrow_islamic ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_prev_julian ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_prev_julian() returns the Julian YMDF date of the previous day. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, yesterday's YMDF date. # y2 = y1 m2 = m1 d2 = d1 - 1 f2 = f1 y2, m2, d2 = day_borrow_julian ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_prev_republican ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_prev_republican() returns the Republican YMDF date of the previous day. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, yesterday's YMDF date. # y2 = y1 m2 = m1 d2 = d1 - 1 f2 = f1 y2, m2, d2 = day_borrow_republican ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_prev_roman ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_prev_roman() returns the Roman YMDF date of the previous day. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, M2, D2, real F2, yesterday's YMDF date. # y2 = y1 m2 = m1 d2 = d1 - 1 f2 = f1 y2, m2, d2 = day_borrow_roman ( y2, m2, d2 ) return y2, m2, d2, f2 def ymdf_swap ( y1, m1, d1, f1, y2, m2, d2, f2 ): #*****************************************************************************80 # ## ymdf_swap() swaps two YMDF dates. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the first YMDF date. # # integer Y2, M2, D2, real F2, the second YMDF date. # # Output: # # integer Y1, M1, D1, real F1, the second YMDF date. # # integer Y2, M2, D2, real F2, the first YMDF date. # tt = y1 y1 = y2 y2 = tt tt = m1 m1 = m2 m2 = tt tt = d1 d1 = d2 d2 = tt tt = f1 f1 = f2 f2 = tt return y1, m1, d1, f1, y2, m2, d2, f2 def ymdf_to_jed_alexandrian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_alexandrian() converts an Alexandrian YMDF date to a JED. # # Discussion: # # This code needs to be adjusted to fit the Alexandrian model. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # # # Convert the calendar date to a computational date. # y_prime = y + 4690 - ( ( 13 - m ) // 13 ) m_prime = ( m + 12 ) % ( 13 ) d_prime = d - 1 # # Convert the computational date to a JED. # jed = ( ( 1461 * y_prime ) // 4 ) + 30 * m_prime + d_prime - 124 - 0.5 jed = jed + f return jed def ymdf_to_jed_armenian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_armenian() converts an Armenian YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Convert the calendar date to a computational date. # y_prime = y + 5268 - floor ( ( 13 - m ) / 13 ) m_prime = ( ( m + 12 ) % 13 ) d_prime = d - 1 # # Convert the computational date to a JED. # jed = 365 * y_prime + 30 * m_prime + d_prime - 317 - 0.5 jed = jed + f return jed def ymdf_to_jed_bahai ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_bahai() converts a Bahai YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Convert the calendar date to a computational date. # y_prime = y + 6560 - floor ( ( 39 - m ) / 20 ) m_prime = ( m % 20 ) d_prime = d - 1 # # Convert the computational date to a JED. # j1 = floor ( ( 1461 * y_prime ) / 4 ) j2 = 19 * m_prime g = floor ( ( y_prime + 184 ) / 100 ) g = floor ( ( 3 * g ) / 4 ) - 50 jed = j1 + j2 + d_prime - 1412 - g - 0.5 jed = jed + f return jed def ymdf_to_jed_common ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_common() converts a Common YMDF date to a JED. # # Discussion: # # The "common" calendar is meant to be the calendar which is Julian up to # day JED = 2299160, and Gregorian from day JED = 2299161 and after. # # The Julian Ephemeris Date is essentially a count of the number # of days that have elapsed since noon, 1 January 4713 BC, at # Greenwich, England. Strictly speaking, the Julian Ephemeris Date # is counted from noon, and thus day "0" began at noon on 1 January 4713 BC, # and ended at noon on 2 January 4713 BC. # # The Julian Ephemeris Date was devised by Joseph Scaliger in 1583. # # The Julian Ephemeris Date has been adopted by astronomers as # a convenient reference for dates. # # Example: # # Y M D JED # -------------- ------- # BC 4713 Jan 1 0 # AD 1968 May 23 2440000 # AD 1984 Dec 31 2446065 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 28 April 2010 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the Julian Ephemeris Date. # # # Copy the month and year. # y2 = 1582 m2 = 10 d2 = 4+1 f2 = 0.0 cmp = ymdf_compare ( y, m, d, f, y2, m2, d2, f2 ) if ( cmp == '<' ): jed = ymdf_to_jed_julian ( y, m, d, f ) return jed # # Use the Gregorian calendar for dates strictly after 1752/9/13. # y2 = 1582 m2 = 10 d2 = 15-1 f2 = 0.0 cmp = ymdf_compare ( y, m, d, f, y2, m2, d2, f2 ) if ( cmp == '>' ): jed = ymdf_to_jed_gregorian ( y, m, d, f ) return jed print ( '' ) print ( 'ymdf_to_jed_common(): Fatal error!' ) print ( ' Illegal date!' ) raise Exception ( 'ymdf_to_jed_common(): Fatal error!' ) return jed def ymdf_to_jed_coptic ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_coptic() converts a Coptic YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Convert the calendar date to a computational date. # y_prime = y + 4996 - floor ( ( 13 - m ) / 13 ) m_prime = ( ( m + 12 ) % 13 ) d_prime = d - 1 # # Convert the computational date to a JED. # jed = floor ( ( 1461 * y_prime ) / 4 ) + 30 * m_prime + d_prime - 124 - 0.5 jed = jed + f return jed def ymdf_to_jed_eg_civil ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_eg_civil() converts an Egyptian Civil YMDF date to a JED. # # Discussion: # # The Egyptian Civil calendar used a year of 365 days. The year comprised # 12 months of 30 days, with 5 epagomenal days occurring at the end of # the year. Since the observed year is about 365.25 days long, and no # attempt was made to adjust the Egyptian Civil year to the observed year, # the calendar dates gradually drifted with respect to the observed dates. # # The epoch or first day of the Egyptian Civil calendar is taken as # JED = 1448638.5. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Convert the calendar date to a computational date. # y_prime = y + 3968 - floor ( ( 13 - m ) / 13 ) m_prime = ( ( m + 12 ) % 13 ) d_prime = d - 1 # # Convert the computational date to a JED. # jed = 365 * y_prime + 30 * m_prime + d_prime - 47 + 1 - 0.5 jed = jed + f return jed def ymdf_to_jed_eg_lunar ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_eg_lunar() converts an Egyptian Lunar YMDF date to a JED. # # Discussion: # # Count # the days up to the day before the start of the calendar, # the days in the current month, # the 29 days guaranteed in the previous months of this year, # the (months/2) 30th days in the previous months of this year, # the 354 days guaranteed in each of the previous years, # the extra leap days in the preceding years, # the extra 30 days in the leap months in the preceding years. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor jed_epoch = epoch_to_jed_eg_lunar ( ) i1 = floor ( ( m - 1 ) / 2 ) i2 = floor ( ( y - 1 ) / 5 ) i3 = floor ( ( y - 1 ) / 25 ) i4 = floor ( i3 * 9 + ( ( ( y - 1 ) % 25 ) + 2 ) / 3 ) jed = jed_epoch - 1 + d \ + 29 * ( m - 1 ) + i1 \ + 354 * ( y - 1 ) + i2 \ + 30 * i4 + f return jed def ymdf_to_jed_english ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_english() converts an English YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # # # Check the date. # y, m, d, ierror = ymd_check_english ( y, m, d ) if ( ierror ): jed = -1.0 return jed # # Use the Julian Calendar for dates strictly before 1752/9/3. # y1 = 1752 m1 = 9 d1 = 3 f1 = 0.0 cmp = ymdf_compare ( y, m, d, f, y1, m1, d1, f1 ) if ( cmp == '<' ): jed = ymdf_to_jed_julian ( y, m, d, f ) return jed # # Use the Gregorian calendar for dates strictly after 1752/9/13. # y2 = 1752 m2 = 9 d2 = 13 f2 = 0.0 cmp = ymdf_compare ( y, m, d, f, y2, m2, d2, f2 ) if ( cmp == '>' ): jed = ymdf_to_jed_gregorian ( y, m, d, f ) return jed # # Error return jed if the date falls between the transition dates. # jed = -1.0 return jed def ymdf_to_jed_ethiopian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_ethiopian() converts an Ethiopian YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Convert the calendar date to a computational date. # y_prime = y + 4720 - floor ( ( 13 - m ) / 13 ) m_prime = ( ( m + 12 ) % 13 ) d_prime = d - 1 # # Convert the computational date to a JED. # j1 = floor ( ( 1461 * y_prime ) / 4 ) j2 = 30 * m_prime jed = j1 + j2 + d_prime - 124 - 0.5 jed = jed + f return jed def ymdf_to_jed_gregorian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_gregorian() converts a Gregorian YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 28 April 2010 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding JED. # import numpy as np # # Account for the missing year 0 by moving negative years up one. # y2 = y_common_to_astronomical ( y ) # # Convert the calendar date to a computational date. # y_prime = y2 + 4716 - int ( np.floor ( ( 14 - m ) / 12.0 ) ) m_prime = ( ( m + 9 ) % 12 ) d_prime = d - 1 # # Convert the computational date to a JED. # j1 = np.floor ( ( 1461 * y_prime ) / 4.0 ) j2 = np.floor ( ( 153 * m_prime + 2 ) / 5.0 ) g = ( np.floor ( 3 * ( np.floor ( ( y_prime + 184 ) / 100.0 ) ) / 4.0 ) ) - 38 jed = j1 + j2 + d_prime - 1401 - g - 0.5 jed = jed + f return jed def ymdf_to_jed_hebrew ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_hebrew() converts a Hebrew YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm J, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 334. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # # # Check the date. # y, m, d, ierror = ymd_check_hebrew ( y, m, d ) if ( ierror ): print ( '' ) print ( 'ymdf_to_jed_hebrew(): Fatal error!' ) print ( ' Illegal date.' ) print ( ' Y/M/D = ', y, '/', m, '/', d ) jed = -1.0 return jed # # Determine the JED of the beginning of the year. # jed = new_year_to_jed_hebrew ( y ) # # Work through the preceding months. # for m2 in range ( 1, m ): jed = jed + month_length_hebrew ( y, m2 ) # # Add on the days. # jed = jed + d - 1 jed = jed + f return jed def ymdf_to_jed_hindu_solar ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_hindu_solar() converts a Hindu solar YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Reingold, Nachum Dershowitz, Stewart Clamen, # Calendrical Calculations, II: Three Historical Calendars, # Software - Practice and Experience, # Volume 23, Number 4, pages 383-404, April 1993. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # jed_epoch = epoch_to_jed_hindu_solar ( ) mz = 0 yz = 0 jed = jed_epoch + \ ( d - 1 ) \ + ( m - 1 ) * month_length_hindu_solar ( yz, mz ) \ + y * year_length_days_hindu_solar ( yz ) \ + f return jed def ymdf_to_jed_islamic_a2 ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_islamic_a2() converts an Islamic A YMDF date to a JED. # # Discussion: # # The algorithm has the beauty of being comprehensible# # # Count the days up to the day before the start of the calendar, # plus the days in the current month, the 29 days guaranteed # in the previous months of this year, the (months/2) 30th days, # the 354 days in each of the previous years, plus the total number # of leap days in the preceding years. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Reingold, Nachum Dershowitz, # Calendrical Calculations I, # Software - Practice and Experience, # Volume 20, Number 9, September 1990, pages 899-928. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Check the date. # y, m, d, ierror = ymd_check_islamic ( y, m, d ) if ( ierror ): jed = -1.0 return jed jed_epoch = epoch_to_jed_islamic_a ( ) jed = jed_epoch - 1 + d + 29 * ( m - 1 ) + floor ( m / 2 ) \ + 354 * ( y - 1 ) + floor ( ( 11 * y + 3 ) / 30 ) + f return jed def ymdf_to_jed_islamic_a ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_islamic_a() converts an Islamic A YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Check the date. # y, m, d, ierror = ymd_check_islamic ( y, m, d ) if ( ierror ): jed = -1.0 return jed # # Convert the calendar date to a computational date. # y_prime = y + 5519 - floor ( ( 12 - m ) / 12 ) m_prime = ( ( m + 11 ) % 12 ) d_prime = d - 1 # # Convert the computational date to a JED. # j1 = floor ( ( 10631 * y_prime + 14 ) / 30 ) j2 = floor ( ( 2951 * m_prime + 51 ) / 100 ) jed = j1 + j2 + d_prime - 7665 - 0.5 + f return jed def ymdf_to_jed_islamic_b ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_islamic_b() converts an Islamic B YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Check the date. # y, m, d, ierror = ymd_check_islamic ( y, m, d ) if ( ierror ): jed = -1.0 return jed # # Convert the calendar date to a computational date. # y_prime = y + 5519 - floor ( ( 12 - m ) / 12 ) m_prime = ( ( m + 11 ) % 12 ) d_prime = d - 1 # # Convert the computational date to a JED. # j1 = floor ( ( 10631 * y_prime + 14 ) / 30 ) j2 = floor ( ( 2951 * m_prime + 51 ) / 100 ) jed = j1 + j2 + d_prime - 7664 - 0.5 + f return jed def ymdf_to_jed_jelali ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_jelali() converts a Jelali YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor jed_epoch = epoch_to_jed_jelali ( ) jed = jed_epoch + ( d - 1 ) + 30 * ( m - 1 ) + 365 * ( y - 1 ) \ + floor ( ( y - 1 ) / 4 ) + f return jed def ymdf_to_jed_julian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_julian() converts a Julian YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 03 July 2017 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the Julian Ephemeris Date. # import numpy as np # # Account for the missing year 0 by moving negative years up one. # y2 = y_common_to_astronomical ( y ) # # Convert the calendar date to a computational date. # y_prime = y2 + 4716 - int ( np.floor ( ( 14 - m ) / 12.0 ) ) m_prime = ( ( m + 9 ) % 12 ) d_prime = d - 1 # # Convert the computational date to a JED. # j1 = np.floor ( ( 1461 * y_prime ) / 4.0 ) j2 = np.floor ( ( 153 * m_prime + 2 ) / 5.0 ) jed = j1 + j2 + d_prime - 1401.0 - 0.5 jed = jed + f return jed def ymdf_to_jed_julian2 ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_julian2() converts a Julian YMDF date to a JED. # # Example: # # Y M D JED # -------------- ------- # BC 4713 1 1 0 # AD 1 1 1 1721424 # AD 1844 5 11 2394710 # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor y2 = y m2 = m d2 = d y2, m2, d2, ierror = ymd_check_julian ( y2, m2, d2 ) if ( ierror ): jed = -1.0 return jed # # Account for the missing year 0 by moving negative years up one. # y3 = y_common_to_astronomical ( y2 ) # # The JED is the number of days in years past, plus the number of days in # the previous months this year, plus the number of days. # t = floor ( ( 1461 * ( y3 + 4715 ) ) / 4 ) jed = t - 1095 + days_before_month_julian ( y2, m2 ) + d2 - 1 - 0.5 + f return jed def ymdf_to_jed_khwarizmian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_khwarizmian() converts a Khwarizmian YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Convert the calendar date to a computational date. # y_prime = y + 5348 - floor ( ( 13 - m ) / 13 ) m_prime = ( ( m + 12 ) % 13 ) d_prime = d - 1 # # Convert the computational date to a JED. # jed = 365 * y_prime + 30 * m_prime + d_prime - 317 - 0.5 + f return jed def ymdf_to_jed_macedonian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_macedonian() converts a Macedonian YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Convert the calendar date to a computational date. # y_prime = y + 4405 - floor ( ( 18 - m ) / 12 ) m_prime = ( ( m + 5 ) % 12 ) d_prime = d - 1 # # Convert the computational date to a JED. # j1 = floor ( ( 1461 * y_prime ) / 4 ) j2 = floor ( ( 153 * m_prime + 2 ) / 5 ) jed = j1 + j2 + d_prime - 1401 - 0.5 + f return jed def ymdf_to_jed_persian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_persian() converts a Persian YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Convert the calendar date to a computational date. # y_prime = y + 5348 - floor ( ( 22 - m ) / 13 ) m_prime = ( ( m + 3 ) % 13 ) d_prime = d - 1 # # Convert the computational date to a JED. # jed = 365 * y_prime + 30 * m_prime + d_prime - 77 - 0.5 + f return jed def ymdf_to_jed_republican ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_republican() converts a Republican YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Check the date. # [ y, m, d, ierror ] = ymd_check_republican ( y, m, d ) if ( ierror ): jed = -1.0 return jed # # Convert the calendar date to a computational date. # y_prime = y + 6504 - floor ( ( 13 - m ) / 13 ) m_prime = ( ( m + 12 ) % 13 ) d_prime = d - 1 # # Convert the computational date to a JED. # j1 = floor ( ( 1461 * y_prime ) / 4 ) j2 = 30 * m_prime g = floor ( ( y_prime + 396 ) / 100 ) g = floor ( 3 * g / 4 ) - 51 jed = j1 + j2 + d_prime - 111 - g - 0.5 jed = jed + f return jed def ymdf_to_jed_roman ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_roman() converts a Roman YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # # # Check the date. # y, m, d, ierror = ymd_check_roman ( y, m, d ) if ( ierror ): jed = -1.0 return jed y2 = y_roman_to_julian ( y ) jed = ymdf_to_jed_julian ( y2, m, d, f ) return jed def ymdf_to_jed_saka ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_saka() converts a Saka YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Convert the calendar date to a computational date. # y_prime = y + 4794 - floor ( ( 13 - m ) / 12 ) m_prime = ( ( m + 10 ) % 12 ) d_prime = d - 1 # # Convert the computational date to a JED. # j1 = floor ( ( 1461 * y_prime ) / 4 ) z = floor ( m_prime / 6 ) j2 = ( 31 - z ) * m_prime + 5 * z g = floor ( ( y_prime + 184 ) / 100 ) g = floor ( ( 3 * g ) / 4 ) - 36 jed = j1 + j2 + d_prime - 1348 - g - 0.5 + f return jed def ymdf_to_jed_soor_san ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_soor_san() converts a Soor San YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor jed_epoch = epoch_to_jed_soor_san ( ) jed = jed_epoch + ( d - 1 ) + 30 * ( m - 1 ) + 365 * ( y - 1 ) \ + floor ( ( y - 1 ) / 4 ) + f return jed def ymdf_to_jed_syrian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_syrian() converts a Syrian YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm E, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 323-324. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # from math import floor # # Convert the calendar date to a computational date. # y_prime = y + 4405 - floor ( ( 17 - m ) / 12 ) m_prime = ( ( m + 6 ) % 12 ) d_prime = d - 1 # # Convert the computational date to a JED. # j1 = floor ( ( 1461 * y_prime ) / 4 ) j2 = floor ( ( 153 * m_prime + 2 ) / 5 ) jed = j1 + j2 + d_prime - 1401 - 0.5 + f return jed def ymdf_to_jed_zoroastrian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_jed_zoroastrian() converts a Zoroastrian YMDF date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 05 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # real JED, the corresponding Julian Ephemeris Date. # jed_epoch = epoch_to_jed_zoroastrian ( ) jed = jed_epoch + ( d - 1 ) + 30 * ( m - 1 ) + 365 * ( y - 1 ) + f return jed def ymdf_to_s_common ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_s_common() writes a Common YMDF date into a string. # # Format: # # CE YYYY/MM/DD.FF # BCE YYYY/MM/DD.FF # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 25 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, double F, the YMDF date. # # Output: # # string S, a representation of the date. # if ( 0 <= y ): s = 'CE %d/%d/%d%.2f' % ( y, m, d, f ) else: s = 'BCE %d/%d/%d%.2f' % ( -y, m, d, f ) return s def ymdf_to_s_english ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_s_english() writes an English YMDF date into a string. # # Format: # # BC OS YYYY/MM/DD.FF # AD OS YYYY/MM/DD.FF # AD NS YYYY/MM/DD.FF # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 07 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # string S, a representation of the date. # if ( y < 0 ): s = ( 'BC OS %d/%02d/%05.2f' % ( -y, m, d + f ) ) elif ( y < 1752 or ( y == 1752 and m < 9 ) or ( y == 1752 and m == 9 and d < 3 ) ): s = ( 'AD OS %d/%02d/%05.2f' % ( y, m, d + f ) ) else: s = ( 'AD NS %d/%02d/%05.2f' % ( y, m, d + f ) ) return s def ymdf_to_s_gregorian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_s_gregorian() writes a Gregorian YMDF date into a string. # # Format: # # AD YYYY/MM/DD.FF # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # string S, a representation of the date. # if ( y < 0 ): s = ( 'BC %d/%02d/%05.2f' % ( y, m, d + f ) ) else: s = ( 'AD %d/%02d/%05.2f' % ( y, m, d + f ) ) return s def ymdf_to_s_hebrew ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_s_hebrew() "prints" a Hebrew YMDF date into a string. # # Format: # # DayNumber.Fraction MonthName YearNumber AM # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 08 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # string S, a representation of the date. # sm = month_to_month_name_hebrew ( y, m ) s = ( '%05.2f %s %d AM' % ( d + f, sm, y ) ) return s def ymdf_to_s_islamic ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_s_islamic() writes an Islamic YMDF date into a string. # # Format: # # AH YYYY/MM/DD.FF # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 09 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # string S, a representation of the date. # s = ( 'AH %d/%02d/%05.2f' % ( y, m, d + f ) ) return s def ymdf_to_s_julian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_s_julian() writes a Julian YMDF date into a string. # # Format: # # AD YYYY/MM/DD.FF # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 09 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # string S, a representation of the date. # if ( y < 0 ): s = ( 'BC %d/%02d/%05.2f' % ( -y, m, d + f ) ) else: s = ( 'AD %d/%02d/%05.2f' % ( y, m, d + f ) ) return s def ymdf_to_s_numeric ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_s_numeric() writes a YMDF date into a string. # # Format: # # YYYY/MM/DD.FF # or # -YYYY/MM/DD.FF # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 09 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # string S, a representation of the date. # s = ( '%d/%02d/%05.2f' % ( y, m, d + f ) ) return s def ymdf_to_s_republican ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_s_republican() writes a Republican YMDF date into a string. # # Format: # # ER YYYY/MM/DD.FF # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 09 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # string S, a representation of the date. # s = ( 'ER %d/%02d/%05.2f' % ( y, m, d + f ) ) return s def ymdf_to_week_common ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_week_common() returns the week number for a Common YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, is the date. # # Output: # # integer IWEEK, is the week number of the date, with # 1 for the first week, and 53 or 54 for the last. A week begins # on Sunday. The first and last weeks may be partial weeks. # from math import floor # # Make a local copy of the input date. # d2 = d m2 = m y2 = y f2 = f # # Check the input date. # y2, m2, d2, f2, ierror = ymdf_check_common ( y2, m2, d2, f2 ) if ( ierror ): iweek = 0 return iweek # # Find the number of days between Y/1/1 and Y/M1/D1. # d1 = 1 m1 = 1 y1 = y f1 = 0.0 days, ierror = ymdf_dif_common ( y1, m1, d1, f1, y2, m2, d2, f2 ) # # Find the day of the week of Y/1/1. # iday1 = ymdf_to_weekday_common ( y1, m1, d1, f1 ) # # Find the day of the week of Y/M2/D2. # iday2 = ymdf_to_weekday_common ( y2, m2, d2, f2 ) # # Expand the week containing Y/1/1 to begin on Sunday. # ndays = floor ( days ) + ( iday1 - 1 ) # # Expand the week containing Y/M2/D2 to end on Saturday. # ndays = ndays + ( 8 - iday2 ) # # Now NDAYS should be an exact multiple of 7, and IWEEK is easy. # iweek = floor ( ndays / 7 ) return iweek def ymdf_to_weekday_common ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_common() returns the weekday of a Common YMDF date. # # Discussion: # # The "common" calendar is meant to be the calendar which is Julian up to # day JED = 2299160, and Gregorian from day JED = 2299161 and after. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 24 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # jed = ymdf_to_jed_common ( y, m, d, f ) w, f2 = jed_to_weekday ( jed ) return w def ymdf_to_weekday_english ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_english() returns the weekday of an English YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 18 October 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # jed = ymdf_to_jed_english ( y, m, d, f ); w, f2 = jed_to_weekday ( jed ); return w def ymdf_to_weekday_english2 ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_english2() returns the weekday of an English YMDF date. # # Discussion: # # Lewis Carroll's method is used. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 18 October 2024 # # Author: # # John Burkardt # # Reference: # # Gary Meisters, # Lewis Carroll's Day-of-the-Week Algorithm, # Math Horizons, November 2002, pages 24-25. # # Lewis Carroll (Charles Dodgson), # To Find the Day of the Week for Any Given Date, # Nature, 31 March 1887. # # John Conway, # Tomorrow is the Day After Doomsday, # Eureka, 1973. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # from math import floor m_table = [ 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 12 ];\ # # Dates of 2 September 1752 and earlier fall under one scheme. # y1 = 1752 m1 = 9 d1 = 3 f1 = 0.0 cmp1 = ymdf_compare ( y, m, d, f, y1, m1, d1, f1 ) # # Dates of 14 September 1752 and later fall under another. # y1 = 1752 m1 = 9 d1 = 13 f1 = 0.0 cmp2 = ymdf_compare ( y, m, d, f, y1, m1, d1, f1 ) if ( cmp1 == '<' ): cval = 18 - floor ( y / 100 ) elif ( cmp2 == '>' ): cval = 2 * ( 3 - ( floor ( y / 100 ) % 4 ) ) else: print ( '' ) print ( 'ymdf_to_weekday_english2(): Fatal error!' ) print ( ' The given date is illegal.' ) raise Exception ( 'ymdf_to_english2(): Fatal error!' ) cc = floor ( y / 100 ) yy = y - cc * 100 a = floor ( yy / 12 ) b = yy - 12 * a yval = a + b + floor ( b / 4 ) mval = m_table[m-1] dval = d if ( ( m == 1 or m == 2 ) and year_is_leap_english ( y ) ): mval = mval + 6; w = i4_modp ( cval + yval + mval + dval, 7 ) + 1 return w def ymdf_to_weekday_gregorian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_gregorian() returns the weekday of a Gregorian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 19 October 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # jed = ymdf_to_jed_gregorian ( y, m, d, f ) w, f2 = jed_to_weekday ( jed ) return w def ymdf_to_weekday_gregorian2 ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_gregorian2() returns the weekday of a Gregorian YMDF date. # # Discussion: # # This routine computes the day of the week from the date in # the Gregorian calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 19 October 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm B, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 308. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # from math import floor # # Check the input. # y, m, d, ierror = ymd_check_gregorian ( y, m, d ) if ( ierror != 0 ): w = 0 return w m_prime = ( ( 9 + m ) % 12 ) q = floor ( m_prime / 10 ) z = floor ( ( 13 * m_prime + 2 ) / 5 ) t = 28 * m_prime + z + d - 365 * q + 59 c = i4_wrap ( t, 1, 7 ) y_prime = y - q v = ( floor ( y / 4 ) - floor ( y_prime / 4 ) ) \ - ( floor ( y / 100 ) - floor ( y_prime / 100 ) ) \ + ( floor ( y / 400 ) - floor ( y_prime / 400 ) ) p = y + floor ( y / 4 ) - floor ( y / 100 ) + floor ( y / 400 ) - 1 - v n = 7 - i4_modp ( p, 7 ) w = 1 + i4_modp ( 7 + c - n, 7 ) return w def ymdf_to_weekday_gregorian3 ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_gregorian3() returns the weekday of a Gregorian YMDF date. # # Discussion: # # The algorithm is also valid for BC years. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 19 October 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm D, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 309. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # from math import floor y, m, d, ierror = ymd_check_gregorian ( y, m, d ) if ( ierror != 0 ): w = 0 return w if ( y < 0 ): y2 = 1 - y else: y2 = y m_prime = ( ( 9 + m ) % 12 ) y_prime = y2 - floor ( m_prime / 10 ) while ( y_prime < 0 ): y_prime = y_prime + 400 w = 1 + i4_modp ( 2 + d + floor ( ( 13 * m_prime + 2 ) / 5 ) \ + y_prime + floor ( y_prime / 4 ) - floor ( y_prime / 100 ) \ + floor ( y_prime / 400 ), 7 ) return w def ymdf_to_weekday_gregorian4 ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_gregorian4() returns the weekday of a Gregorian YMDF date. # # Discussion: # # This routine uses "Zeller's congruence" # # W = 1 + ( [ 2.6*M-0.2 ] + K + Y + [ Y/4 ] + [ C/4 ] - 2 * C ) mod 7 # # where # # M = month, but counting so that March = 1, April = 2, ..., Feb = 12. # K = the day of the month # Y = the century year (that is, the last two digits of the year) # C = the century (the year divided by 100) # W = the day of the week, with Sunday = 1, # [X] = integer part of X. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 19 October 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # y, m, d, ierror = ymd_check_gregorian ( y, m, d ) if ( ierror != 0 ): w = 0 return w if ( m <= 2 ): a = m + 10 else: a = m - 2 # # What do you want to happen when Y is negative? # c = i4_modp ( y, 100 ) e = floor ( ( y - c ) / 100 ) v = floor ( ( 13 * a - 1 ) / 5 ) x = floor ( c / 4 ) u = floor ( e / 4 ) z = v + x + u + d + c - 2 * e w = i4_modp ( z, 7 ) + 1 return w def ymdf_to_weekday_gregorian5 ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_gregorian5() returns the weekday of a Gregorian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 19 October 2024 # # Author: # # John Burkardt # # Reference: # # Daniel Zwillinger, editor, # CRC Standard Mathematical Tables and Formulae, # CRC Press, 2000, page 738. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # from math import floor y, m, d, ierror = ymd_check_gregorian ( y, m, d ) if ( ierror != 0 ): w = 0 return w c = floor ( y / 100 ) yy = y - c * 100 if ( m < 3 ): mm = m + 10 yy = yy - 1 else: mm = m - 2 days = d + floor ( 2.6 * mm - 0.2 ) - 2 * c + yy + floor ( yy / 4 ) \ + floor ( c / 4 ) w = i4_modp ( days, 7 ) + 1 return w def ymdf_to_weekday_hebrew ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_hebrew() returns the weekday of a Hebrew YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 19 October 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # jed = ymdf_to_jed_hebrew ( y, m, d, f ) w, f2 = jed_to_weekday ( jed ) return w def ymdf_to_weekday_islamic_a ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_islamic_a() returns the weekday of an Islamic A YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 19 October 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # jed = ymdf_to_jed_islamic_a ( y, m, d, f ) w, f2 = jed_to_weekday ( jed ) return w def ymdf_to_weekday_julian ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_julian() computes the weekday of a Julian YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 19 October 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # jed = ymdf_to_jed_julian ( y, m, d, f ) w, f2 = jed_to_weekday ( jed ) return w def ymdf_to_weekday_julian2 ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_julian2() returns the weekday of a Julian YMDF date. # # Discussion: # # This routine computes the day of the week from the date in # the Julian calendar, that is, the calendar in force before the # Gregorian calendar, in which every fourth year was a leap year. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 19 October 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm A, # Mapping Time, The Calendar and Its History, # Oxford, 1999, pages 307-308. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # from math import floor m_prime = ( ( 9 + m ) % 12 ) q = floor ( m_prime / 10 ) z = floor ( ( 13 * m_prime + 2 ) / 5 ) t = 28 * m_prime + z + d - 365 * q + 59 c = i4_wrap ( t, 1, 7 ) y_prime = y - q v = floor ( y / 4 ) - floor ( y_prime / 4 ) p = y + floor ( y / 4 ) + 4 - v n = 7 - ( p % 7 ) w = i4_wrap ( c + 1 - n, 1, 7 ) return w def ymdf_to_weekday_julian3 ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_julian3() returns the week day of a Julian YMD date. # # Discussion: # # The algorithm is also valid for BC years. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 19 October 2024 # # Author: # # John Burkardt # # Reference: # # Edward Richards, # Algorithm C, # Mapping Time, The Calendar and Its History, # Oxford, 1999, page 309. # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # from math import floor if ( y < 0 ): y2 = 1 - y else: y2 = y m_prime = ( ( 9 + m ) % 12 ) y_prime = y2 - floor ( m_prime / 10 ) while ( y_prime < 0 ): y_prime = y_prime + 28 w = 1 + ( ( d + floor ( ( 13 * m_prime + 2 ) / 5 ) + y_prime \ + floor ( y_prime / 4 ) ) % 7 ) return w def ymdf_to_weekday_republican ( y, m, d, f ): #*****************************************************************************80 # ## ymdf_to_weekday_republican() returns the weekday of a Republican YMDF date. # # Discussion: # # The Republican calendar used a 10 day week. # There was a final "month" of 5 or 6 days. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 19 October 2024 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, real F, the YMDF date. # # Output: # # integer W, is the week day number of the date, with # 1 for Sunday, through 7 for Saturday. # w = i4_wrap ( d, 1, 10 ) return w def ymdf_to_yjf_common ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_to_yjf_common() converts from YMDF to YJF form in the Common calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, J2, real F2, YJF date. # # # Check the date. # y1, m2, d1, f1, ierror = ymdf_check_common ( y1, m1, d1, f1 ) if ( ierror ): y2 = 0 j2 = 0 f2 = 0.0 return y2, j2, f2 y2 = y1 j2 = d1 f2 = f1 # # Add in the days of the elapsed months. # for m in range ( 1, m1 ): j2 = j2 + month_length_common ( y2, m ) return y2, j2, f2 def ymdf_to_yjf_english ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_to_yjf_english() converts from YMDF to YJF form in the English calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, J2, real F2, YJF date. # # # Check the date. # y1, m1, d1, f1, ierror = ymdf_check_english ( y1, m1, d1, f1 ) if ( ierror ): y2 = 0 j2 = 0 f2 = 0.0 return y2, j2, f2 y2 = y1 j2 = d1 f2 = f1 # # Add in the days of the elapsed months. # for m in range ( 1, m1 ): j2 = j2 + month_length_english ( y2, m ) return y2, j2, f2 def ymdf_to_yjf_gregorian ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_to_yjf_gregorian(): YMDF to YJF form in the Gregorian calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, J2, real F2, YJF date. # # # Check the date. # y1, m1, d1, ierror = ymd_check_gregorian ( y1, m1, d1 ) if ( ierror ): y2 = 0 j2 = 0 f2 = 0.0 return y2, j2, f2 y2 = y1 j2 = d1 f2 = f1 # # Add in the days of the elapsed months. # for m in range ( 1, m1 ): j2 = j2 + month_length_gregorian ( y2, m ) return y2, j2, f2 def ymdf_to_yjf_hebrew ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_to_yjf_hebrew() converts from YMDF to YJF form in the Hebrew calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, J2, real F2, YJF date. # y2 = y1 j2 = d1 f2 = f1 for m in range ( 1, m1 ): j2 = j2 + month_length_hebrew ( y1, m ) return y2, j2, f2 def ymdf_to_yjf_islamic ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_to_yjf_islamic() converts from YMDF to YJF form in the Islamic calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, J2, real F2, YJF date. # # # Check the date. # y1, m1, d1, ierror = ymd_check_islamic ( y1, m1, d1 ) if ( ierror ): y2 = 0 j2 = 0 f2 = 0.0 return y2, j2, f2 y2 = y1 j2 = d1 f2 = f1 # # Add in the days of the elapsed months. # for m in range ( 1, m1 ): j2 = j2 + month_length_islamic ( y2, m ) return y2, j2, f2 def ymdf_to_yjf_julian ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_to_yjf_julian() converts from YMDF to YJF form in the Julian calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, J2, real F2, YJF date. # # # Check the date. # y1, m1, d1, ierror = ymd_check_julian ( y1, m1, d1 ) if ( ierror ): y2 = 0 j2 = 0 f2 = 0.0 return y2, j2, f2 y2 = y1 j2 = d1 f2 = f1 # # Add in the days of the elapsed months. # for m in range ( 1, m1 ): j2 = j2 + month_length_julian ( y2, m ) return y2, j2, f2 def ymdf_to_yjf_republican ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_to_yjf_republican(): YMDF to YJF form in the Republican calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, J2, real F2, YJF date. # # # Check the date. # y1, m1, d1, ierror = ymd_check_republican ( y1, m1, d1 ) if ( ierror ): y2 = 0 j2 = 0 f2 = 0.0 return y2, j2, f2 y2 = y1 j2 = d1 f2 = f1 # # Add in the days of the elapsed months. # for m in range ( 1, m1 ): j2 = j2 + month_length_republican ( y2, m ) return y2, j2, f2 def ymdf_to_yjf_roman ( y1, m1, d1, f1 ): #*****************************************************************************80 # ## ymdf_to_yjf_roman() converts from YMDF to YJF form in the Roman calendar. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, real F1, the YMDF date. # # Output: # # integer Y2, J2, real F2, YJF date. # # Check the date. # y1, m1, d1, f1, ierror = ymdf_check_roman ( y1, m1, d1, f1 ) if ( ierror ): y2 = 0 j2 = 0 f2 = 0.0 return y2, j2, f2 y2 = y1 j2 = d1 f2 = f1 # # Add in the days of the elapsed months. # for m in range ( 1, m1 ): j2 = j2 + month_length_roman ( y2, m ) return y2, j2, f2 def ymdhms_check_common ( y, m, d, h, n, s ): #*****************************************************************************80 # ## ymdhms_check_common() checks a Common YMDHMS date. # # Discussion: # # The routine will correct certain simple errors in dates, such as # "11:03:42 31 September 1996" # which will become # "11:03:42 1 October 1996". # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, H, N, S, the date information. # # Output: # # integer Y, M, D, H, N, S, the normalized data information. # # logical ierror: True if an error was found. # # # Check that the second is between 0 and 59. # N may get bumped up or down. # y, m, d, h, n, s = second_borrow_common ( y, m, d, h, n, s ) y, m, d, h, n, s = second_carry_common ( y, m, d, h, n, s ) # # Check that the minute is between 0 and 59. # H may get bumped up or down. # y, m, d, h, n = minute_borrow_common ( y, m, d, h, n ) y, m, d, h, n = minute_carry_common ( y, m, d, h, n ) # # Check that the hour is between 0 and 23. # D may get bumped up or down. # y, m, d, h = hour_borrow_common ( y, m, d, h ) y, m, d, h = hour_carry_common ( y, m, d, h ) # # Now make adjustments to D, M, and Y. # y, m, d, ierror = ymd_check_common ( y, m, d ) return y, m, d, h, n, s, ierror def ymdhms_compare ( y1, m1, d1, h1, n1, s1, y2, m2, d2, h2, n2, s2 ): #*****************************************************************************80 # ## ymdhms_compare() compares two YMDHMS dates. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 10 September 2024 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, H1, N1, S1, the first date. # # integer Y2, M2, D2, H2, N2, S2, the second date. # # Output: # # character CMP: # '<' if date 1 precedes date 2 # '=' if date 1 equals date 2 # '>' if date 1 follows date 2 # '?' if one of the dates was illegal. # cmp = '?' # # Make local copies of the and then check them. # We need local copies because the checking routine can # change the input values. # y1, m1, d1, h1, n1, s1, ierror = ymdhms_check_common ( y1, m1, d1, h1, n1, s1 ) if ( ierror ): print ( '' ) print ( 'ymdhms_compare(): Fatal error!' ) print ( ' Date #1 is illegal.' ) raise Exception ( 'ymdhms_compare(): Fatal error!' ) y2, m2, d2, h2, n2, s2, ierror = ymdhms_check_common ( y2, m2, d2, h2, n2, s2 ) if ( ierror ): print ( '' ) print ( 'ymdhms_compare(): Fatal error!' ) print ( ' Date #2 is illegal.' ) raise Exception ( 'ymdhms_compare(): Fatal error!' ) # # Compare years... # if ( y1 < y2 ): cmp = '<' elif ( y1 > y2 ): cmp = '>' else: # # ...if necessary, compare months in equal years... # if ( m1 < m2 ): cmp = '<' elif ( m1 > m2 ): cmp = '>' else: # # ...if necessary, compare days in equal months... # if ( d1 < d2 ): cmp = '<' elif ( d1 > d2 ): cmp = '>' else: # # ...if necessary, compare hours in equal days... # if ( h1 < h2 ): cmp = '<' elif ( h1 > h2 ): cmp = '>' else: # # ...if necessary, compare minutes in equal hours... # if ( n1 < n2 ): cmp = '<' elif ( n1 > n2 ): cmp = '>' else: # # ...if necessary, compare seconds in equal minutes... # if ( s1 < s2 ): cmp = '<' elif ( s1 > s2 ): cmp = '>' else: cmp = '=' return cmp def ymdhms_to_jed_common ( y, m, d, h, n, s ): #*****************************************************************************80 # ## ymdhms_to_jed_common() converts a Common YMDHMS date to a JED. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 14 December 2017 # # Author: # # John Burkardt # # Input: # # integer Y, M, D, H, N, S, the YMDHMS date. # # Output: # # real JED, the Julian Ephemeris Date. # y1, m1, d1, f1 = ymdhms_to_ymdf_common ( y, m, d, h, n, s ) jed = ymdf_to_jed_common ( y1, m1, d1, f1 ) return jed def ymdhms_to_ymdf_common ( y1, m1, d1, h1, n1, s1 ): #*****************************************************************************80 # ## ymdhms_to_ymdf_common() converts a YMDHMS date to a YMDF date. # # Licensing: # # This code is distributed under the MIT license. # # Modified: # # 18 April 2013 # # Author: # # John Burkardt # # Input: # # integer Y1, M1, D1, H1, N1, S1, # the year, month, day, hour, minute and second of the date. # # Output: # # integer Y2, M2, D2, real F2, # the YMDF date. # # # Check the date. # y, m, d, h, n, s, ierror = ymdhms_check_common ( y1, m1, d1, h1, n1, s1 ) if ( ierror ): print ( '' ) print ( 'ymdhms_to_ymdf_common(): Fatal error!' ) raise Exception ( 1 ) y2 = y1 m2 = m1 d2 = d1 # # Now compute the day fraction. # f2 = ( ( h1 * 60 + n1 ) * 60 + s1 ) / ( 24 * 60 * 60 ) return y2, m2, d2, f2 if ( __name__ == '__main__' ): timestamp ( ) calpak_test ( ) timestamp ( )