French Republican calendar: Difference between revisions
(Realize in F#) |
m (→{{header|Phix}}: added syntax colouring, made p2js compatible) |
||
Line 1,405: | Line 1,405: | ||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
<lang Phix>constant gregorians = {"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}, |
|||
republicans = {"Vendémiaire", "Brumaire", "Frimaire", "Nivôse", "Pluviôse", |
|||
"Ventôse", "Germinal", "Floréal", "Prairial", "Messidor", |
|||
"Thermidor", "Fructidor"}, |
|||
sansculottides = {"Fête de la vertu", "Fête du génie", "Fête du travail", |
|||
"Fête de l'opinion", "Fête des récompenses", |
|||
"Fête de la Révolution"} |
|||
function rep_leap(integer year) |
|||
return mod(year+1,4)==0 and (mod(year+1,100)!=0 or mod(year+1,400)==0) |
|||
end function |
|||
<!--<lang Phix>(phixonline)--> |
|||
function rep_to_day(sequence dmy) |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
integer {d, m, y} = dmy |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">gregorians</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"January"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"February"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"March"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"April"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"May"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"June"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"July"</span><span style="color: #0000FF;">,</span> |
|||
if m == 13 then |
|||
<span style="color: #008000;">"August"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"September"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"October"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"November"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"December"</span><span style="color: #0000FF;">},</span> |
|||
m -= 1 |
|||
<span style="color: #000000;">gregorian</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">31</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">28</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">31</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">30</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">31</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">30</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">31</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">31</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">30</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">31</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">30</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">31</span><span style="color: #0000FF;">},</span> |
|||
d += 30 |
|||
<span style="color: #000000;">republicans</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"Vendémiaire"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Brumaire"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Frimaire"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Nivôse"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Pluviôse"</span><span style="color: #0000FF;">,</span> |
|||
end if |
|||
<span style="color: #008000;">"Ventôse"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Germinal"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Floréal"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Prairial"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Messidor"</span><span style="color: #0000FF;">,</span> |
|||
if rep_leap(y) then |
|||
<span style="color: #008000;">"Thermidor"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Fructidor"</span><span style="color: #0000FF;">},</span> |
|||
d -= 1 |
|||
<span style="color: #000000;">sansculottides</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"Fête de la vertu"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Fête du génie"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Fête du travail"</span><span style="color: #0000FF;">,</span> |
|||
end if |
|||
<span style="color: #008000;">"Fête de l'opinion"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Fête des récompenses"</span><span style="color: #0000FF;">,</span> |
|||
integer res = 365*(y-1) + floor((y+1)/4) - floor((y+1)/100) + floor((y+1)/400) + 30*(m-1) + d |
|||
<span style="color: #008000;">"Fête de la Révolution"</span><span style="color: #0000FF;">}</span> |
|||
return res |
|||
end function |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">rep_leap</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">year</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">year</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)==</span><span style="color: #000000;">0</span> <span style="color: #008080;">and</span> <span style="color: #0000FF;">(</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">year</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">year</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">400</span><span style="color: #0000FF;">)==</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> |
|||
function gre_leap(integer year) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
return mod(year,4)==0 and (mod(year,100)!=0 or mod(year,400)==0) |
|||
end function |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">rep_to_day</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">dmy</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dmy</span> |
|||
function gre_to_day(sequence dmy) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">13</span> <span style="color: #008080;">then</span> |
|||
integer {d, m, y} = dmy |
|||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span> |
|||
if m < 3 then |
|||
<span style="color: #000000;">d</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">30</span> |
|||
y -= 1 |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
m += 12 |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">rep_leap</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
end if |
|||
<span style="color: #000000;">d</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span> |
|||
integer res = floor(y*365.25) - floor(y/100) + floor(y/400) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
+ floor(30.6*(m+1)) + d - 654842 |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">365</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">100</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">400</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">30</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">d</span> |
|||
return res |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span> |
|||
end function |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
function day_to_rep(integer day) |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">gre_leap</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">year</span><span style="color: #0000FF;">)</span> |
|||
integer y = floor((day-1)/365.25) |
|||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">year</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)==</span><span style="color: #000000;">0</span> <span style="color: #008080;">and</span> <span style="color: #0000FF;">(</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">year</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">year</span><span style="color: #0000FF;">,</span><span style="color: #000000;">400</span><span style="color: #0000FF;">)==</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> |
|||
if not rep_leap(y) then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
y += 1 |
|||
end if |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">gre_to_day</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">dmy</span><span style="color: #0000FF;">)</span> |
|||
integer d = day - floor(y*365.25) + 365 + floor(y/100) - floor(y/400), |
|||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dmy</span> |
|||
m = 1, |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;"><</span> <span style="color: #000000;">3</span> <span style="color: #008080;">then</span> |
|||
sansculottide = 5+rep_leap(y) |
|||
<span style="color: #000000;">y</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span> |
|||
while d>30 do |
|||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">12</span> |
|||
d -= 30 |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
m += 1 |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">365.25</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">/</span><span style="color: #000000;">100</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">/</span><span style="color: #000000;">400</span><span style="color: #0000FF;">)</span> |
|||
if m == 13 then |
|||
<span style="color: #0000FF;">+</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">30.6</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">654842</span> |
|||
if d > sansculottide then |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span> |
|||
d -= sansculottide |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
m = 1 |
|||
y += 1 |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">day_to_rep</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">day</span><span style="color: #0000FF;">)</span> |
|||
sansculottide = 5 + rep_leap(y) |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #000000;">day</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">365.25</span><span style="color: #0000FF;">)</span> |
|||
end if |
|||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">rep_leap</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
end if |
|||
<span style="color: #000000;">y</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> |
|||
end while |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
return {d,m,y} |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">day</span> <span style="color: #0000FF;">-</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">365.25</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">365</span> <span style="color: #0000FF;">+</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">/</span><span style="color: #000000;">100</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">/</span><span style="color: #000000;">400</span><span style="color: #0000FF;">),</span> |
|||
end function |
|||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">sansculottide</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">+</span><span style="color: #000000;">rep_leap</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)</span> |
|||
function day_to_gre(integer day) |
|||
<span style="color: #008080;">while</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">></span><span style="color: #000000;">30</span> <span style="color: #008080;">do</span> |
|||
integer y = floor(day/365.25), |
|||
<span style="color: #000000;">d</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">30</span> |
|||
d = day - floor(y*365.25) + 21, |
|||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> |
|||
m = 9 |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">13</span> <span style="color: #008080;">then</span> |
|||
y += 1792 |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">></span> <span style="color: #000000;">sansculottide</span> <span style="color: #008080;">then</span> |
|||
d += floor(y/100) - floor(y/400) - 13 |
|||
<span style="color: #000000;">d</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">sansculottide</span> |
|||
sequence gregoriam = gregorian -- (modifiable copy) |
|||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> |
|||
while d>gregoriam[m] do |
|||
<span style="color: #000000;">y</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> |
|||
d -= gregoriam[m] |
|||
<span style="color: #000000;">sansculottide</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">5</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">rep_leap</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)</span> |
|||
m += 1 |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
if m == 13 then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
m = 1 |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span> |
|||
y += 1 |
|||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">}</span> |
|||
gregoriam[2] = 28 + gre_leap(y) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
end if |
|||
end while |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">day_to_gre</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">day</span><span style="color: #0000FF;">)</span> |
|||
return {d,m,y} |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">day</span><span style="color: #0000FF;">/</span><span style="color: #000000;">365.25</span><span style="color: #0000FF;">),</span> |
|||
end function |
|||
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">day</span> <span style="color: #0000FF;">-</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">365.25</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">21</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">9</span> |
|||
function greg_to_frep(string greg) |
|||
<span style="color: #000000;">y</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1792</span> |
|||
{{integer day, string months, integer year}} = scanf(greg,"%d %s %d") |
|||
<span style="color: #000000;">d</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">/</span><span style="color: #000000;">100</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">/</span><span style="color: #000000;">400</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">13</span> |
|||
integer month = find(months,gregorians) |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">gregoriam</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">gregorian</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (modifiable copy)</span> |
|||
{day,month,year} = day_to_rep(gre_to_day({day,month,year})) |
|||
<span style="color: #008080;">while</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">></span><span style="color: #000000;">gregoriam</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">do</span> |
|||
string frep = iff(month=13?sprintf("%s %d",{sansculottides[day], year}) |
|||
<span style="color: #000000;">d</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">gregoriam</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m</span><span style="color: #0000FF;">]</span> |
|||
:sprintf("%d %s %d",{day, republicans[month], year})) |
|||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> |
|||
return frep |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">13</span> <span style="color: #008080;">then</span> |
|||
end function |
|||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> |
|||
<span style="color: #000000;">y</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> |
|||
function frep_to_greg(string frep) |
|||
<span style="color: #000000;">gregoriam</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">28</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">gre_leap</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)</span> |
|||
integer day, month, year |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
if frep[1]<='9' then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span> |
|||
{{day, string months, year}} = scanf(frep,"%d %s %d") |
|||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">}</span> |
|||
month = find(months,republicans) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
else |
|||
{{string days, year}} = scanf(frep,"%s %d") |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">greg_to_frep</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">greg</span><span style="color: #0000FF;">)</span> |
|||
day = find(days,sansculottides) |
|||
<span style="color: #0000FF;">{</span><span style="color: #004080;">integer</span> <span style="color: #000000;">day</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">months</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">year</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">scanf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">greg</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d %s %d"</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> |
|||
month = 13 |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">month</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">months</span><span style="color: #0000FF;">,</span><span style="color: #000000;">gregorians</span><span style="color: #0000FF;">)</span> |
|||
end if |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">day</span><span style="color: #0000FF;">,</span><span style="color: #000000;">month</span><span style="color: #0000FF;">,</span><span style="color: #000000;">year</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">day_to_rep</span><span style="color: #0000FF;">(</span><span style="color: #000000;">gre_to_day</span><span style="color: #0000FF;">({</span><span style="color: #000000;">day</span><span style="color: #0000FF;">,</span><span style="color: #000000;">month</span><span style="color: #0000FF;">,</span><span style="color: #000000;">year</span><span style="color: #0000FF;">}))</span> |
|||
{day,month,year} = day_to_gre(rep_to_day({day, month, year})) |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">frep</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">month</span><span style="color: #0000FF;">=</span><span style="color: #000000;">13</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%s %d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">sansculottides</span><span style="color: #0000FF;">[</span><span style="color: #000000;">day</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">year</span><span style="color: #0000FF;">})</span> |
|||
string greg = sprintf("%02d %s %d",{day, gregorians[month], year}) |
|||
<span style="color: #0000FF;">:</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d %s %d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">day</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">republicans</span><span style="color: #0000FF;">[</span><span style="color: #000000;">month</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">year</span><span style="color: #0000FF;">}))</span> |
|||
return greg |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">frep</span> |
|||
end function |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
constant test_data = { |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">frep_to_greg</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">frep</span><span style="color: #0000FF;">)</span> |
|||
{ "22 September 1792", "1 Vendémiaire 1" }, |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">day</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">month</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">year</span> |
|||
{ "20 May 1795", "1 Prairial 3" }, |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">months</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">days</span> |
|||
{ "15 July 1799", "27 Messidor 7" }, |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">frep</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]<=</span><span style="color: #008000;">'9'</span> <span style="color: #008080;">then</span> |
|||
{ "23 September 1803", "Fête de la Révolution 11" }, |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">day</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">months</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">year</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">scanf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">frep</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d %s %d"</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> |
|||
{ "31 December 1805", "10 Nivôse 14" }, |
|||
<span style="color: #000000;">month</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">months</span><span style="color: #0000FF;">,</span><span style="color: #000000;">republicans</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">else</span> |
|||
{ "18 March 1871", "27 Ventôse 79" }, |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">days</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">year</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">scanf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">frep</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s %d"</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> |
|||
{ "25 August 1944", "7 Fructidor 152" }, |
|||
<span style="color: #000000;">day</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">days</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sansculottides</span><span style="color: #0000FF;">)</span> |
|||
{ "19 September 2016", "Fête du travail 224" }, |
|||
<span style="color: #000000;">month</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">13</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
{ "06 May 1871", "16 Floréal 79" }, -- Paris Commune begins |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">day</span><span style="color: #0000FF;">,</span><span style="color: #000000;">month</span><span style="color: #0000FF;">,</span><span style="color: #000000;">year</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">day_to_gre</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rep_to_day</span><span style="color: #0000FF;">({</span><span style="color: #000000;">day</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">month</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">year</span><span style="color: #0000FF;">}))</span> |
|||
{ "23 May 1871", "3 Prairial 79" }, -- Paris Commune ends |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">greg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%02d %s %d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">day</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gregorians</span><span style="color: #0000FF;">[</span><span style="color: #000000;">month</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">year</span><span style="color: #0000FF;">})</span> |
|||
{ "09 November 1799", "18 Brumaire 8" }, -- Revolution ends by Napoléon coup |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">greg</span> |
|||
{ "02 December 1804", "11 Frimaire 13" }, -- Republic ends by Napoléon coronation |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
{ "30 October 1794", "9 Brumaire 3" }, -- École Normale Supérieure established |
|||
{ "27 July 1794", "9 Thermidor 2" }, -- Robespierre falls |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">test_data</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span> |
|||
{ "27 May 1799", "8 Prairial 7" }, -- Fromental Halévy born |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"22 September 1792"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 1"</span> <span style="color: #0000FF;">},</span> |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"20 May 1795"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Prairial 3"</span> <span style="color: #0000FF;">},</span> |
|||
{ "22 September 1792", "1 Vendémiaire 1" }, |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"15 July 1799"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"27 Messidor 7"</span> <span style="color: #0000FF;">},</span> |
|||
{ "22 September 1793", "1 Vendémiaire 2" }, |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 1803"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Fête de la Révolution 11"</span> <span style="color: #0000FF;">},</span> |
|||
{ "22 September 1794", "1 Vendémiaire 3" }, |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"31 December 1805"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"10 Nivôse 14"</span> <span style="color: #0000FF;">},</span> |
|||
{ "23 September 1795", "1 Vendémiaire 4" }, |
|||
{ "22 September 1796", "1 Vendémiaire 5" }, |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"18 March 1871"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"27 Ventôse 79"</span> <span style="color: #0000FF;">},</span> |
|||
{ "22 September 1797", "1 Vendémiaire 6" }, |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"25 August 1944"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"7 Fructidor 152"</span> <span style="color: #0000FF;">},</span> |
|||
{ "22 September 1798", "1 Vendémiaire 7" }, |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"19 September 2016"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Fête du travail 224"</span> <span style="color: #0000FF;">},</span> |
|||
{ "23 September 1799", "1 Vendémiaire 8" }, |
|||
{ "23 September 1800", "1 Vendémiaire 9" }, |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"06 May 1871"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"16 Floréal 79"</span> <span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- Paris Commune begins</span> |
|||
{ "23 September 1801", "1 Vendémiaire 10" }, |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 May 1871"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"3 Prairial 79"</span> <span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- Paris Commune ends</span> |
|||
{ "23 September 1802", "1 Vendémiaire 11" }, |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"09 November 1799"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"18 Brumaire 8"</span> <span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- Revolution ends by Napoléon coup</span> |
|||
{ "24 September 1803", "1 Vendémiaire 12" }, |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"02 December 1804"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"11 Frimaire 13"</span> <span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- Republic ends by Napoléon coronation</span> |
|||
{ "23 September 1804", "1 Vendémiaire 13" }, |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"30 October 1794"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"9 Brumaire 3"</span> <span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- École Normale Supérieure established</span> |
|||
{ "23 September 1805", "1 Vendémiaire 14" }, |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"27 July 1794"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"9 Thermidor 2"</span> <span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- Robespierre falls</span> |
|||
{ "23 September 1806", "1 Vendémiaire 15" }, |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"27 May 1799"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"8 Prairial 7"</span> <span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- Fromental Halévy born</span> |
|||
{ "24 September 1807", "1 Vendémiaire 16" }, |
|||
{ "23 September 1808", "1 Vendémiaire 17" }, |
|||
{ " |
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"22 September 1792"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 1"</span> <span style="color: #0000FF;">},</span> |
||
{ " |
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"22 September 1793"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 2"</span> <span style="color: #0000FF;">},</span> |
||
{ " |
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"22 September 1794"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 3"</span> <span style="color: #0000FF;">},</span> |
||
{ "23 September |
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 1795"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 4"</span> <span style="color: #0000FF;">},</span> |
||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"22 September 1796"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 5"</span> <span style="color: #0000FF;">},</span> |
|||
{ "21 September 2016", "Fête des récompenses 224" }, |
|||
{ "22 September |
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"22 September 1797"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 6"</span> <span style="color: #0000FF;">},</span> |
||
{ " |
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"22 September 1798"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 7"</span> <span style="color: #0000FF;">},</span> |
||
{ " |
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 1799"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 8"</span> <span style="color: #0000FF;">},</span> |
||
{ " |
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 1800"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 9"</span> <span style="color: #0000FF;">},</span> |
||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 1801"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 10"</span> <span style="color: #0000FF;">},</span> |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 1802"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 11"</span> <span style="color: #0000FF;">},</span> |
|||
for i=1 to length(test_data) do |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"24 September 1803"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 12"</span> <span style="color: #0000FF;">},</span> |
|||
string {greg, frep} = test_data[i], |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 1804"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 13"</span> <span style="color: #0000FF;">},</span> |
|||
frep2 = greg_to_frep(greg), |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 1805"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 14"</span> <span style="color: #0000FF;">},</span> |
|||
greg2 = frep_to_greg(frep), |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 1806"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 15"</span> <span style="color: #0000FF;">},</span> |
|||
ok = iff(frep=frep2 and greg=greg2?"ok":"**** ERROR ****") |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"24 September 1807"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 16"</span> <span style="color: #0000FF;">},</span> |
|||
if platform()=WINDOWS then |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 1808"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 17"</span> <span style="color: #0000FF;">},</span> |
|||
-- the windows console does not handle |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 1809"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 18"</span> <span style="color: #0000FF;">},</span> |
|||
-- non-basic-latin-ascii characters well... |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 1810"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 19"</span> <span style="color: #0000FF;">},</span> |
|||
frep = substitute_all(frep,"éêéô","eeeo") |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"24 September 1811"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 20"</span> <span style="color: #0000FF;">},</span> |
|||
end if |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 2015"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 224"</span> <span style="color: #0000FF;">},</span> |
|||
printf(1,"%18s <==> %-25s %s\n",{greg,frep,ok}) |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"21 September 2016"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Fête des récompenses 224"</span> <span style="color: #0000FF;">},</span> |
|||
end for |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"22 September 2016"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 225"</span> <span style="color: #0000FF;">},</span> |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"23 September 2016"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"2 Vendémiaire 225"</span> <span style="color: #0000FF;">},</span> |
|||
--sanity test: |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"22 September 2017"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1 Vendémiaire 226"</span> <span style="color: #0000FF;">},</span> |
|||
for i=1 to 150000 do -- (years 1792..~2203) |
|||
<span style="color: #0000FF;">{</span> <span style="color: #008000;">"28 September 2017"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"7 Vendémiaire 226"</span> <span style="color: #0000FF;">}</span> <span style="color: #0000FF;">}</span> |
|||
if rep_to_day(day_to_rep(i))!=i then ?9/0 end if |
|||
if gre_to_day(day_to_gre(i))!=i then ?9/0 end if |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test_data</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
end for</lang> |
|||
<span style="color: #004080;">string</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">greg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">frep</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">test_data</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> |
|||
<span style="color: #000000;">frep2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">greg_to_frep</span><span style="color: #0000FF;">(</span><span style="color: #000000;">greg</span><span style="color: #0000FF;">),</span> |
|||
<span style="color: #000000;">greg2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">frep_to_greg</span><span style="color: #0000FF;">(</span><span style="color: #000000;">frep</span><span style="color: #0000FF;">),</span> |
|||
<span style="color: #000000;">ok</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">frep</span><span style="color: #0000FF;">=</span><span style="color: #000000;">frep2</span> <span style="color: #008080;">and</span> <span style="color: #000000;">greg</span><span style="color: #0000FF;">=</span><span style="color: #000000;">greg2</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"ok"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"**** ERROR ****"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">WINDOWS</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000080;font-style:italic;">-- the windows console does not handle |
|||
-- non-basic-latin-ascii characters well...</span> |
|||
<span style="color: #000000;">frep</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute_all</span><span style="color: #0000FF;">(</span><span style="color: #000000;">frep</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"éêéô"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"eeeo"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%18s <==> %-25s %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">greg</span><span style="color: #0000FF;">,</span><span style="color: #000000;">frep</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ok</span><span style="color: #0000FF;">})</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #000080;font-style:italic;">--sanity test:</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">150000</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- (years 1792..~2203)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">rep_to_day</span><span style="color: #0000FF;">(</span><span style="color: #000000;">day_to_rep</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">))!=</span><span style="color: #000000;">i</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">gre_to_day</span><span style="color: #0000FF;">(</span><span style="color: #000000;">day_to_gre</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">))!=</span><span style="color: #000000;">i</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<!--</lang>--> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
Revision as of 15:36, 18 January 2022
You are encouraged to solve this task according to the task description, using any language you may know.
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 IF FN_rep_leap(y%) THEN sansculottides% = 6 ELSE sansculottides% = 5 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
FreeBASIC
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 freebasic>' version 18 Pluviose 227 ' compile with: fbc -s console ' retained the original comments for then BBC BASIC entry
- Macro rep_leap (_year)
' see comment at the beginning of rep_to_day ((_year +1) Mod 4 = 0 And ((_year +1) Mod 100 <> 0 Or (_year +1) Mod 400 = 0))
- EndMacro
- Macro gre_leap (_year)
(_year Mod 4 = 0 And (_year Mod 100 <> 0 Or _year Mod 400 = 0))
- EndMacro
Dim Shared As UInteger gregorian(11) => {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} Dim Shared As String gregorian_s(11), republican(11), sanscolottides(5) ' 7-bit ASCII encoding, so no accents on French words Data "January", "February", "March", "April", "May", "June" Data "July", "August", "September", "October", "November", "December" Data "Vendemiaire", "Brumaire", "Frimaire","Nivose", "Pluviose", "Ventose" Data "Germinal", "Floreal", "Prairial", "Messidor", "Thermidor", "Fructidor" Data "Fete de la Vertu", "Fete du Genie", "Fete du Travail", "Fete de l'Opinion" Data "Fete des Recompenses","Fete de la Revolution" Restore For i As UInteger = 0 To 11
Read gregorian_s(i)
Next For i As UInteger = 0 To 11
Read republican(i)
Next For i As UInteger = 0 To 5
Read sanscolottides(i)
Next
Sub split(s As String, ByRef d As UInteger, ByRef m As UInteger, ByRef y As UInteger)
Dim As String month_and_year, Month Dim As UInteger i
s = LCase(Trim(s)) : d = 0 : m = 0 : y = 0 If Left(s,4) = "fete" Then m = 13 For i = 0 To 5 If Left(s, Len(sanscolottides(i))) = LCase(sanscolottides(i)) Then d = i +1 y = Val(Right(s, Len(s) - Len(sanscolottides(i)) -1)) End If 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 For i = 0 To 11 If LCase(republican(i)) = Month Then m = i +1 Next Else For i = 0 To 11 If LCase(gregorian_s(i)) = Month Then m = i +1 Next End If End If
End Sub
Sub day_to_gre(Day As UInteger, ByRef d As UInteger, ByRef m As UInteger, ByRef y As UInteger)
y = Fix(Day / 365.25) d = Day - Fix(365.25 * y) + 21 y += 1792 d += y \ 100 - y \ 400 - 13 m = 8
While d > gregorian(m) d -= gregorian(m) m += 1 If m = 12 Then m = 0 y += 1 If gre_leap(y) Then gregorian(1) = 29 Else gregorian(1) = 28 End If Wend gregorian(1) = 28 m += 1
End Sub
Function gre_to_day(d As UInteger, m As UInteger, y As UInteger) As UInteger
' modified & repurposed from code given at ' https://www.staff.science.uu.nl/~gent0113/calendar/isocalendar_text5.htm
If m < 3 Then y -= 1 m += 12 End If Return Fix(365.25 * y) - y \ 100 + y \ 400 + Fix(30.6 * (m +1)) + d - 654842
End Function
Function rep_to_day(d As UInteger, m As UInteger, y As UInteger) As UInteger
' assume that a year is a leap year iff the _following_ year is ' divisible by 4, but not by 100 unless also by 400 ' ' other methods for computing republican leap years exist
If m = 13 Then m -= 1 d += 30 End If If rep_leap(y) Then d -= 1
Return 365 * y + (y +1) \ 4 - (y +1) \ 100 + (y +1) \ 400 + 30 * m + d - 395
End Function
Sub day_to_rep(Day As UInteger, ByRef d As UInteger, ByRef m As UInteger, ByRef y As UInteger)
Dim As UInteger sansculottides = 5
y = Fix(Day / 365.25) If rep_leap(y) Then y -= 1 d = Day - Fix(365.25 * y) + (y +1) \ 100 - (y +1) \ 400 y += 1 m = 1 If rep_leap(y) Then sansculottides = 6 While d > 30 d -= 30 m += 1 If m = 13 Then If d > sansculottides Then d -= sansculottides m = 1 y += 1 If rep_leap(y) Then sansculottides = 6 Else sansculottides = 5 End If End If Wend
End Sub
' ------=< main >=------
Dim As UInteger Day, Month, Year Dim As String src
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
Do
Line Input "> ", src If src <> "" Then split(src, Day, Month, Year) If Day = 0 Or Month = 0 Or Year <= 0 Then Print "Error in input" Continue Do End If ' for simplicity, we assume that years up to 1791 are republican ' and years from 1792 onwards are gregorian If Year < 1792 Then ' convert republican date to number of days elapsed ' since 21 september 1792, then convert that number ' to the gregorian date day_to_gre(rep_to_day(Day, Month, Year),Day, Month, Year) Print; Day; " "; gregorian_s(Month -1); " "; Year Else ' convert gregorian date to republican, via ' number of days elapsed since 21 september 1792 day_to_rep(gre_to_day(Day, Month, Year), Day, Month, Year) If Month = 13 Then Print sanscolottides(Day -1); " "; Year Else Print ; Day; " "; republican(Month -1); " "; Year End If End If End If
Loop Until src = ""
End</lang>
- Output:
> 1 Vendemiaire 1 > 22 September 1792 > 1 Vendemiaire 1 > 23 September 1806 > 1 Vendemiaire 15 22 September 1792 1 Vendemiaire 1 22 September 1792 1 Vendemiaire 15 23 September 1806 > 22 September 1792 > 22 September 1793 > 1 Vendemiaire 2 > 24 September 1807 > 1 Vendemiaire 16 1 Vendemiaire 1 1 Vendemiaire 2 22 September 1793 1 Vendemiaire 16 24 September 1807 > 1 Prairial 3 > 22 September 1794 > 1 Vendemiaire 3 > 23 September 1808 > 1 Vendemiaire 17 20 May 1795 1 Vendemiaire 3 22 September 1794 1 Vendemiaire 17 23 September 1808 > 20 May 1795 > 23 September 1795 > 1 Vendemiaire 4 > 23 September 1809 > 1 Vendemiaire 18 1 Prairial 3 1 Vendemiaire 4 23 September 1795 1 Vendemiaire 18 23 September 1809 > 27 Messidor 7 > 22 September 1796 > 1 Vendemiaire 5 > 23 September 1810 > 1 Vendemiaire 19 15 July 1799 1 Vendemiaire 5 22 September 1796 1 Vendemiaire 19 23 September 1810 > 15 July 1799 > 22 September 1797 > 1 Vendemiaire 6 > 24 September 1811 > 1 Vendemiaire 20 27 Messidor 7 1 Vendemiaire 6 22 September 1797 1 Vendemiaire 20 24 September 1811 > Fete de la Revolution 11 > 22 September 1798 > 1 Vendemiaire 7 > 23 September 2015 > 1 Vendemiaire 224 23 September 1803 1 Vendemiaire 7 22 September 1798 1 Vendemiaire 224 23 September 2015 > 23 September 1803 > 23 September 1799 > 1 Vendemiaire 8 > 22 September 2016 > 1 Vendemiaire 225 Fete de la Revolution 11 1 Vendemiaire 8 23 September 1799 1 Vendemiaire 225 22 September 2016 > 10 Nivose 14 > 23 September 1800 > 1 Vendemiaire 9 > 22 September 2017 > 1 Vendemiaire 226 31 December 1805 1 Vendemiaire 9 23 September 1800 1 Vendemiaire 226 22 September 2017 > 31 December 1805 > 23 September 1801 > 1 Vendemiaire 10 > 22 September 2018 > 1 Vendemiaire 227 10 Nivose 14 1 Vendemiaire 10 23 September 1801 1 Vendemiaire 227 22 September 2018 > 23 September 1802 > 1 Vendemiaire 11 > 23 September 2019 > 1 Vendemiaire 228 1 Vendemiaire 11 23 September 1802 1 Vendemiaire 228 23 September 2019 > 24 September 1803 > 1 Vendemiaire 12 > 22 September 2020 > 1 Vendemiaire 229 1 Vendemiaire 12 24 September 1803 1 Vendemiaire 229 22 September 2020 > 23 September 1804 > 1 Vendemiaire 13 1 Vendemiaire 13 23 September 1804 > 23 September 1805 > 1 Vendemiaire 14 1 Vendemiaire 14 23 September 1805
F#
<lang fsharp> // French Republican Calander: Nigel Galloway. April 16th., 2021 let firstDay=System.DateTime.Parse("22/9/1792") type monthsFRC= Vendemiaire = 0
|Brumaire = 30 |Frimaire = 60 |Nivose = 90 |Pluviose = 120 |Ventose = 150 |Germinal = 180 |Floral = 210 |Prairial = 240 |Messidor = 270 |Thermidor = 300 |Fructidor = 330 |Virtue = 360 |Talent = 361 |Labour = 362 |Opinion = 363 |Honours = 364 |Revolution = 365
type months= January = 1
|February = 2 |March = 3 |April = 4 |May = 5 |June = 6 |July = 7 |August = 8 |September = 9 |October = 10 |November = 11 |December = 12
let frc2Greg n (g:monthsFRC) l=firstDay+System.TimeSpan.FromDays(float((l-1)*365+l/4+(int g)+n-1)) let rec fG n g=let i=match g with 3 |7 |11->366 |_->365 in if n(1,enum<monthsFRC>(360+n),g) |(n,l)->(l+1,enum<monthsFRC>(n*30),g) let n=(frc2Greg 1 monthsFRC.Vendemiaire 1) in printfn "%d %s %d -> %d %A %d" 1 "Vendemiaire" 1 n.Day (enum<months> n.Month) n.Year let n=(frc2Greg 27 monthsFRC.Messidor 7) in printfn "%d %s %d -> %d %A %d" 27 "Messidor" 7 n.Day (enum<months> n.Month) n.Year let n=(frc2Greg 1 monthsFRC.Revolution 11) in printfn "%d %s %d -> %d %A %d" 1 "Revolution" 11 n.Day (enum<months> n.Month) n.Year let n=(frc2Greg 10 monthsFRC.Nivose 14) in printfn "%d %s %d -> %d %A %d" 10 "Nivose" 14 n.Day (enum<months> n.Month) n.Year let n,g,l=Greg2FRC(System.DateTime(1792,9,22)) in printfn "%d %s %d -> %d %A %d" 22 "September" 1792 n g l let n,g,l=Greg2FRC(System.DateTime(1799,7,15)) in printfn "%d %s %d -> %d %A %d" 15 "July" 1799 n g l let n,g,l=Greg2FRC(System.DateTime(1803,9,23)) in printfn "%d %s %d -> %d %A %d" 23 "September" 1803 n g l let n,g,l=Greg2FRC(System.DateTime(1805,12,31)) in printfn "%d %s %d -> %d %A %d" 31 "December" 1805 n g l </lang>
- Output:
1 Vendemiaire 1 -> 22 September 1792 27 Messidor 7 -> 15 July 1799 1 Revolution 11 -> 23 September 1803 10 Nivose 14 -> 31 December 1805 22 September 1792 -> 1 Vendemiaire 1 15 July 1799 -> 27 Messidor 7 23 September 1803 -> 1 Revolution 11 31 December 1805 -> 10 Nivose 14
Go
A rather literal port, just for reference. Far from idiomatic Go. <lang go>package main
import (
"bufio" "fmt" "os" "strconv" "strings"
)
var (
gregorianStr = []string{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} gregorian = []int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} republicanStr = []string{"Vendemiaire", "Brumaire", "Frimaire", "Nivose", "Pluviose", "Ventose", "Germinal", "Floreal", "Prairial", "Messidor", "Thermidor", "Fructidor"} sansculottidesStr = []string{"Fete de la vertu", "Fete du genie", "Fete du travail", "Fete de l'opinion", "Fete des recompenses", "Fete de la Revolution"}
)
func main() {
fmt.Println("*** French Republican ***") fmt.Println("*** calendar converter ***") fmt.Println("Enter a date to convert, in the format 'day month year'") fmt.Println("e.g.: 1 Prairial 3,") fmt.Println(" 20 May 1795.") fmt.Println("For Sansculottides, use 'day year'") fmt.Println("e.g.: Fete de l'opinion 9.") fmt.Println("Or just press 'RETURN' to exit the program.") fmt.Println() for sc := bufio.NewScanner(os.Stdin); ; { fmt.Print("> ") sc.Scan() src := sc.Text() if src == "" { return } day, month, year := split(src) if year < 1792 { day, month, year = dayToGre(repToDay(day, month, year)) fmt.Println(day, gregorianStr[month-1], year) } else { day, month, year := dayToRep(greToDay(day, month, year)) if month == 13 { fmt.Println(sansculottidesStr[day-1], year) } else { fmt.Println(day, republicanStr[month-1], year) } } }
}
func split(s string) (d, m, y int) {
if strings.HasPrefix(s, "Fete") { m = 13 for i, sc := range sansculottidesStr { if strings.HasPrefix(s, sc) { d = i + 1 y, _ = strconv.Atoi(s[len(sc)+1:]) } } } else { d, _ = strconv.Atoi(s[:strings.Index(s, " ")]) my := s[strings.Index(s, " ")+1:] mStr := my[:strings.Index(my, " ")] y, _ = strconv.Atoi(my[strings.Index(my, " ")+1:]) months := gregorianStr if y < 1792 { months = republicanStr } for i, mn := range months { if mn == mStr { m = i + 1 } } } return
}
func greToDay(d, m, y int) int {
if m < 3 { y-- m += 12 } return y*36525/100 - y/100 + y/400 + 306*(m+1)/10 + d - 654842
}
func repToDay(d, m, y int) int {
if m == 13 { m-- d += 30 } if repLeap(y) { d-- } return 365*y + (y+1)/4 - (y+1)/100 + (y+1)/400 + 30*m + d - 395
}
func dayToGre(day int) (d, m, y int) {
y = day * 100 / 36525 d = day - y*36525/100 + 21 y += 1792 d += y/100 - y/400 - 13 m = 8 for d > gregorian[m] { d -= gregorian[m] m++ if m == 12 { m = 0 y++ if greLeap(y) { gregorian[1] = 29 } else { gregorian[1] = 28 } } } m++ return
}
func dayToRep(day int) (d, m, y int) {
y = (day-1) * 100 / 36525 if repLeap(y) { y-- } d = day - (y+1)*36525/100 + 365 + (y+1)/100 - (y+1)/400 y++ m = 1 sansculottides := 5 if repLeap(y) { sansculottides = 6 } for d > 30 { d -= 30 m += 1 if m == 13 { if d > sansculottides { d -= sansculottides m = 1 y++ sansculottides = 5 if repLeap(y) { sansculottides = 6 } } } } return
}
func repLeap(year int) bool {
return (year+1)%4 == 0 && ((year+1)%100 != 0 || (year+1)%400 == 0)
}
func greLeap(year int) bool {
return year%4 == 0 && (year%100 != 0 || year%400 == 0)
}</lang>
- Output:
$ go run frc.go *** 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 > $
More idiomatic
A start anyway. Computations extracted to a package, a type defined for French Republican Dates, time package from standard library used. Ignores invalid input rather than panicking. <lang go>package frc
import (
"fmt" "strconv" "strings" "time"
)
type Date struct {
Year int Month int Day int
}
func (d Date) String() string {
if d.Month == 13 { return fmt.Sprintf("%s %d", sansculotidesStr[d.Day-1], d.Year) } return fmt.Sprintf("%d %s %d", d.Day, republicanStr[d.Month-1], d.Year)
}
func Parse(s string) (dt Date, ok bool) {
f := strings.Fields(s) var err error switch { case len(f) == 3: if dt.Day, err = strconv.Atoi(f[0]); err != nil { return } i := 0 for republicanStr[i] != f[1] { i++ if i == len(republicanStr) { return } } dt.Month = i + 1 if dt.Year, err = strconv.Atoi(f[2]); err != nil { return } ok = true return case len(f) > 3: for i, sc := range sansculotidesStr { if strings.HasPrefix(s, sc) { dt.Month = 13 dt.Day = i + 1 dt.Year, err = strconv.Atoi(s[len(sc)+1:]) if err == nil { ok = true } return } } } return
}
func (dt Date) ToGregorian() (y int, m time.Month, d int) {
yr, mn, dy := dayToGre(repToDay(dt.Day, dt.Month, dt.Year)) return yr, time.Month(mn), dy
}
func FromGregorian(y int, m time.Month, d int) Date {
day, month, year := dayToRep(greToDay(d, int(m), y)) return Date{Year: year, Month: month, Day: day}
} var (
gregorian = []int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} republicanStr = []string{"Vendemiaire", "Brumaire", "Frimaire", "Nivose", "Pluviose", "Ventose", "Germinal", "Floreal", "Prairial", "Messidor", "Thermidor", "Fructidor"} sansculotidesStr = []string{"Fete de la vertu", "Fete du genie", "Fete du travail", "Fete de l'opinion", "Fete des recompenses", "Fete de la Revolution"}
)
func greToDay(d, m, y int) int {
if m < 3 { y-- m += 12 } return y*36525/100 - y/100 + y/400 + 306*(m+1)/10 + d - 654842
}
func repToDay(d, m, y int) int {
if m == 13 { m-- d += 30 } if repLeap(y) { d-- } return 365*y + (y+1)/4 - (y+1)/100 + (y+1)/400 + 30*m + d - 395
}
func dayToGre(day int) (d, m, y int) {
y = day * 100 / 36525 d = day - y*36525/100 + 21 y += 1792 d += y/100 - y/400 - 13 m = 8 for d > gregorian[m] { d -= gregorian[m] m++ if m == 12 { m = 0 y++ if greLeap(y) { gregorian[1] = 29 } else { gregorian[1] = 28 } } } m++ return
}
func dayToRep(day int) (d, m, y int) {
y = (day-1) * 100 / 36525 if repLeap(y) { y-- } d = day - (y+1)*36525/100 + 365 + (y+1)/100 - (y+1)/400 y++ m = 1 sansculottides := 5 if repLeap(y) { sansculottides = 6 } for d > 30 { d -= 30 m += 1 if m == 13 { if d > sansculottides { d -= sansculottides m = 1 y++ sansculottides = 5 if repLeap(y) { sansculottides = 6 } } } } return
}
func repLeap(year int) bool {
return (year+1)%4 == 0 && ((year+1)%100 != 0 || (year+1)%400 == 0)
}
func greLeap(year int) bool {
return year%4 == 0 && (year%100 != 0 || year%400 == 0)
}</lang> <lang go>package main
import (
"bufio" "fmt" "os" "time"
"frc"
)
func main() {
fmt.Println("*** French Republican ***") fmt.Println("*** calendar converter ***") fmt.Println("Enter a date to convert, in the format 'day month year'") fmt.Println("e.g.: 1 Prairial 3,") fmt.Println(" 20 May 1795.") fmt.Println("For Sansculottides, use 'day year'") fmt.Println("e.g.: Fete de l'opinion 9.") fmt.Println("Or just press 'RETURN' to exit the program.") fmt.Println() for sc := bufio.NewScanner(os.Stdin); ; { fmt.Print("> ") sc.Scan() src := sc.Text() if src == "" { return } f, ok := frc.Parse(src) if ok { fmt.Println(f.ToGregorian()) continue } t, err := time.Parse(`2 January 2006`, src) if err == nil { fmt.Println(frc.FromGregorian(t.Date())) } }
}</lang>
Julia
To stay within historical dates, will throw a domain error if the French Republican date is outside the interval the calendar was actually used. <lang julia>using Dates
const GC_FORMAT = DateFormat("d U y")
const RC_FIRST_DAY = Date(1792, 9, 22)
const MAX_RC_DATE = Date(1805, 12, 31)
const RC_MONTHS = [
"Vendémiaire", "Brumaire", "Frimaire", "Nivôse", "Pluviôse", "Ventôse", "Germinal", "Floréal", "Prairial", "Messidor", "Thermidor", "Fructidor"
]
const RC_DAYS_IN_MONTH = 30
const RC_SANSCULOTTIDES = [
"Fête de la vertu", "Fête du génie", "Fête du travail", "Fête de l'opinion", "Fête des récompenses", "Fête de la Révolution"
]
additionaldaysforyear(yr) = yr > 11 ? 3 : yr > 7 ? 2 : yr > 3 ? 1 : 0 additionaldaysformonth(mo) = 30 * (mo - 1) daysforFete(s) = findfirst(x -> x == s, RC_SANSCULOTTIDES) + 359
function togregorian(rc::String)
yearstring, firstpart = reverse.(split(reverse(strip(rc)), r"\s+", limit=2)) rcyear = parse(Int, yearstring) pastyeardays = (rcyear - 1) * 365 + additionaldaysforyear(rcyear) if isnumeric(firstpart[1]) daystring, monthstring = split(firstpart, r"\s+", limit=2) nmonth = findfirst(x -> x == monthstring, RC_MONTHS) pastmonthdays = 30 * (nmonth - 1) furtherdays = parse(Int, daystring) + pastmonthdays + pastyeardays - 1 else furtherdays = daysforFete(firstpart) + pastyeardays end gregorian = RC_FIRST_DAY + Day(furtherdays) if furtherdays < 0 || gregorian > MAX_RC_DATE throw(DomainError("French Republican Calendar date out of range")) end return Day(gregorian).value, monthname(Month(gregorian).value), Year(gregorian).value
end
function torepublican(gc::String)
date = Date(DateTime(gc, GC_FORMAT)) if date < RC_FIRST_DAY || date > MAX_RC_DATE throw(DomainError("French Republican Calendar date out of range")) end rcyear, rcdays = divrem(((date - RC_FIRST_DAY).value + 366), 365) rcdays -= additionaldaysforyear(rcyear) if rcdays < 1 rcyear -= 1 rcdays += 366 end if rcdays < 361 nmonth, rcday = divrem(rcdays, 30) return rcday, RC_MONTHS[nmonth + 1], rcyear else return RC_SANSCULOTTIDES[rcdays - 360], rcyear end
end
const republican = [
"1 Vendémiaire 1", "1 Prairial 3", "27 Messidor 7", "Fête de la Révolution 11", "10 Nivôse 14"
]
const gregorian = [
"22 September 1792", "20 May 1795", "15 July 1799", "23 September 1803", "31 December 1805"
]
function testrepublicancalendar()
println("French Republican to Gregorian") for s in republican println(lpad(s, 24), " => ", togregorian(s)) end println("Gregorian to French Republican") for s in gregorian println(lpad(s, 24), " => ", torepublican(s)) end
end
testrepublicancalendar()
</lang>
- Output:
French Republican to Gregorian 1 Vendémiaire 1 => (22, "September", 1792) 1 Prairial 3 => (20, "May", 1795) 27 Messidor 7 => (15, "July", 1799) Fête de la Révolution 11 => (23, "September", 1803) 10 Nivôse 14 => (31, "December", 1805) Gregorian to French Republican 22 September 1792 => (1, "Vendémiaire", 1) 20 May 1795 => (1, "Prairial", 3) 15 July 1799 => (27, "Messidor", 7) 23 September 1803 => ("Fête de la Révolution", 11) 31 December 1805 => (10, "Nivôse", 14)
Kotlin
<lang scala>// version 1.1.4-3
import java.time.format.DateTimeFormatter import java.time.LocalDate import java.time.temporal.ChronoUnit.DAYS
/* year = 1.. month = 1..13 day = 1..30 */ class FrenchRCDate(val year: Int, val month: Int, val day: Int) {
init { require (year > 0 && month in 1..13) if (month < 13) require (day in 1..30) else { val leap = isLeapYear(year) require (day in (if (leap) 1..6 else 1..5)) } }
override fun toString() = if (month < 13) "$day ${months[month - 1]} $year" else "${intercal[day - 1]} $year"
fun toLocalDate(): LocalDate { var sumDays = 0L for (i in 1 until year) sumDays += if (isLeapYear(i)) 366 else 365 val dayInYear = (month - 1) * 30 + day - 1 return introductionDate.plusDays(sumDays + dayInYear) }
companion object { /* uses the 'continuous method' for years after 1805 */ fun isLeapYear(y: Int): Boolean { val yy = y + 1 return (yy % 4 == 0) && (yy % 100 != 0 || yy % 400 == 0) }
fun parse(frcDate: String): FrenchRCDate { val splits = frcDate.trim().split(' ') if (splits.size == 3) { val month = months.indexOf(splits[1]) + 1 require(month in 1..13) val year = splits[2].toIntOrNull() ?: 0 require(year > 0) val monthLength = if (month < 13) 30 else if (isLeapYear(year)) 6 else 5 val day = splits[0].toIntOrNull() ?: 0 require(day in 1..monthLength) return FrenchRCDate(year, month, day) } else if (splits.size in 4..5) { val yearStr = splits[splits.lastIndex] val year = yearStr.toIntOrNull() ?: 0 require(year > 0) val scDay = frcDate.trim().dropLast(yearStr.length + 1) val day = intercal.indexOf(scDay) + 1 val maxDay = if (isLeapYear(year)) 6 else 5 require (day in 1..maxDay) return FrenchRCDate(year, 13, day) } else throw IllegalArgumentException("Invalid French Republican date") }
/* for convenience we treat 'Sansculottide' as an extra month with 5 or 6 days */ val months = arrayOf( "Vendémiaire", "Brumaire", "Frimaire", "Nivôse", "Pluviôse", "Ventôse", "Germinal", "Floréal", "Prairial", "Messidor", "Thermidor", "Fructidor", "Sansculottide" )
val intercal = arrayOf( "Fête de la vertu", "Fête du génie", "Fête du travail", "Fête de l'opinion", "Fête des récompenses", "Fête de la Révolution" )
val introductionDate = LocalDate.of(1792, 9, 22) }
}
fun LocalDate.toFrenchRCDate(): FrenchRCDate {
val daysDiff = DAYS.between(FrenchRCDate.introductionDate, this).toInt() + 1 if (daysDiff <= 0) throw IllegalArgumentException("Date can't be before 22 September 1792") var year = 1 var startDay = 1 while (true) { val endDay = startDay + if (FrenchRCDate.isLeapYear(year)) 365 else 364 if (daysDiff in startDay..endDay) break year++ startDay = endDay + 1 } val remDays = daysDiff - startDay val month = remDays / 30 val day = remDays - month * 30 return FrenchRCDate(year, month + 1, day + 1)
}
fun main(args: Array<String>) {
val formatter = DateTimeFormatter.ofPattern("d MMMM yyyy") val dates = arrayOf("22 September 1792", "20 May 1795", "15 July 1799", "23 September 1803", "31 December 1805", "18 March 1871", "25 August 1944", "19 September 2016", "22 September 2017", "28 September 2017") val frcDates = Array<String>(dates.size) { "" } for ((i, date) in dates.withIndex()) { val thisDate = LocalDate.parse(date, formatter) val frcd = thisDate.toFrenchRCDate() frcDates[i] = frcd.toString() println("${date.padEnd(25)} => $frcd") }
// now process the other way around println() for (frcDate in frcDates) { val thisDate = FrenchRCDate.parse(frcDate) val lds = formatter.format(thisDate.toLocalDate()) println("${frcDate.padEnd(25)} => $lds") }
}</lang>
- Output:
22 September 1792 => 1 Vendémiaire 1 20 May 1795 => 1 Prairial 3 15 July 1799 => 27 Messidor 7 23 September 1803 => Fête de la Révolution 11 31 December 1805 => 10 Nivôse 14 18 March 1871 => 27 Ventôse 79 25 August 1944 => 7 Fructidor 152 19 September 2016 => Fête du travail 224 22 September 2017 => 1 Vendémiaire 226 28 September 2017 => 7 Vendémiaire 226 1 Vendémiaire 1 => 22 September 1792 1 Prairial 3 => 20 May 1795 27 Messidor 7 => 15 July 1799 Fête de la Révolution 11 => 23 September 1803 10 Nivôse 14 => 31 December 1805 27 Ventôse 79 => 18 March 1871 7 Fructidor 152 => 25 August 1944 Fête du travail 224 => 19 September 2016 1 Vendémiaire 226 => 22 September 2017 7 Vendémiaire 226 => 28 September 2017
Nim
As was done in Julia version, we have limited the date range to historical dates only. <lang Nim> import strformat, strscans, strutils, times
const
RcMonths = ["Vendémiaire", "Brumaire", "Frimaire", "Nivôse", "Pluviôse", "Ventôse", "Germinal", "Floréal", "Prairial", "Messidor", "Thermidor", "Fructidor"]
SansCulottides = ["Fête de la vertu", "Fête du génie", "Fête du travail", "Fête de l’opinion", "Fête des récompenses", "Fête de la Révolution"]
let
# First and last dates of republican calendar expressed in gregorian calendar. FirstRcDate = initDateTime(22, mSep, 1792, 0, 0, 0) LastRcDate = initDateTime(31, mDec, 1805, 0, 0, 0)
type
# French republican date representation. RcDayRange = 1..30 RcMonthRange = 1..13 RcYearRange = 1..14 RepublicanDate = tuple[year: RcYearRange, month: RcMonthRange, day: RcDayRange]
- Last dates of republican calendar expressed in republican calendar.
const RcLastDate: RepublicanDate = (RcYearRange(14), RcMonthRange(4), RcDayRange(10))
proc notnum(input: string; str: var string; start: int): int =
# Parsing procedure to extract non numerical part of a date. var i = start while i <= input.high: if input[i] in '0'..'9': break str.add input[i] inc i if str.len == 0 or str[^1] != ' ': return -1 # Not terminated by a space. str.setLen(str.len - 1) # Back before the space. result = str.len
proc parseRepublicanDate(rdate: string): RepublicanDate =
## Parse a French republican date and return its representation.
let date = rdate.strip() var day, month, year: int var monthString, dayString: string
if date.scanf("$i $+ $i", day, monthString, year): # Normal day. if day notin 1..30: raise newException(ValueError, "wrong day number: $1.".format(day)) month = RcMonths.find(monthString) + 1 if month == 0: raise newException(ValueError, "unknown French republican month: $1." % monthString)
elif date.scanf("${notnum} $i", dayString, year): # Sans-culottide day (also known as “jour complémentaire”). month = 13 # Value used for sans-culottide days. day = SansCulottides.find(dayString) + 1 if day == 0: raise newException(ValueError, "wrong “sans-culottide” day: « $1 »." % dayString) if day == 6 and year mod 4 != 3: raise newException(ValueError, "republican year $1 is not a leap year".format(year))
else: raise newException(ValueError, "invalid French republican date: « $1 »." % date)
result = (RcYearRange(year), RcMonthRange(month), RcDayRange(day)) if result > RcLastDate: raise newException(ValueError, "republican date out of range: « $1 »." % date)
proc `$`(date: RepublicanDate): string =
## Return the string representation of a French republican date.
if date.month != 13: # Normal day. result = "$1 $2 $3".format(date.day, RcMonths[date.month - 1], date.year) else: # Supplementary day. result = "$1 $2".format(SansCulottides[date.day - 1], date.year)
proc toGregorian(rdate: RepublicanDate): DateTime =
## Convert a republican date tuple to a gregorian date (DateTime object). let day = (rdate.day - 1) + (rdate.month - 1) * 30 + (rdate.year - 1) * 365 + rdate.year div 4 result = FirstRcDate + initTimeInterval(days = day)
proc toGregorian(rdate: string): string =
## Convert a republican date string to a gregorian date string. let date = rdate.parseRepublicanDate() result = date.toGregorian().format("dd MMMM yyyy")
proc toRepublican(gdate: DateTime): RepublicanDate =
## Convert a gregorian date (DateTime object) to a republican date tuple.
if gdate notin FirstRcDate..LastRcDate: raise newException(ValueError, "impossible conversion to republican date.") let d = gdate - FirstRcDate
# Add a dummy year before year 1 in order to use a four years period. let dayNumber = d.inDays + 365 let periodNum = dayNumber div 1461 let dayInPeriod = dayNumber mod 1461
# Compute year and day in year. let yearInPeriod = min(dayInPeriod div 365, 3) result.year = periodNum * 4 + yearInPeriod let dayInYear = dayInPeriod - yearInPeriod * 365
# Compute month and day. result.month = dayInYear div 30 + 1 result.day = dayInYear mod 30 + 1
proc toRepublican(gdate: string): string =
## Convert a gregorian date string to a republican date string. let date = gdate.parse("d MMMM yyyy") result = $(date.toRepublican())
when isMainModule:
const RepublicanDates = ["1 Vendémiaire 1", "1 Prairial 3", "27 Messidor 7", "Fête de la Révolution 11", "10 Nivôse 14"] GregorianDates = ["22 September 1792", "20 May 1795", "15 July 1799", "23 September 1803", "31 December 1805"]
echo "From French republican dates to gregorian dates:" for rdate in RepublicanDates: echo &"{rdate:>24} → {rdate.toGregorian()}" echo()
echo "From gregorian dates to French republican dates:" for gdate in GregorianDates: echo &"{gdate:>24} → {gdate.toRepublican()}"</lang>
- Output:
From French republican dates to gregorian dates: 1 Vendémiaire 1 → 22 September 1792 1 Prairial 3 → 20 May 1795 27 Messidor 7 → 15 July 1799 Fête de la Révolution 11 → 23 September 1803 10 Nivôse 14 → 31 December 1805 From gregorian dates to French republican dates: 22 September 1792 → 1 Vendémiaire 1 20 May 1795 → 1 Prairial 3 15 July 1799 → 27 Messidor 7 23 September 1803 → Fête de la Révolution 11 31 December 1805 → 10 Nivôse 14
Perl
<lang perl>use feature 'state'; use DateTime; my @month_names = qw{
Vendémiaire Brumaire Frimaire Nivôse Pluviôse Ventôse Germinal Floréal Prairial Messidor Thermidor Fructidor
}; my @intercalary = (
'Fête de la vertu', 'Fête du génie', 'Fête du travail', "Fête de l'opinion", 'Fête des récompenses', 'Fête de la Révolution',
); my %month_nums = map { $month_names[$_] => $_+1 } 0 .. $#month_names; my %i_cal_nums = map { $intercalary[$_] => $_+1 } 0 .. $#intercalary; my $i_cal_month = 13; my $epoch = DateTime->new( year => 1792, month => 9, day => 22 );
sub is_republican_leap_year {
my $y = $_[0] + 1; return !!( ($y % 4)==0 and (($y % 100)!=0 or ($y % 400)==0) );
}
sub Republican_to_Gregorian {
my ($rep_date) = @_; state $months = join '|', map { quotemeta } @month_names; state $intercal = join '|', map { quotemeta } @intercalary; state $re = qr{ \A \s* (?: (?<ic> $intercal) | (?<day> \d+) \s+ (?<month> $months) ) \s+ (?<year> \d+) \s* \z }msx;
$rep_date =~ /$re/ or die "Republican date not recognized: '$rep_date'";
my $day1 = $+{ic} ? $i_cal_nums{$+{ic}} : $+{day}; my $month1 = $+{month} ? $month_nums{$+{month}} : $i_cal_month; my $year1 = $+{year};
my $days_since_epoch = ($year1-1) * 365 + ($month1-1) * 30 + ($day1-1);
my $leap_days = grep { is_republican_leap_year($_) } 1 .. $year1-1; return $epoch->clone->add( days => ($days_since_epoch + $leap_days) );
}
sub Gregorian_to_Republican {
my ($greg_date) = @_;
my $days_since_epoch = $epoch->delta_days($greg_date)->in_units('days'); die if $days_since_epoch < 0; my ( $year, $days ) = ( 1, $days_since_epoch ); while (1) { my $year_length = 365 + ( is_republican_leap_year($year) ? 1 : 0 ); last if $days < $year_length; $days -= $year_length; $year += 1; } my $day0 = $days % 30; my $month0 = ($days - $day0) / 30;
my ( $day1, $month1 ) = ( $day0 + 1, $month0 + 1 );
return $month1 == $i_cal_month ? "$intercalary[$day0 ] $year" : "$day1 $month_names[$month0] $year";
}
while () {
s{\s*\#.+\n?\z}{}; /^(\d{4})-(\d{2})-(\d{2})\s+(\S.+?\S)\s*$/ or die;
my $g = DateTime->new( year => $1, month => $2, day => $3 ); my $r = $4;
die if Republican_to_Gregorian($r) != $g or Gregorian_to_Republican($g) ne $r;
die if Gregorian_to_Republican(Republican_to_Gregorian($r)) ne $r or Republican_to_Gregorian(Gregorian_to_Republican($g)) != $g;
} say 'All tests successful.';
__DATA__ 1792-09-22 1 Vendémiaire 1 1795-05-20 1 Prairial 3 1799-07-15 27 Messidor 7 1803-09-23 Fête de la Révolution 11 1805-12-31 10 Nivôse 14 1871-03-18 27 Ventôse 79 1944-08-25 7 Fructidor 152 2016-09-19 Fête du travail 224 1871-05-06 16 Floréal 79 # Paris Commune begins 1871-05-23 3 Prairial 79 # Paris Commune ends 1799-11-09 18 Brumaire 8 # Revolution ends by Napoléon coup 1804-12-02 11 Frimaire 13 # Republic ends by Napoléon coronation 1794-10-30 9 Brumaire 3 # École Normale Supérieure established 1794-07-27 9 Thermidor 2 # Robespierre falls 1799-05-27 8 Prairial 7 # Fromental Halévy born 1792-09-22 1 Vendémiaire 1 1793-09-22 1 Vendémiaire 2 1794-09-22 1 Vendémiaire 3 1795-09-23 1 Vendémiaire 4 1796-09-22 1 Vendémiaire 5 1797-09-22 1 Vendémiaire 6 1798-09-22 1 Vendémiaire 7 1799-09-23 1 Vendémiaire 8 1800-09-23 1 Vendémiaire 9 1801-09-23 1 Vendémiaire 10 1802-09-23 1 Vendémiaire 11 1803-09-24 1 Vendémiaire 12 1804-09-23 1 Vendémiaire 13 1805-09-23 1 Vendémiaire 14 1806-09-23 1 Vendémiaire 15 1807-09-24 1 Vendémiaire 16 1808-09-23 1 Vendémiaire 17 1809-09-23 1 Vendémiaire 18 1810-09-23 1 Vendémiaire 19 1811-09-24 1 Vendémiaire 20 2015-09-23 1 Vendémiaire 224 2016-09-22 1 Vendémiaire 225 2017-09-22 1 Vendémiaire 226 </lang>
- Output:
All tests successful.
Phix
with javascript_semantics constant gregorians = {"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}, republicans = {"Vendémiaire", "Brumaire", "Frimaire", "Nivôse", "Pluviôse", "Ventôse", "Germinal", "Floréal", "Prairial", "Messidor", "Thermidor", "Fructidor"}, sansculottides = {"Fête de la vertu", "Fête du génie", "Fête du travail", "Fête de l'opinion", "Fête des récompenses", "Fête de la Révolution"} function rep_leap(integer year) return mod(year+1,4)==0 and (mod(year+1,100)!=0 or mod(year+1,400)==0) end function function rep_to_day(sequence dmy) integer {d, m, y} = dmy if m == 13 then m -= 1 d += 30 end if if rep_leap(y) then d -= 1 end if integer res = 365*(y-1) + floor((y+1)/4) - floor((y+1)/100) + floor((y+1)/400) + 30*(m-1) + d return res end function function gre_leap(integer year) return mod(year,4)==0 and (mod(year,100)!=0 or mod(year,400)==0) end function function gre_to_day(sequence dmy) integer {d, m, y} = dmy if m < 3 then y -= 1 m += 12 end if integer res = floor(y*365.25) - floor(y/100) + floor(y/400) + floor(30.6*(m+1)) + d - 654842 return res end function function day_to_rep(integer day) integer y = floor((day-1)/365.25) if not rep_leap(y) then y += 1 end if integer d = day - floor(y*365.25) + 365 + floor(y/100) - floor(y/400), m = 1, sansculottide = 5+rep_leap(y) while d>30 do d -= 30 m += 1 if m == 13 then if d > sansculottide then d -= sansculottide m = 1 y += 1 sansculottide = 5 + rep_leap(y) end if end if end while return {d,m,y} end function function day_to_gre(integer day) integer y = floor(day/365.25), d = day - floor(y*365.25) + 21, m = 9 y += 1792 d += floor(y/100) - floor(y/400) - 13 sequence gregoriam = deep_copy(gregorian) -- (modifiable copy) while d>gregoriam[m] do d -= gregoriam[m] m += 1 if m == 13 then m = 1 y += 1 gregoriam[2] = 28 + gre_leap(y) end if end while return {d,m,y} end function function greg_to_frep(string greg) {integer day, string months, integer year} = scanf(greg,"%d %s %d")[1] integer month = find(months,gregorians) {day,month,year} = day_to_rep(gre_to_day({day,month,year})) string frep = iff(month=13?sprintf("%s %d",{sansculottides[day], year}) :sprintf("%d %s %d",{day, republicans[month], year})) return frep end function function frep_to_greg(string frep) integer day, month, year string months, days if frep[1]<='9' then {day, months, year} = scanf(frep,"%d %s %d")[1] month = find(months,republicans) else {days, year} = scanf(frep,"%s %d")[1] day = find(days,sansculottides) month = 13 end if {day,month,year} = day_to_gre(rep_to_day({day, month, year})) string greg = sprintf("%02d %s %d",{day, gregorians[month], year}) return greg end function constant test_data = { { "22 September 1792", "1 Vendémiaire 1" }, { "20 May 1795", "1 Prairial 3" }, { "15 July 1799", "27 Messidor 7" }, { "23 September 1803", "Fête de la Révolution 11" }, { "31 December 1805", "10 Nivôse 14" }, { "18 March 1871", "27 Ventôse 79" }, { "25 August 1944", "7 Fructidor 152" }, { "19 September 2016", "Fête du travail 224" }, { "06 May 1871", "16 Floréal 79" }, -- Paris Commune begins { "23 May 1871", "3 Prairial 79" }, -- Paris Commune ends { "09 November 1799", "18 Brumaire 8" }, -- Revolution ends by Napoléon coup { "02 December 1804", "11 Frimaire 13" }, -- Republic ends by Napoléon coronation { "30 October 1794", "9 Brumaire 3" }, -- École Normale Supérieure established { "27 July 1794", "9 Thermidor 2" }, -- Robespierre falls { "27 May 1799", "8 Prairial 7" }, -- Fromental Halévy born { "22 September 1792", "1 Vendémiaire 1" }, { "22 September 1793", "1 Vendémiaire 2" }, { "22 September 1794", "1 Vendémiaire 3" }, { "23 September 1795", "1 Vendémiaire 4" }, { "22 September 1796", "1 Vendémiaire 5" }, { "22 September 1797", "1 Vendémiaire 6" }, { "22 September 1798", "1 Vendémiaire 7" }, { "23 September 1799", "1 Vendémiaire 8" }, { "23 September 1800", "1 Vendémiaire 9" }, { "23 September 1801", "1 Vendémiaire 10" }, { "23 September 1802", "1 Vendémiaire 11" }, { "24 September 1803", "1 Vendémiaire 12" }, { "23 September 1804", "1 Vendémiaire 13" }, { "23 September 1805", "1 Vendémiaire 14" }, { "23 September 1806", "1 Vendémiaire 15" }, { "24 September 1807", "1 Vendémiaire 16" }, { "23 September 1808", "1 Vendémiaire 17" }, { "23 September 1809", "1 Vendémiaire 18" }, { "23 September 1810", "1 Vendémiaire 19" }, { "24 September 1811", "1 Vendémiaire 20" }, { "23 September 2015", "1 Vendémiaire 224" }, { "21 September 2016", "Fête des récompenses 224" }, { "22 September 2016", "1 Vendémiaire 225" }, { "23 September 2016", "2 Vendémiaire 225" }, { "22 September 2017", "1 Vendémiaire 226" }, { "28 September 2017", "7 Vendémiaire 226" } } for i=1 to length(test_data) do string {greg, frep} = test_data[i], frep2 = greg_to_frep(greg), greg2 = frep_to_greg(frep), ok = iff(frep=frep2 and greg=greg2?"ok":"**** ERROR ****") if platform()=WINDOWS then -- the windows console does not handle -- non-basic-latin-ascii characters well... frep = substitute_all(frep,"éêéô","eeeo") end if printf(1,"%18s <==> %-25s %s\n",{greg,frep,ok}) end for --sanity test: for i=1 to 150000 do -- (years 1792..~2203) if rep_to_day(day_to_rep(i))!=i then ?9/0 end if if gre_to_day(day_to_gre(i))!=i then ?9/0 end if end for
- Output:
22 September 1792 <==> 1 Vendemiaire 1 ok 20 May 1795 <==> 1 Prairial 3 ok 15 July 1799 <==> 27 Messidor 7 ok 23 September 1803 <==> Fete de la Revolution 11 ok 31 December 1805 <==> 10 Nivose 14 ok 18 March 1871 <==> 27 Ventose 79 ok 25 August 1944 <==> 7 Fructidor 152 ok 19 September 2016 <==> Fete du travail 224 ok 06 May 1871 <==> 16 Floreal 79 ok 23 May 1871 <==> 3 Prairial 79 ok 09 November 1799 <==> 18 Brumaire 8 ok 02 December 1804 <==> 11 Frimaire 13 ok 30 October 1794 <==> 9 Brumaire 3 ok 27 July 1794 <==> 9 Thermidor 2 ok 27 May 1799 <==> 8 Prairial 7 ok 22 September 1792 <==> 1 Vendemiaire 1 ok 22 September 1793 <==> 1 Vendemiaire 2 ok 22 September 1794 <==> 1 Vendemiaire 3 ok 23 September 1795 <==> 1 Vendemiaire 4 ok 22 September 1796 <==> 1 Vendemiaire 5 ok 22 September 1797 <==> 1 Vendemiaire 6 ok 22 September 1798 <==> 1 Vendemiaire 7 ok 23 September 1799 <==> 1 Vendemiaire 8 ok 23 September 1800 <==> 1 Vendemiaire 9 ok 23 September 1801 <==> 1 Vendemiaire 10 ok 23 September 1802 <==> 1 Vendemiaire 11 ok 24 September 1803 <==> 1 Vendemiaire 12 ok 23 September 1804 <==> 1 Vendemiaire 13 ok 23 September 1805 <==> 1 Vendemiaire 14 ok 23 September 1806 <==> 1 Vendemiaire 15 ok 24 September 1807 <==> 1 Vendemiaire 16 ok 23 September 1808 <==> 1 Vendemiaire 17 ok 23 September 1809 <==> 1 Vendemiaire 18 ok 23 September 1810 <==> 1 Vendemiaire 19 ok 24 September 1811 <==> 1 Vendemiaire 20 ok 23 September 2015 <==> 1 Vendemiaire 224 ok 21 September 2016 <==> Fete des recompenses 224 ok 22 September 2016 <==> 1 Vendemiaire 225 ok 23 September 2016 <==> 2 Vendemiaire 225 ok 22 September 2017 <==> 1 Vendemiaire 226 ok 28 September 2017 <==> 7 Vendemiaire 226 ok
Raku
(formerly Perl 6) <lang perl6>use v6; constant @month_names = <
Vendémiaire Brumaire Frimaire Nivôse Pluviôse Ventôse Germinal Floréal Prairial Messidor Thermidor Fructidor
>; constant @intercalary =
'Fête de la vertu', 'Fête du génie', 'Fête du travail', "Fête de l'opinion", 'Fête des récompenses', 'Fête de la Révolution',
constant %month_nums = %( @month_names Z=> 1..12 ); constant %i_cal_nums = %( @intercalary Z=> 1.. 6 ); constant $i_cal_month = 13; constant $epoch = Date.new: '1792-09-22';
sub is_republican_leap_year ( Int:D $year --> Bool ) {
my $y := $year + 1; return ?( $y %% 4 and ($y !%% 100 or $y %% 400) );
}
sub Republican_to_Gregorian ( Str:D $rep_date --> Date ) {
grammar Republican_date_text { token day { \d+ } token year { \d+ } token ic { @intercalary } token month { @month_names } rule TOP { ^ [ <ic> | <day> <month> ] <year> $ } } Republican_date_text.parse($rep_date) orelse die "Republican date not recognized: '$rep_date'";
my $day1 := $/<ic> ?? %i_cal_nums{~$/<ic>} !! +$/<day>; my $month1 := $/<month> ?? %month_nums{~$/<month>} !! $i_cal_month;
my @ymd0 := ($/<year>, $month1, $day1) »-» 1; my $days_since_epoch := [+] @ymd0 Z* (365, 30, 1);
my $leap_days := +grep &is_republican_leap_year, 1 ..^ $/<year>; return $epoch + $days_since_epoch + $leap_days;
}
sub Gregorian_to_Republican ( Date:D $greg_date --> Str ) {
my $days_since_epoch := $greg_date - $epoch; die if $days_since_epoch < 0;
my ( $year, $days ) = 1, $days_since_epoch; loop { my $year_length = 365 + (1 if $year.&is_republican_leap_year); last if $days < $year_length; $days -= $year_length; $year += 1; }
my ( $day0, $month0 ) = $days.polymod( 30 ); my ( $day1, $month1 ) = ($day0, $month0) X+ 1;
return $month1 == $i_cal_month ?? "@intercalary[$day0 ] $year" !! "$day1 @month_names[$month0] $year";
}
my @test_data =
( '1792-09-22', '1 Vendémiaire 1' ), ( '1795-05-20', '1 Prairial 3' ), ( '1799-07-15', '27 Messidor 7' ), ( '1803-09-23', 'Fête de la Révolution 11' ), ( '1805-12-31', '10 Nivôse 14' ),
( '1871-03-18', '27 Ventôse 79' ), ( '1944-08-25', '7 Fructidor 152' ), ( '2016-09-19', 'Fête du travail 224' ),
( '1871-05-06', '16 Floréal 79' ), # Paris Commune begins ( '1871-05-23', '3 Prairial 79' ), # Paris Commune ends ( '1799-11-09', '18 Brumaire 8' ), # Revolution ends by Napoléon coup ( '1804-12-02', '11 Frimaire 13' ), # Republic ends by Napoléon coronation ( '1794-10-30', '9 Brumaire 3' ), # École Normale Supérieure established ( '1794-07-27', '9 Thermidor 2' ), # Robespierre falls ( '1799-05-27', '8 Prairial 7' ), # Fromental Halévy born
( '1792-09-22', '1 Vendémiaire 1' ), ( '1793-09-22', '1 Vendémiaire 2' ), ( '1794-09-22', '1 Vendémiaire 3' ), ( '1795-09-23', '1 Vendémiaire 4' ), ( '1796-09-22', '1 Vendémiaire 5' ), ( '1797-09-22', '1 Vendémiaire 6' ), ( '1798-09-22', '1 Vendémiaire 7' ), ( '1799-09-23', '1 Vendémiaire 8' ), ( '1800-09-23', '1 Vendémiaire 9' ), ( '1801-09-23', '1 Vendémiaire 10' ), ( '1802-09-23', '1 Vendémiaire 11' ), ( '1803-09-24', '1 Vendémiaire 12' ), ( '1804-09-23', '1 Vendémiaire 13' ), ( '1805-09-23', '1 Vendémiaire 14' ), ( '1806-09-23', '1 Vendémiaire 15' ), ( '1807-09-24', '1 Vendémiaire 16' ), ( '1808-09-23', '1 Vendémiaire 17' ), ( '1809-09-23', '1 Vendémiaire 18' ), ( '1810-09-23', '1 Vendémiaire 19' ), ( '1811-09-24', '1 Vendémiaire 20' ), ( '2015-09-23', '1 Vendémiaire 224' ), ( '2016-09-22', '1 Vendémiaire 225' ), ( '2017-09-22', '1 Vendémiaire 226' ),
for @test_data -> ( $g_text, $r ) {
my $g = Date.new: $g_text;
die if Republican_to_Gregorian($r) != $g or Gregorian_to_Republican($g) ne $r;
die if Gregorian_to_Republican(Republican_to_Gregorian($r)) ne $r or Republican_to_Gregorian(Gregorian_to_Republican($g)) != $g;
} say 'All tests successful.';</lang>
- Output:
All tests successful.
Sidef
<lang ruby>require('DateTime')
var month_names = %w(
Vendémiaire Brumaire Frimaire Nivôse Pluviôse Ventôse Germinal Floréal Prairial Messidor Thermidor Fructidor
)
var intercalary = [
'Fête de la vertu', 'Fête du génie', 'Fête du travail', "Fête de l'opinion", 'Fête des récompenses', 'Fête de la Révolution', ]
var i_cal_month = 13 var epoch = %O<DateTime>.new(year => 1792, month => 9, day => 22)
var month_nums = Hash(month_names.kv.map {|p| [p[1], p[0]+1] }.flat...) var i_cal_nums = Hash(intercalary.kv.map {|p| [p[1], p[0]+1] }.flat...)
func is_republican_leap_year(Number year) -> Bool {
var y = (year + 1) !!(4.divides(y) && (!100.divides(y) || 400.divides(y)))
}
func Republican_to_Gregorian(String rep_date) -> String {
static months = month_names.map { .escape }.join('|') static intercal = intercalary.map { .escape }.join('|') static re = Regex("^ \\s* (?: (?<ic> #{intercal}) | (?<day> \\d+) \\s+ (?<month> #{months}) ) \\s+ (?<year> \\d+) \\s* \\z", 'x')
var m = (rep_date =~ re) m || die "Republican date not recognized: '#{rep_date}'"
var ncap = m.named_captures
var day1 = Number(ncap{:ic} ? i_cal_nums{ncap{:ic}} : ncap{:day}) var month1 = Number(ncap{:month} ? month_nums{ncap{:month}} : i_cal_month) var year1 = Number(ncap{:year})
var days_since_epoch = (365*(year1 - 1) + 30*(month1 - 1) + (day1 - 1))
var leap_days = (1 ..^ year1 -> grep { is_republican_leap_year(_) }) epoch.clone.add(days => (days_since_epoch + leap_days)).strftime("%Y-%m-%d")
}
func Gregorian_to_Republican(String greg_date) -> String {
var m = (greg_date =~ /^(\d{4})-(\d{2})-(\d{2})\z/) m || die "Gregorian date not recognized: '#{greg_date}'"
var g = %O<DateTime>.new(year => m[0], month => m[1], day => m[2]) var days_since_epoch = epoch.delta_days(g).in_units('days') days_since_epoch < 0 && die "unexpected error" var (year, days) = (1, days_since_epoch)
loop { var year_length = (365 + (is_republican_leap_year(year) ? 1 : 0)) days < year_length && break days -= year_length year += 1; }
var day0 = (days % 30) var month0 = (days - day0)/30
var (day1, month1) = (day0 + 1, month0 + 1)
(month1 == i_cal_month ? "#{intercalary[day0]} #{year}" : "#{day1} #{month_names[month0]} #{year}")
}
for line in DATA {
line.sub!(/\s*\#.+\R?\z/, )
var m = (line =~ /^(\d{4})-(\d{2})-(\d{2})\s+(\S.+?\S)\s*$/) m || die "error for: #{line.dump}"
var g = "#{m[0]}-#{m[1]}-#{m[2]}" var r = m[3]
var r2g = Republican_to_Gregorian(r) var g2r = Gregorian_to_Republican(g)
#say "#{r} -> #{r2g}" #say "#{g} -> #{g2r}"
if ((g2r != r) || (r2g != g)) { die "1-way error" }
if ((Gregorian_to_Republican(r2g) != r) || (Republican_to_Gregorian(g2r) != g) ) { die "2-way error" }
}
say 'All tests successful.'
__DATA__ 1792-09-22 1 Vendémiaire 1 1795-05-20 1 Prairial 3 1799-07-15 27 Messidor 7 1803-09-23 Fête de la Révolution 11 1805-12-31 10 Nivôse 14 1871-03-18 27 Ventôse 79 1944-08-25 7 Fructidor 152 2016-09-19 Fête du travail 224 1871-05-06 16 Floréal 79 # Paris Commune begins 1871-05-23 3 Prairial 79 # Paris Commune ends 1799-11-09 18 Brumaire 8 # Revolution ends by Napoléon coup 1804-12-02 11 Frimaire 13 # Republic ends by Napoléon coronation 1794-10-30 9 Brumaire 3 # École Normale Supérieure established 1794-07-27 9 Thermidor 2 # Robespierre falls 1799-05-27 8 Prairial 7 # Fromental Halévy born 1792-09-22 1 Vendémiaire 1 1793-09-22 1 Vendémiaire 2 1794-09-22 1 Vendémiaire 3 1795-09-23 1 Vendémiaire 4 1796-09-22 1 Vendémiaire 5 1797-09-22 1 Vendémiaire 6 1798-09-22 1 Vendémiaire 7 1799-09-23 1 Vendémiaire 8 1800-09-23 1 Vendémiaire 9 1801-09-23 1 Vendémiaire 10 1802-09-23 1 Vendémiaire 11 1803-09-24 1 Vendémiaire 12 1804-09-23 1 Vendémiaire 13 1805-09-23 1 Vendémiaire 14 1806-09-23 1 Vendémiaire 15 1807-09-24 1 Vendémiaire 16 1808-09-23 1 Vendémiaire 17 1809-09-23 1 Vendémiaire 18 1810-09-23 1 Vendémiaire 19 1811-09-24 1 Vendémiaire 20 2015-09-23 1 Vendémiaire 224 2016-09-22 1 Vendémiaire 225 2017-09-22 1 Vendémiaire 226</lang>
- Output:
All tests successful.
Wren
<lang ecmascript>import "/date" for Date import "/seq" for Lst import "/fmt" for Fmt
class FrenchRCDate {
/* uses the 'continuous method' for years after 1805 */ static isLeapYear(y) { var yy = y + 1 return (yy % 4 == 0) && (yy % 100 != 0 || yy % 400 == 0) }
static parse(frcDate) { var splits = frcDate.trim().split(" ") if (splits.count == 3) { var month = Lst.indexOf(months, splits[1]) + 1 if (month < 1 || month > 13) Fiber.abort("Invalid month.") var year = Num.fromString(splits[2]) if (year < 1) Fiber.abort("Invalid year.") var monthLength = (month < 13) ? 30 : (isLeapYear(year) ? 6 : 5) var day = Num.fromString(splits[0]) if (day < 1 || day > monthLength) Fiber.abort("Invalid day.") return FrenchRCDate.new(year, month, day) } else if (splits.count == 4 || splits.count == 5) { var yearStr = splits[-1] var year = Num.fromString(yearStr) if (year < 1) Fiber.abort("Invalid year.") var scDay = frcDate.trim()[0...-(yearStr.count + 1)] var day = Lst.indexOf(intercal, scDay) + 1 var maxDay = isLeapYear(year) ? 6 : 5 if (day < 1 || day > maxDay) Fiber.abort("Invalid day.") return FrenchRCDate.new(year, 13, day) } else Fiber.abort("Invalid French Republican date.") }
/* for convenience we treat 'Sansculottide' as an extra month with 5 or 6 days */ static months { return ["Vendémiaire", "Brumaire", "Frimaire", "Nivôse", "Pluviôse", "Ventôse", "Germinal", "Floréal", "Prairial", "Messidor", "Thermidor", "Fructidor", "Sansculottide"] }
static intercal { return ["Fête de la vertu", "Fête du génie", "Fête du travail", "Fête de l'opinion", "Fête des récompenses", "Fête de la Révolution"] }
static introductionDate { Date.new(1792, 9, 22) }
/* year = 1.. month = 1..13 day = 1..30 */ construct new(year, month, day) { if (year <= 0 || month < 1 || month > 13) Fiber.abort("Invalid date.") if (month < 13) { if (day < 1 || day > 30) Fiber.abort("Invalid date.") } else { var leap = FrenchRCDate.isLeapYear(year) if (leap && (day < 1 || day > 6)) Fiber.abort("Invalid date.") if (!leap && (day < 1 || day > 5)) Fiber.abort("Invalid date.") } _year = year _month = month _day = day }
static fromLocalDate(ldate) { var daysDiff = (ldate - introductionDate).days + 1 if (daysDiff <= 0) Fiber.abort("Date can't be before 22 September 1792.") var year = 1 var startDay = 1 while (true) { var endDay = startDay + (isLeapYear(year) ? 365 : 364) if (daysDiff >= startDay && daysDiff <= endDay) break year = year + 1 startDay = endDay + 1 } var remDays = daysDiff - startDay var month = (remDays / 30).floor var day = remDays - month * 30 return FrenchRCDate.new(year, month + 1, day + 1) }
toString { if (_month < 13) return "%(_day) %(FrenchRCDate.months[_month - 1]) %(_year)" return "%(FrenchRCDate.intercal[_day - 1]) %(_year)" }
toLocalDate { var sumDays = 0 for (i in 1..._year) sumDays = sumDays + (FrenchRCDate.isLeapYear(i) ? 366 : 365) var dayInYear = (_month - 1) * 30 + _day - 1 return FrenchRCDate.introductionDate.addDays(sumDays + dayInYear) }
}
var fmt = "d| |mmmm| |yyyy" var dates = [
"22 September 1792", "20 May 1795", "15 July 1799", "23 September 1803", "31 December 1805", "18 March 1871", "25 August 1944", "19 September 2016", "22 September 2017", "28 September 2017"
] var frcDates = List.filled(dates.count, null) var i = 0 for (date in dates) {
var thisDate = Date.parse(date, fmt) var frcd = FrenchRCDate.fromLocalDate(thisDate) frcDates[i] = frcd.toString Fmt.print("$-25s => $s", date, frcd) i = i + 1
}
// now process the other way around System.print() for (frcDate in frcDates) {
var thisDate = FrenchRCDate.parse(frcDate) var lds = thisDate.toLocalDate.format(fmt) Fmt.print("$-25s => $s", frcDate, lds)
}</lang>
- Output:
22 September 1792 => 1 Vendémiaire 1 20 May 1795 => 1 Prairial 3 15 July 1799 => 27 Messidor 7 23 September 1803 => Fête de la Révolution 11 31 December 1805 => 10 Nivôse 14 18 March 1871 => 27 Ventôse 79 25 August 1944 => 7 Fructidor 152 19 September 2016 => Fête du travail 224 22 September 2017 => 1 Vendémiaire 226 28 September 2017 => 7 Vendémiaire 226 1 Vendémiaire 1 => 22 September 1792 1 Prairial 3 => 20 May 1795 27 Messidor 7 => 15 July 1799 Fête de la Révolution 11 => 23 September 1803 10 Nivôse 14 => 31 December 1805 27 Ventôse 79 => 18 March 1871 7 Fructidor 152 => 25 August 1944 Fête du travail 224 => 19 September 2016 1 Vendémiaire 226 => 22 September 2017 7 Vendémiaire 226 => 28 September 2017