170 lines
16 KiB
HTML
170 lines
16 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Time</title>
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
<nav role="navigation">
|
|
<h1><a href="../webs.html">Sources</a></h1>
|
|
<ul>
|
|
<li><a href="../inweb/index.html">inweb</a></li>
|
|
</ul>
|
|
<h2>Foundation</h2>
|
|
<ul>
|
|
<li><a href="../foundation-module/index.html">foundation-module</a></li>
|
|
<li><a href="../foundation-test/index.html">foundation-test</a></li>
|
|
</ul>
|
|
|
|
|
|
</nav>
|
|
<main role="main">
|
|
|
|
<!--Weave of 'Time' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="index.html">foundation</a></li><li><a href="index.html#3">Chapter 3: The Operating System</a></li><li><b>Time</b></li></ul><p class="purpose">Managing how we record and use the current time and date.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Clock</a></li><li><a href="#SP3">§3. Calendrical</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Clock. </b>From the local environment, we'll extract the time at which we're running.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">right_now</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">tm</span><span class="plain"> *</span><span class="identifier">the_present</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">fix_time_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Time::begin</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">right_now</span><span class="plain"> = </span><span class="identifier">time</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">the_present</span><span class="plain"> = </span><span class="identifier">localtime</span><span class="plain">(&</span><span class="identifier">right_now</span><span class="plain">);</span>
|
|
<span class="identifier">fix_time_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Time::begin is used in 1/fm (<a href="1-fm.html#SP8">§8</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b>The command line option <code class="display"><span class="extract">-fixtime</span></code> causes any tool compiled with Foundation
|
|
to fix the date as 11 a.m. on 28 March 2016, which is Inform's birthday. This
|
|
makes it easier to automate testing, since we can compare output generated
|
|
in one session with output generated another, even though that was on two
|
|
different dates.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Time::fix</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">tm</span><span class="plain"> </span><span class="identifier">start</span><span class="plain">;</span>
|
|
<span class="identifier">start</span><span class="plain">.</span><span class="identifier">tm_sec</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">start</span><span class="plain">.</span><span class="identifier">tm_min</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">start</span><span class="plain">.</span><span class="identifier">tm_hour</span><span class="plain"> = </span><span class="constant">11</span><span class="plain">;</span>
|
|
<span class="identifier">start</span><span class="plain">.</span><span class="identifier">tm_mday</span><span class="plain"> = </span><span class="constant">28</span><span class="plain">; </span><span class="identifier">start</span><span class="plain">.</span><span class="identifier">tm_mon</span><span class="plain"> = </span><span class="constant">3</span><span class="plain">; </span><span class="identifier">start</span><span class="plain">.</span><span class="identifier">tm_year</span><span class="plain"> = </span><span class="constant">116</span><span class="plain">; </span><span class="identifier">start</span><span class="plain">.</span><span class="identifier">tm_isdst</span><span class="plain"> = -1;</span>
|
|
<span class="identifier">time_t</span><span class="plain"> </span><span class="identifier">pretend_time</span><span class="plain"> = </span><span class="identifier">mktime</span><span class="plain">(&</span><span class="identifier">start</span><span class="plain">);</span>
|
|
<span class="identifier">the_present</span><span class="plain"> = </span><span class="identifier">localtime</span><span class="plain">(&</span><span class="identifier">pretend_time</span><span class="plain">);</span>
|
|
<span class="identifier">fix_time_mode</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Time::fixed</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">fix_time_mode</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Time::fix is used in 3/cla (<a href="3-cla.html#SP13_1">§13.1</a>).</p>
|
|
|
|
<p class="endnote">The function Time::fixed appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. Calendrical. </b>The date of Easter depends on who and where you are. Inform's notional home
|
|
is England. Following League of Nations advice in 1926, Easter is legally
|
|
celebrated in England on the Sunday after the second Saturday in April, unless
|
|
the Church requests otherwise. Since the Church has made this request every
|
|
year since 1926 and shows no sign of coming around, we instead have to turn to
|
|
church law, which is where it becomes complicated. There are five main
|
|
algorithms ordained by major Christian churches: Catholic, continental
|
|
European Protestant, Church of England, Eastern and Russian Orthodox. The
|
|
first three always agree on the date, but usually disagree with the last
|
|
two. The two eastern algorithms only disagree with each other once or twice
|
|
a century, but the usual result has been riots with significant loss of life.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The official Church of England algorithm is a clumsy one adopted during the
|
|
reign of George II. It was then thought important to use a non-Catholic
|
|
method of calculation even though the same answer was required. We'll
|
|
instead follow the algorithm of J.-M. Oudin, first published in the
|
|
Bulletin astronomique in 1940, as adapted by the US Naval Observatory.
|
|
Oudin corrected a small mistake in the calculation by Gauss (1800) of the
|
|
Allgemeiner Reichskalender (1776) which reconciled Lutheran Easter with
|
|
Gregorian, which in turn followed the reforms of Clavius et al. (1582),
|
|
which in turn... and so on. See Leofranc Holford-Strevens, "The History of
|
|
Time" (Oxford, 2005).
|
|
</p>
|
|
|
|
<p class="inwebparagraph">In principle we calculate the first Sunday after the first ecclesiastical
|
|
moon that occurs on or after March 21. An "ecclesiastical moon" is one as
|
|
seen from a longitude near Rome, except that the ratios used to adjust lunar and
|
|
solar calendars are not quite right. The result is also tampered with to
|
|
stop Easter from coinciding with the pagan anniversary of the founding of
|
|
Rome (for the convenience of people living in the Vatican) and also to
|
|
stop it from coinciding with the Jewish Passover (a change motivated purely
|
|
by anti-Semitism). However, since they botched this tampering, it sometimes
|
|
does.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Knuth remarks that calculating Easter was almost the only algorithmic
|
|
research in the West for many centuries. Nevertheless the result is
|
|
practically a random-number generator. The one thing to be said in its
|
|
favour is that it can be computed accurately with integer arithmetic using
|
|
fairly low numbers, and this we now do.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">CHRISTMAS_FEAST</span><span class="plain"> </span><span class="constant">1</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">EASTER_FEAST</span><span class="plain"> </span><span class="constant">2</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">NON_FEAST</span><span class="plain"> </span><span class="constant">3</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Time::feast</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">this_month</span><span class="plain"> = </span><span class="identifier">the_present</span><span class="plain">-></span><span class="identifier">tm_mon</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">this_day</span><span class="plain"> = </span><span class="identifier">the_present</span><span class="plain">-></span><span class="identifier">tm_mday</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">this_year</span><span class="plain"> = </span><span class="identifier">the_present</span><span class="plain">-></span><span class="identifier">tm_year</span><span class="plain"> + </span><span class="constant">1900</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain">, </span><span class="identifier">y</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">n</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">l</span><span class="plain">, </span><span class="identifier">m</span><span class="plain">, </span><span class="identifier">d</span><span class="plain">;</span>
|
|
<span class="identifier">y</span><span class="plain"> = </span><span class="identifier">this_year</span><span class="plain">;</span>
|
|
<span class="identifier">c</span><span class="plain"> = </span><span class="identifier">y</span><span class="plain">/100;</span>
|
|
<span class="identifier">n</span><span class="plain"> = </span><span class="identifier">y</span><span class="plain">-19*(</span><span class="identifier">y</span><span class="plain">/19);</span>
|
|
<span class="identifier">k</span><span class="plain"> = (</span><span class="identifier">c</span><span class="plain">-17)/25;</span>
|
|
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">c</span><span class="plain">-</span><span class="identifier">c</span><span class="plain">/4-(</span><span class="identifier">c</span><span class="plain">-</span><span class="identifier">k</span><span class="plain">)/3+19*</span><span class="identifier">n</span><span class="plain">+15;</span>
|
|
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">-30*(</span><span class="identifier">i</span><span class="plain">/30);</span>
|
|
<span class="identifier">i</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">-(</span><span class="identifier">i</span><span class="plain">/28)*(1-(</span><span class="identifier">i</span><span class="plain">/28)*(29/(</span><span class="identifier">i</span><span class="plain">+1))*((21-</span><span class="identifier">n</span><span class="plain">)/11));</span>
|
|
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">y</span><span class="plain">+</span><span class="identifier">y</span><span class="plain">/4+</span><span class="identifier">i</span><span class="plain">+2-</span><span class="identifier">c</span><span class="plain">+</span><span class="identifier">c</span><span class="plain">/4;</span>
|
|
<span class="identifier">j</span><span class="plain"> = </span><span class="identifier">j</span><span class="plain">-7*(</span><span class="identifier">j</span><span class="plain">/7);</span>
|
|
<span class="identifier">l</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">-</span><span class="identifier">j</span><span class="plain">;</span>
|
|
<span class="identifier">m</span><span class="plain"> = </span><span class="constant">3</span><span class="plain">+(</span><span class="identifier">l</span><span class="plain">+40)/44;</span>
|
|
<span class="identifier">d</span><span class="plain"> = </span><span class="identifier">l</span><span class="plain">+28-31*(</span><span class="identifier">m</span><span class="plain">/4);</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">this_month</span><span class="plain"> == </span><span class="identifier">m</span><span class="plain">) && (</span><span class="identifier">this_day</span><span class="plain"> >= </span><span class="identifier">d</span><span class="plain">-2) && (</span><span class="identifier">this_day</span><span class="plain"> <= </span><span class="identifier">d</span><span class="plain">+1))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="constant">EASTER_FEAST</span><span class="plain">; </span><span class="comment"> that is, Good Friday to Easter Monday</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">this_year</span><span class="plain"> == </span><span class="constant">2018</span><span class="plain">) && (</span><span class="identifier">this_month</span><span class="plain"> == </span><span class="constant">3</span><span class="plain">) && (</span><span class="identifier">this_day</span><span class="plain"> >= </span><span class="constant">30</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="constant">EASTER_FEAST</span><span class="plain">; </span><span class="comment"> Easter Sunday falls on 1 April in 2018</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">this_month</span><span class="plain"> == </span><span class="constant">12</span><span class="plain">) && (</span><span class="identifier">this_day</span><span class="plain"> >= </span><span class="constant">25</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="constant">CHRISTMAS_FEAST</span><span class="plain">; </span><span class="comment"> that is, Christmas Day to New Year's Eve</span>
|
|
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="constant">NON_FEAST</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Time::feast appears nowhere else.</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="3-drc.html">Back to 'Directories'</a></li><li><i>(This section ends Chapter 3: The Operating System.)</i></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|