MONOCAL

 
 

Today, I was introduced to Ian Battaglia's MONOCAL calendrical system, which is an alternative to the Gregorian calendar and a modified version of the International Fixed Calendar.

 

Mechanics

You can read more about Ian's system over on his blog, but basically, like the International Fixed Calendar, MONOCAL's year has 13 months with 28 days each, plus an additional day after each year, totaling to 365 days (+1 on leap years).

  • A year is divided into 13 months which is divided into 4 weeks (28 days)
  • A year is also divided into 4 quarters (consisting of 13 weeks each)
  • After 4 quarters, a day called Chomsky Day (named after Noam Chomsky) comes

The 13 months are as follows: Ununium, Duomium, Tresium, Quattrium, Quintium, Sexium, Septium, Octium, Nonium, Decium, Undecium, Dudecium, Tredecium.

 

Code

As an exercise and for the sake of at least having something done today, I implemented MONOCAL in JavaScript. All this thing does is convert today's Gregorian calendar date into MONOCAL's format and displays it.

The first step is to get today's date and convert it to the nth day of the year. It is the 2nd of July at the time of this writing; July 2 is the 183rd day of 2017.

var gD = new Date(),
    gS = new Date(gD.getFullYear(), 0, 0),
    gY = Math.floor((gD - gS) / (1000 * 60 * 60 * 24))

Now we have a number to work with. All that's left to do is to run it through a few processes to convert it from Gregorian to MONOCAL.

Update: I initially made a mistake with the date conversions. I was dividing the nth day with (n / 28), which would always give 28. My bad.

To convert it to a date, 28x is subtracted from the (n + 1), where n is the nth day of the year and x is (n / 28) rounded downwards to the nearest integer. One is added to n because January 1, 2017 has been declared as Chomsky Day. Rounding x upwards to the nearest integer gives us the month.

function getDate(n) {
  var date = (n + 1) - (28 * Math.floor((n + 1) / 28))
  if (date % 28 === 0) date = 28
  return date
}

function getMonth(n) {
  return Math.ceil(n / 28)
}
July 2 (183) / 28 = 6.54
(183 - 1) - (28 * 6) = 14

Math.ceil(6.54) = 7 = Septium

Therefore, July 2 is Septium 16.

That's essentially all you really need, but you may also want to know the week number and which quarter you're on. To know the week number, simply divide n by 7 and round it downward to the nearest integer. To know which quarter it is, divide the week number by 13.

Therefore, July 2 (Septium 16) is in Week 26 and Quarter ii.

function getWeek(n) {
  return Math.floor(n / 7)
}

function getQuarter(n) {
  return Math.ceil(getWeek(n) / 13)
}

 

Conclusion

And that's pretty much it. Check it out on GitHub or CodePen. This is definitely an imperfect implementation. There are still some things to work on, like leap years and reverse conversions. Feel free to share any thoughts, comments, suggestions, improvements, etc.

Thanks for reading.

 

P.S. Check out Ian's blog. He writes interesting short stories.
P.P.S. And follow him on Twitter @IanJBattaglia
P.P.P.S. I fixed the embarrassing error with the date calculations. ._.