French Republican calendar: Difference between revisions
Created draft task and added one implementation |
m →{{header|BBC BASIC}}: Minor tidying-up |
||
Line 21:
=={{header|BBC BASIC}}==
Computes leap years using the "continuous" method: a year in the Republican calendar is a leap year if and only if the number of the <i>following</i> year is divisible by 4 but not by 100 unless also by 400. No attempt is made to deal with ill-formed or invalid input dates.
<lang bbcbasic>REM >frrepcal
:
Line 154:
DEF FN_rep_leap(year%)
REM see comment at the beginning of FN_rep_to_day
= (
:
DEF FN_gre_leap(year%)
|
Revision as of 23:39, 19 September 2016
Write a program to convert dates between the Gregorian calendar and the French Republican calendar.
The year 1 of the Republican calendar began on 22 September 1792. There were twelve months (Vendémiaire, Brumaire, Frimaire, Nivôse, Pluviôse, Ventôse, Germinal, Floréal, Prairial, Messidor, Thermidor, and Fructidor) of 30 days each, followed by five intercalary days or Sansculottides (Fête de la vertu / Virtue Day, Fête du génie / Talent Day, Fête du travail / Labour Day, Fête de l'opinion / Opinion Day, and Fête des récompenses / Honours Day). In leap years (the years 3, 7, and 11) a sixth Sansculottide was added: Fête de la Révolution / Revolution Day.
As a minimum, your program should give correct results for dates in the range from 1 Vendémiaire 1 = 22 September 1792 to 10 Nivôse 14 = 31 December 1805 (the last day when the Republican calendar was officially in use). If you choose to accept later dates, be aware that there are several different methods (described on the Wikipedia page) about how to determine leap years after the year 14. You should indicate which method you are using. (Because of these different methods, correct programs may sometimes give different results for dates after 1805.)
Test your program by converting the following dates both from Gregorian to Republican and from Republican to Gregorian:
• 1 Vendémiaire 1 = 22 September 1792
• 1 Prairial 3 = 20 May 1795
• 27 Messidor 7 = 15 July 1799 (Rosetta Stone discovered)
• Fête de la Révolution 11 = 23 September 1803
• 10 Nivôse 14 = 31 December 1805
BBC BASIC
Computes leap years using the "continuous" method: a year in the Republican calendar is a leap year if and only if the number of the following year is divisible by 4 but not by 100 unless also by 400. No attempt is made to deal with ill-formed or invalid input dates. <lang bbcbasic>REM >frrepcal
DIM gregorian$(11) DIM gregorian%(11) DIM republican$(11) DIM sansculottides$(5) gregorian$() = "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" gregorian%() = 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 REM 7-bit ASCII encoding, so no accents on French words republican$() = "Vendemiaire", "Brumaire", "Frimaire", "Nivose", "Pluviose", "Ventose", "Germinal", "Floreal", "Prairial", "Messidor", "Thermidor", "Fructidor" sansculottides$() = "Fete de la vertu", "Fete du genie", "Fete du travail", "Fete de l'opinion", "Fete des recompenses", "Fete de la Revolution"
PRINT "*** French Republican ***" PRINT "*** calendar converter ***" PRINT "Enter a date to convert, in the format 'day month year'" PRINT "e.g.: 1 Prairial 3," PRINT " 20 May 1795." PRINT "For Sansculottides, use 'day year'" PRINT "e.g.: Fete de l'opinion 9." PRINT "Or just press 'RETURN' to exit the program." PRINT REPEAT
INPUT LINE "> " src$ IF src$ <> "" THEN PROC_split(src$, day%, month%, year%) REM for simplicity, we assume that years up to 1791 are Republican REM and years from 1792 onwards are Gregorian IF year% < 1792 THEN REM convert Republican date to number of days elapsed REM since 21 September 1792, then convert that number REM to the Gregorian date PROC_day_to_gre(FN_rep_to_day(day%, month%, year%), day%, month%, year%) PRINT; day%; " "; gregorian$(month% - 1); " " year% ELSE REM convert Gregorian date to Republican, via REM number of days elapsed since 21 September 1792 PROC_day_to_rep(FN_gre_to_day(day%, month%, year%), day%, month%, year%) IF month% = 13 THEN PRINT sansculottides$(day% - 1); " "; year% ELSE PRINT; day%; " "; republican$(month% - 1); " "; year% ENDIF ENDIF ENDIF
UNTIL src$ = "" END
DEF PROC_split(s$, RETURN d%, RETURN m%, RETURN y%) LOCAL month_and_year$, month$, months$(), i% DIM months$(11) IF LEFT$(s$, 4) = "Fete" THEN
m% = 13 FOR i% = 0 TO 5 IF LEFT$(s$, LEN sansculottides$(i%)) = sansculottides$(i%) THEN d% = i% + 1 y% = VAL(RIGHT$(s$, LEN s$ - LEN sansculottides$(i%) - 1)) ENDIF NEXT
ELSE
d% = VAL(LEFT$(s$, INSTR(s$, " ") - 1)) month_and_year$ = MID$(s$, INSTR(s$, " ") + 1) month$ = LEFT$(month_and_year$, INSTR(month_and_year$, " ") - 1) y% = VAL(MID$(month_and_year$, INSTR(month_and_year$, " ") + 1)) IF y% < 1792 THEN months$() = republican$() ELSE months$() = gregorian$() FOR i% = 0 TO 11 IF months$(i%) = month$ THEN m% = i% + 1 NEXT
ENDIF ENDPROC
DEF FN_gre_to_day(d%, m%, y%) REM modified & repurposed from code given at REM https://www.staff.science.uu.nl/~gent0113/calendar/isocalendar_text5.htm IF m% < 3 THEN
y% -= 1 m% += 12
ENDIF = INT(365.25 * y%) - INT(y% / 100) + INT(y% / 400) + INT(30.6 * (m% + 1)) + d% - 654842
DEF FN_rep_to_day(d%, m%, y%) REM assume that a year is a leap year iff the _following_ year is REM divisible by 4, but not by 100 unless also by 400 REM REM other methods for computing Republican leap years exist IF m% = 13 THEN
m% -= 1 d% += 30
ENDIF IF FN_rep_leap(y%) THEN d% -= 1 = 365 * y% + INT((y% + 1) / 4) - INT((y% + 1) / 100) + INT((y% + 1) / 400) + 30 * m% + d% - 395
DEF PROC_day_to_gre(day%, RETURN d%, RETURN m%, RETURN y%) y% = INT(day% / 365.25) d% = day% - INT(365.25 * y%) + 21 y% += 1792 d% += INT(y% / 100) - INT(y% / 400) - 13 m% = 8 WHILE d% > gregorian%(m%)
d% -= gregorian%(m%) m% += 1 IF m% = 12 THEN m% = 0 y% += 1 IF FN_gre_leap(y%) THEN gregorian%(1) = 29 ELSE gregorian%(1) = 28 ENDIF
ENDWHILE m% += 1 ENDPROC
DEF PROC_day_to_rep(day%, RETURN d%, RETURN m%, RETURN y%) LOCAL sansculottides% y% = INT(day% / 365.25) IF FN_rep_leap(y%) THEN y% -= 1 d% = day% - INT(365.25 * y%) + INT((y% + 1) / 100) - INT((y% + 1) / 400) y% += 1 m% = 1 IF FN_rep_leap(y%) THEN sansculottides% = 6 ELSE sansculottides% = 5 WHILE d% > 30
d% -= 30 m% += 1 IF m% = 13 THEN IF d% > sansculottides% THEN d% -= sansculottides% m% = 1 y% += 1 ENDIF ENDIF
ENDWHILE ENDPROC
DEF FN_rep_leap(year%) REM see comment at the beginning of FN_rep_to_day = ((year% + 1) MOD 4 = 0 AND ((year% + 1) MOD 100 <> 0 OR (year% + 1) MOD 400 = 0))
DEF FN_gre_leap(year%) = (year% MOD 4 = 0 AND (year% MOD 100 <> 0 OR year% MOD 400 = 0))</lang> Output for the test dates:
*** French Republican *** *** calendar converter *** Enter a date to convert, in the format 'day month year' e.g.: 1 Prairial 3, 20 May 1795. For Sansculottides, use 'day year' e.g.: Fete de l'opinion 9. Or just press 'RETURN' to exit the program. > 1 Vendemiaire 1 22 September 1792 > 22 September 1792 1 Vendemiaire 1 > 1 Prairial 3 20 May 1795 > 20 May 1795 1 Prairial 3 > 27 Messidor 7 15 July 1799 > 15 July 1799 27 Messidor 7 > Fete de la Revolution 11 23 September 1803 > 23 September 1803 Fete de la Revolution 11 > 10 Nivose 14 31 December 1805 > 31 December 1805 10 Nivose 14
Output for a few subsequent dates:
> 18 March 1871 27 Ventose 79 > 25 August 1944 7 Fructidor 152 > 19 September 2016 Fete du travail 224