<html> <head> <title> :: phodd.net :: Magic Microfortnights :: </title> <script><!-- function fill0(number, width){ var numlen = Math.floor(number).toString().length; for(var i=numlen;i<width;i++) number = (0).toString() + "" + number; return number; } // Global offset object for this form. //// With this, the autoupdater can run from the day and time the form shows, //// and so not have to default to the current time. var offsetFromNow = 0; function calculateFormOffsetFromRealDayAndTimeInMs() { var formDate, pageNow; // Store the form's info in the page's global Date object defined above formDate = new Date(); pageNow = new Date(formDate); // copy formDate.setDate( formDate.getDate() - formDate.getDay() + 1 * document.f.d.value + 1); // + 1 because the mfClock says 0 = Monday, while Javascript needs 0 (or 7) = Sunday formDate.setHours( document.f.h.value); formDate.setMinutes( document.f.m.value); formDate.setSeconds( document.f.s.value); formDate.setMilliseconds( document.f.ms.value); offsetFromNow = formDate - pageNow; } var weekDays = new Array("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"); function godate(onchanger) { var s, mf; var mfd, mfdl, mfq, mfh, mfm, mfs; // Every time form is update manually... if (onchanger) calculateFormOffsetFromRealDayAndTimeInMs(); // Calculate number of seconds into form-specified week s = document.f.d.value * 86400 + document.f.h.value * 3600 + document.f.m.value * 60 + document.f.s.value * 1 + document.f.ms.value / 1000; mf = s / 1.2096; // Find which 'day' of the mfweek it is; these do not correspond exactly to the usual day of the week // also find mf time for the mfday //// Assumes pattern of 71428 per day, plus one for tue, thu, sat and sun ////// sunday does not need to be catered for here because it is the 'last' day of the week ////// and so the full number of mf in a week never needs to be subtracted for(mfd=0;mfd<6;mfd++){ mfdl = 71428 + (mfd % 2); if (mf >= mfdl) mf -= mfdl; else break; } // find the quarter of the day we are in //// an internal leap mf is added at the end of each 1/4 day mfq = Math.floor(mf / 17857); if (mfq > 3) mfq = 3; // 0123 // leap seconds would cause an apparent 5th quarter to happen // find which 'hour' of the quarter we're in mf -= mfq * 17857; mfh = Math.floor(mf / 2976); if (mfh > 5) mfh = 5; // 012345 // there is a leap second at the end of each quarter that would cause an apparent 7th 'hour' to happen // find which 'minute' of the 'hour' we're in mf -= mfh * 2976; mfm = Math.floor(mf / 48); if (mfm > 61) mfm = 61 // 0..61 // leap seconds would make an apparent 63rd 'minute' in an hour // find the remaining number of mf's mf -= mfm * 48; mfs = Math.floor(mf*100)/100; // combine the quarter and the 'hour' into a 24-'hour' designation mfh += mfq * 6; document.f.t.value = "f" + weekDays[mfd] + " @ " + fill0(mfh,2) + ":" + fill0(mfm,2) + ":" + fill0(mfs,2) goApproxDate() } function goApproxDate() { var mfd, mfh, mfm, mfs; mfd = document.f.d.value; mfh = document.f.h.value; mfs = ( document.f.m.value * 60 + document.f.s.value * 1 + document.f.ms.value / 1000 ) * 2975.19 / 3599.07; mfm = Math.floor(mfs / 48); mfs -= 48 * mfm mfs = Math.floor(mfs*100)/100; document.f.t2.value = "f" + weekDays[mfd] + " @ " + fill0(mfh,2) + ":" + fill0(mfm,2) + ":" + fill0(mfs,2) } function setFormTime(){ var D = new Date(); if (arguments.length) offsetFromNow = 0; D.setMilliseconds(D.getMilliseconds() + offsetFromNow); document.f.d[(D.getDay()+6)%7].selected = document.f.h[ D.getHours() ].selected = document.f.m[ D.getMinutes() ].selected = document.f.s[ D.getSeconds() ].selected = document.f.ms[ Math.floor(D.getMilliseconds()/25) ].selected = true; } var autoTickTimeoutID, autoTickGranularity = 1209.6; function autoTick() { setFormTime();godate(0); } function toggleAutoTick() { if(document.f.toggle.value == "Start"){ calculateFormOffsetFromRealDayAndTimeInMs(); autoTickTimeoutID = setInterval(autoTick, autoTickGranularity); document.f.toggle.value = "Stop"; } else { clearInterval(autoTickTimeoutID); document.f.toggle.value = "Start"; } } function setAutoTickGranularity() { autoTickGranularity = document.f.aTgran.value; if(document.f.toggle.value == "Stop"){ clearInterval(autoTickTimeoutID); autoTickTimeoutID = setInterval(autoTick, autoTickGranularity); } } //--> </script> <style><!-- body { background: #ffffff url('fades/phlue.png') repeat-x top left; font-family: Verdana, Arial, Helvetica, Sans-Serif; font-size: 12px; } h1 { font-size: 22px; } .clockformcontainer { background-color: #eff8ff; color: #003060; border-left: solid 1px #3050b0; border-top: solid 1px #3050b0; border-right: solid 2px #2040a0; border-bottom: solid 2px #2040a0; width: 35em; height: 18em; position: absolute; top: 50%; left: 50%; margin-top: -9em; margin-left: -17.5em; padding: 0.25em; } .clockformcontainer h1 { margin-top: 0.1em; margin-bottom: 0.1em; text-align: right; font-style: italic; } .clockformcontainer h1 a { cursor: help; } .clockformcontainer .hint { float: right; font-size: 8px; color: #7794af; cursor: pointer; } .clockformcontainer dd { margin-bottom: 0.5em; } .clockformtextbox { font-family: monospace; width: 80%; } .granMfOption { background-color: #e8f4ff; } .granSecOption { } .helpcontainer { background-color: #eff8ff; color: #003060; border-left: solid 1px #3050b0; border-top: solid 1px #3050b0; border-right: solid 2px #2040a0; border-bottom: solid 2px #2040a0; width: 52.5em; height: 32em; position: absolute; top: 25em; left: 50%; margin-top: 0em; margin-left: -26.25em; padding: 0.25em; visibility: hidden; overflow-y: scroll; } .helpcontainer h1 { margin-top: 1px; } .nobr { white-space: nowrap; } --></style> <script><!-- Style Script var helpIsVisible = false; function hideHint() { document.getElementById("hint").style.visibility="hidden"; } function showHelp() { // The hint only needs to be shown until the user gets the idea hideHint(); if(! helpIsVisible) { document.getElementById("clock").style.top="13em"; document.getElementById("clockhelp").style.visibility="visible"; helpIsVisible = true; } else { document.getElementById("clock").style.top="50%"; document.getElementById("clockhelp").style.visibility="hidden"; helpIsVisible = false; } } //--> </script> </head> <body> <div id="clock" class="clockformcontainer"> <h1> <a name="" onClick="showHelp();" title="Show/hide the Infobox"> --- Microfortnight Clock - </a> </h1> <div id="hint" class="hint" onClick="hideHint();" title="Click to get rid of me!">[click the title for more info]</div> <form name="f" method="post" action=""><dl> <dt>Autoupdater: <dd><input type=button name="toggle" onClick="toggleAutoTick();" value="Start" > &nbsp;&nbsp;&nbsp;&nbsp;Granularity:<select name="aTgran" onChange="setAutoTickGranularity();"> <option value= "1.00" class="granMfOption" > As fast as possible <option value= "62.50" class="granSecOption"> 1/16 of a second <option value= "75.60" class="granMfOption" > 1/16 of a microfortnight <option value= "100.00" class="granSecOption"> 1/10 of a second <option value= "120.96" class="granMfOption" > 1/10 of a microfortnight <option value= "125.00" class="granSecOption"> 1/8 of a second <option value= "151.20" class="granMfOption" > 1/8 of a microfortnight <option value= "200.00" class="granSecOption"> 1/5 of a second <option value= "241.92" class="granMfOption" > 1/5 of a microfortnight <option value= "250.00" class="granSecOption"> 1/4 of a second <option value= "302.40" class="granMfOption" > 1/4 of a microfortnight <option value= "500.00" class="granSecOption"> half a second <option value= "604.80" class="granMfOption" > half a microfortnight <option value="1000.00" class="granSecOption"> one second <option selected value="1209.60" class="granMfOption" > one microfortnight <option value="2000.00"> two seconds <option value="2419.20" class="granMfOption" > two microfortnights <option value="5000.00"> five seconds <option value="6048.00" class="granMfOption" > five microfortnights </select> <dt>Set standard weekday and time: <dd><input type=button name="now" onClick="setFormTime('now');godate(0);" value="Now&gt;" > <select name="d" onChange="godate(1)"> <script><!-- for(i=0;i<7;i++)document.write('<option value="'+i+'">'+weekDays[i]); //--> </script> </select><span class="nobr">@<select name="h" onChange="godate(1)"> <script><!-- for(i=0;i<24;i++)document.write('<option value="'+i+'">'+fill0(i,2)); //--> </script> </select>:<select name="m" onChange="godate(1)"> <script><!-- for(i=0;i<60;i++)document.write('<option value="'+i+'">'+fill0(i,2)); //--> </script> </select></span><span class="nobr">:<select name="s" onChange="godate(1)"> <script><!-- for(i=0;i<60;i++)document.write('<option value="'+i+'">'+fill0(i,2)); //--> </script> </select>.<select name="ms" onChange="godate(1)"> <script><!-- for(i=0;i<1000;i+=25)document.write('<option value="'+i+'">'+fill0(i,3)); //--> </script> </select> </span> <dt>Real Microfortnight Time: <dd><input type=text name="t" class="clockformtextbox" value="fMonday @ 00:00:00" > <dt>Approx Microfortnight Time: <dd><input type=text name="t2" class="clockformtextbox" value="fMonday @ 00:00:00"; > </dl> </form> </div> <div id="clockhelp" class="helpcontainer"> <h1 style="{padding-top: 0}">The Microfortnight Clock</h1> <p> Firstly, you may ask, "What on earth is a microfortnight?" </p><p> The answer is very simple. A microfortnight is the period of time that is precisely one millionth of a fortnight; i.e. two weeks. </p><p> Curiously, this period of time is exactly equivalent to 1.2096 seconds: There are 24x60x60 seconds in a day, multiplied by 14 days, gives 1209600 seconds. Dividing this by a million gives 1.2096. </p><p> This webpage extends the concept of a microfortnight to the level of a timepiece which measures time using that unit. On the way, this provided some unique challenges. </p> <h2>Designing The Clock</h2> <p> Since time is all about measurement and number, the design required a lot of back-of-an-envelope mathematical scribblings. Some of these are presented here, with as much justification as possible, though perhaps still not enough. </p><p> Given that by definition, there are 1000000 microfortnights (henceforth fs) in two weeks, there are therefore 500000 fs in one week. </p> <h3> A few slight hitches </h3> <p> Unfortunately, 500000 is not handily divisible by seven, meaning that there are 71428 4/7ths fs in a day (Compare: there are 86400 seconds in a day). This means that 'Midnight' on most days does not fall on the tick of the clock! </p><p> Yet more issues come about because 71428 fs per day does not divide well into 24 groups analagous to hours, nor into sensible fractions of those 'hours'. </p><p> To work around these inconveniences, the concept of introducing delaying 'leaps' has been borrowed from the greater calendar; i.e. in much the same way the calendar is brought back into line with the seasons by adding an extra day to February every 4 years, the fClock adds an extra f here and there to bring itself back into line with ordinary clock time. </p> <h3> On with the design </h3> <p> Now, to keep things reasonably familiar, we divide the 71428 (or thereabouts) fs into 24 f-hours, all the while acknowledging this is not perfect. This makes for 2976 4/21sts fs per f-hour (Compare: There are 3600 seconds in an hour). </p><p> At this point we could divide that figure by 60 to make some f-minutes, but that ignores the fact that 2976 (ignoring the fraction for a moment) divides evenly by a relatively large selection of other numbers. While there are other choices available, the decision was made that this clock would be designed around the fact that 62x48 = 2976. A decision was also made that there would be 62 f-minutes per f-hour, and 48 fs per f-minute, and not the other way about. </p><p> Those decisions were largely made to make the f-clock look as much like ordinary clock time as possible as often as possible. </p><p> So far then, we have settled on a clock that ticks 24x62x48 times per day. Or 71424 fs per day... which is short of the actual number of fs in a day by 4 4/7ths. </p><p> To recover the missing 4 fs (again ignoring the fraction for the time being), we decide to add a leap f after each quarter of the day, i.e. after 6am, 12noon, 6pm and 12midnight. We could add them all at the end of the day, but we are trying to spread the corrections out evenly so that they are barely noticeable, and also so that the number of fs in a f-minute does not stray too far from the previously set 48. </p><p> We have now accounted for all but the remaining 4/7ths of a f per day; Notice that this translates to 4 fs over the course of a week. </p><p> These can be recovered by simply adding a leap f at the end of any four days of the week. In this case, the leap fs are added at the end of Tuesday, Thursday, Saturday and Sunday; Again this minimises the drift of f-hours from actual hours, and assumes a western week of 5 days starting with Monday and a 2-day weekend to follow. This also has the added bonus of an ever-so-slightly longer weekend, which can only be a good thing! </p> <h3> Wand'ring hands </h3> <p> Of course, because of the leap fs, f-midnight wanders a little relative to actual clock time midnight; This clock labels the days of the f-week as fNameofday because they do not exactly tally with the true days of the week. The discrepancy is slight, little more than a second in the worst case, but enough to warrant an alternate label. Secondly, towards the end of an hour, f-time can look a little strange, with times like 14:61:34. Finally, it can seem very odd to watch a 'seconds' figure tick over from 47 to zero, or even 48 or 49 to zero when the leap seconds are in effect. </p> <h2>The Approximate f-Clock</h2> <p> Since the main f-clock is designed to stick as close to familar 24-hour days as possible, the approximate f-clock takes this one step further and literally uses the hour (and weekday) from standard time. It then divides the 3600 seconds of the hour into 2976 f-like ticks and splits these into 62 f-minutes of exactly 48 fs, no more, no less. </p><p> As a middle ground between the two time systems it fares well, averaging little over one f behind f-time, though at worst just over two fs. </p><p> <h2>Why do this at all?</h2> <p> I'm a geek, plain and simple. As such, I have often leafed through - if such a verb is permissable for an online resource - the Hacker Jargon dictionary; More than once I've come across the entry for the microfortnight. </p><p> The fact that the number of fs per second is a short terminating decimal fraction added to the wonderment of it. Had it been something like 1.142857... recurring or even a long terminator like 1.153564453125 I might have been less captured by it. Then again, if you're a bit OCD like me you'll have to find out why I chose the latter constant as an example, and perhaps I might have found myself doing just that, and being captured by it all the same. </p><p> Still, I paid a hefty price once I got into this project and realised that the number of fs per day wasn't a round number! </p> </div> </body> </html>