Decagon made up of 100 triangles that transitions in a circle of ten swirling teardrops each with a repeat of the larger image at its center.Decagon made up of 100 triangles that transitions in a circle of ten swirling teardrops each with a repeat of the larger image at its center. Martin Laptev
  1. Article List
  2. Dec
  3. Date
  • Home
  • About
  • CV/Résumé
  • Article List
    • Dec
      • Date
      • Time
      • Snap
      • Span
      • Note
    • History
      • World War 2
    • Software
      • Git
      • Jupyter
      • Observable
      • Positron
      • Quarto
        • Filter
        • Include
      • Reveal

On this page

  • Decalendar
  • 0 Day of year (doy)
  • 1 Day of xún (dox)
    • Base32
  • 2 Day of hectoday (doh)
  • 3 Day of era (doe)
  • 4 Year of era (yoe)
  • 5 Day of week (dow)
  • 6 Week of year (woy)
  • 7 Day of month (dom)
  • 8 Month of year (moy)
  • 9 Request for comments (rfc)
  • Summary
  • Next
  • Cite
  • Glossary
  • View source

Other Formats

  • CommonMark
  1. Article List
  2. Dec
  3. Date

Decalendar

Introducing Decalendar, a solar calendar which measures time in years and days without the need for months or weeks.

Author

Martin Laptev

Published

2026+128

Modified

2026+137

%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '32px'}}}%%
flowchart LR
   A[Dec]-->B[date]-->C[time]-->D[snap]-->E[span]
   click A "/dec"
   click B "/dec/date"
   click C "/dec/time"
   click D "/dec/snap"
   click E "/dec/span"

Diagram 1

Decalendar

My website serves as a demonstration of both the Quarto publishing📤system and the Dec measurement📐system. I use several clever hacks to get Quarto to display all of the dates on my website in the Dec year+day format. Knowing the basics of the Dec calendar🗓️(Decalendar) will help you to understand the filter and include articles in the Quarto section of my site.

Among its many features, Quarto offers support for the Observable data visualization system. Observable is my top choice for interactive graphics. We can interact with the two Observable calendar plots below⬇️using the adjacent Observable inputs. The scrubber🧽input is a great place to start because it cycles🔄through every value of the range🎚️inputs beneath it.

0 Day of year (doy)

To activate the scrubber input, press the “Play”▶️button above⬆️the range inputs. Upon activation, the box around the selected day in each plot will move back and forth between the first “day of year” (doy), d0, and the last doy, which is either d364 or d365. To insert or remove d365, use the “Year length” radio📻input to set the number of days in the year.

The insertion of d365 shifts 306 dates, d to d, in the Gregorian calendar by 1 day, but does not change the order of any Dec dates, because d365 is the last day of any Dec leap year and is always followed by d0 of the subsequent Dec year (y+1). The “Year length” radio input also changes the value of the negative “Day of year” range input by 1 day.

Similarly, the “Coordinated Universal Time (UTC) offset” radio input shifts the Gregorian calendar date selected by the “Month” and “Day of month” range inputs by 1 day. The “UTC offset” radio input will also shift the Decalendar plot cell colors🎨by 1 day if the “Color scheme” radio input is set to the “Month” discrete scheme instead of the “Day” continuous scheme.

From the perspective of Dec, month color labels🏷️are only useful if we want to compare the Dec and Gregorian calendars. In contrast, Dec day color labels can help us sort days into groups of 100 called hectodays (h) and groups of 10 named xún (x). Dec defines meterological seasons in terms of h and uses x instead of Gregorian calendar months and weeks.

The “Plot layout” radio input rotates the calendar plots by a quarter turn, interchanging the horizontal (↔︎) and vertical (↕) axes. The axis labels demonstrate that x and “days of xún” (dox) are analogous to weeks and “days of week” (dow). If we multiply an x axis label by ten and add it to a dox axis label, we get a “positive integer doy” (pid) cell value: × 10 + = .

\[\text{pid} = \text{x} \ast 10 + \text{dox} \tag{1}\] \[\text{dyl} = \text{pid} - \text{nid} \tag{2}\]

There are two range inputs labelled “Day of year” because every doy can be expressed as either a positive or a negative integer. The pid is the number of days that have passed in the year, the absolute value of the “negative integer doy” (nid) is the number of days left in the year, and their difference is the “Decalendar year length” (dyl), which can be 365 or 366.

// https://observablehq.com/@tophtucker/horizontal-inputs
viewof leapscrub = Inputs.form([
  Inputs.radio(new Map([["365", false], ["366", true]]), {label: "Year length", value: loadLeap}),
  Inputs.radio(new Map([["Positive", false], ["Negative", true]]), {label: "UTC offset", value: negtzo}),
  Inputs.radio(new Map([["Day", false], ["Month", true]]), {label: "Color scheme", value: false}),
  Inputs.radio(new Map([["Vertical", false], ["Horizontal", true]]), {label: "Plot layout", value: vertic}),
  Scrubber(numbers, {autoplay: false, alternate: true, delay: 86.4, loopDelay: 864, format: y => "", inputStyle: "display:none;"}),
  ],
  {
    template: (inputs) => htl.html`
      <div style="display: flex; flex-wrap: wrap">${inputs}</div>
    `
})
viewof dotyInput = Inputs.range([0, 364 + leapInput], {value: 306, step: 1, label: "Day of year"});
viewof dotyInput1 = transformInput(
  Inputs.range([-365 - leapInput, -1], {step: 1, label: "Day of year"}),
  {bind: viewof dotyInput, transform: subN, invert: addN}
);
viewof monthInput = transformInput(
  Inputs.range([1, 12], {step: 1, label: "Month"}),
  {bind: viewof dotyInput, transform: doty2month, invert: month2doty}
);
viewof dotmInput = transformInput(
  Inputs.range([1, 31], {step: 1, label: "Day of month"}),
  {bind: viewof dotyInput, transform: doty2dotm, invert: (x => Math.floor(( 153 * (
    viewof monthInput.value > 2
    ? viewof monthInput.value - 3
    : viewof monthInput.value + 9) + 2
  ) / 5 + x - 1 + nOffInput
) % nDaysInput)});
decPlot = Plot.plot({
  padding: 0,
  width: layoInput ? 1080 : 360,
  height: layoInput ? 240 : 630,
  className: "calplot",
  title: "Decalendar",
  marginTop: coloInput && layoInput ? -2 : !coloInput && layoInput ? -22 : -3,
  marginLeft: coloInput && !layoInput ? 36 : !coloInput && !layoInput ? 24 : 31,
  marginRight: coloInput && !layoInput ? 36 : !coloInput && !layoInput ? 24 : 31,
  marginBottom: coloInput && layoInput ? 34 : !coloInput && layoInput ? 37 : 32,
  y: layoInput ? {
    tickSize: 0,
    label: "Day of xún    ",
    domain: [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
    ticks: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
    tickPadding: -7,
    labelOffset: 25,
  } : {interval: 1, ticks: 18, label: "Xún", type: "band", tickSize: 0, tickPadding: -2, labelOffset: 32},
  x: layoInput ? {interval: 1, ticks: 18, label: "Xún", type: "band", tickSize: 0, labelOffset: 32} : {
    tickSize: 0,
    label: "       Day of xún",
    domain: [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
    ticks: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
    tickPadding: -2,
    labelOffset: 32,
  },
  style: { fontSize: "21px", overflow: "visible"},
  color: {
    range: motyColors,
    domain: moty,
  },
  marks: [
    Plot.cell(dates, {
      x: (d, i) => layoInput ? Math.floor(i / 10) : i % 10,
      y: (d, i) => layoInput ? i % 10 : Math.floor(i / 10),
      fill: (d, i) => coloInput ? months[(new Date(d.getTime() - nOffInput * 86400000)).getUTCMonth()] : leapInput ? leaps[i] : comms[i],
      stroke: (d, i) => i === dotyInput ? "black" : "none",
      strokeDasharray: "5,2",
      strokeWidth: 3,
      inset: 0.5,
    }),
    layoInput ? Plot.axisX({
      ticks: d3.range(0, 37, 2),
      fill: (d, i) => leapInput ? dekLeapColors[d] : dekCommColors[d],
      textStroke: "black",
      textStrokeWidth: 1,
      tickSize: 0,
      tickPadding: coloInput ? -2 : 0, 
    }) : Plot.axisY({
      ticks: d3.range(0, 37, 2),
      fill: (d, i) => leapInput ? dekLeapColors[d] : dekCommColors[d],
      textStroke: "black",
      textStrokeWidth: 1,
      tickSize: 0,
      tickPadding: coloInput ? -24 : -26,
      labelOffset: coloInput ? 17 : 16,
    }),
    coloInput ? Plot.text(dates, {
      x: (d, i) => layoInput ? Math.floor(i / 10 + (i < 190 ? 1 : 0)) : 6,
      y: (d, i) => layoInput ? -1 : Math.floor(i / 10 + (i < 190 ? 1 : 0)),
      text: d => d.getUTCDate() === 7 ? months[d.getUTCMonth()].slice(0, 3) : "",
      dx: layoInput ? -4 : 129,
      dy:  layoInput ? -4 : 0,
      frameAnchor: layoInput ? "left" : "right",
      monospace: true,
      fontSize: "20px"}) : null,
    Plot.ruleY([layoInput ? dotyInput % 10 : Math.floor(dotyInput / 10)], {stroke: "black", strokeWidth: 2, dy: !coloInput && layoInput ? 10 : layoInput ? 9 : 8, x1: 0, x2: layoInput ? 36 : 9}),
    Plot.ruleY([layoInput ? dotyInput % 10 : Math.floor(dotyInput / 10)], {stroke: "black", strokeWidth: 2, dy:  !coloInput && layoInput ? -10 :layoInput ? -9 : -8, x1: 0, x2: layoInput ? 36 : 9}),
    Plot.ruleX([layoInput ? Math.floor(dotyInput / 10) : dotyInput % 10], {stroke: "black", strokeWidth: 2, dx: coloInput && !layoInput ? 13 : layoInput ? 13.5 : 14, y1: 0, y2: layoInput ? 9 : 36}),
    Plot.ruleX([layoInput ? Math.floor(dotyInput / 10) : dotyInput % 10], {stroke: "black", strokeWidth: 2, dx:  coloInput && !layoInput ? -13 : layoInput ? -13.5 : -14, y1: 0, y2: layoInput ? 9 : 36}),
    Plot.text(dates, {
      x: (d, i) => layoInput ? Math.floor(i / 10) : i % 10,
      y: (d, i) => layoInput ? i % 10 : Math.floor(i / 10),
      fill: (d, i) => coloInput && (i < 31 + nOffInput || i > 213 + nOffInput) ? "white" : !coloInput && (i < 20 || i > 199) ? "white" : "black",
      channels: {
        dayOfYear: {
          value: (d, i) => i,
          label: "Day of year"
        },
        month: {
          value: d => (new Date(d.getTime() - nOffInput * 86400000)).getUTCMonth() + 1,
          label: "Month"
        },
        dayOfMonth: {
          value: d => (new Date(d.getTime() - nOffInput * 86400000)).getUTCDate(),
          label: "Day of month"
        },
        week: {
          value: d => d3.utcWeek.count(d3.utcYear((new Date(d.getTime() - nOffInput * 86400000))), (new Date(d.getTime() - nOffInput * 86400000))),
          label: "Week"
        },
        dayOfWeek: {
          value: d => (new Date(d.getTime() - nOffInput * 86400000)).getUTCDay(),
          label: "Day of week"
        },
      },
      tip: {
        format: {
          dayOfYear: true,
          month: true,
          dayOfMonth: true,
          week: true,
          dayOfWeek: true,
          x: false,
          y: false,
          fill: false,
          text: false
        }
      },
      text: (d, i) => String(i),
      label: "Day of year",
      monospace: true,
      fontSize: "13px"})
  ]
})
grePlot = Plot.plot({
  padding: 0,
  width: layoInput ? 1080 : 220,
  height: layoInput ? 180 : 810,
  title: "Gregorian calendar",
  className: "calplot",
  marginTop: layoInput ? 2 : -2,
  marginBottom: 40,
  marginLeft: 33,
  y: layoInput ? {tickFormat: Plot.formatWeekday("en", "short"), tickSize: 0,
      domain: [-1, 0, 1, 2, 3, 4, 5, 6],
      ticks: [0, 1, 2, 3, 4, 5, 6],
      tickPadding: -3 + (leapInput && dotwInput === "Sat") * 5,
      label: null,
  } : {interval: 1, 
       ticks: 26, label: "Week", type: "band", tickSize: 0, tickPadding: -20, labelOffset: 21},
  x: layoInput ? {interval: 1, ticks: 26, label: "Week", type: "band", tickSize: 0, tickPadding: 2, labelOffset: 36} : {
    tickFormat: Plot.formatWeekday("en", "narrow"), 
    tickSize: 0,
    domain: [-1, 0, 1, 2, 3, 4, 5, 6],
    ticks: [0, 1, 2, 3, 4, 5, 6],
    tickPadding: -11 + (leapInput && dotwInput === "Sat") * 5,
    label: "     Day of week",
    labelOffset: 22 + (leapInput && dotwInput === "Sat") * 5,
  },
  style: { fontSize: "20px", overflow: "visible"},
  color: {
    range: motyColors,
    domain: moty,
    className: "cal",
  },
  marks: [
    Plot.cell(datesCal, {
      x: d => layoInput ? d3.utcWeek.count(d3.utcYear(d), d) : d.getUTCDay(),
      y: d => layoInput ? d.getUTCDay() : d3.utcWeek.count(d3.utcYear(d), d),
      fill: (d, i) => coloInput ? months[d.getUTCMonth()] : leapInput ? leaps[(i + 365 - 59 + nOffInput) % (365 + leapInput)] : comms[(i + 365 - 59 + nOffInput) % (365 + leapInput)],
      stroke: (d, i) => ((i + 365 - 59 + nOffInput) % (365 + leapInput)) === dotyInput ? "black" : "none",
      strokeDasharray: "5,2",
      strokeWidth: 2.5,
      inset: .5,
    }),
    Plot.text(datesCal, {
      x: d => layoInput ? d3.utcWeek.count(d3.utcYear(d), d) : 6,
      y: d => layoInput ? -1 : d3.utcWeek.count(d3.utcYear(d), d),
      text: d => d.getUTCDate() === 7 ? months[d.getUTCMonth()].slice(0, 3) : "",
      dx: layoInput ? 9 : 48,
      dy: layoInput ? -3 : 0,
      frameAnchor: layoInput ? "left" : "right",
      monospace: true,
      fontSize: "20px"}),
    Plot.ruleY(layoInput ? seldow : selwee, {stroke: "black", strokeWidth: 2, dy: layoInput ? -8.5 : -7, x1: 0, x2: layoInput ? 52 + (leapInput && dotwInput === "Sat") : 6}),
    Plot.ruleY(layoInput ? seldow : selwee, {stroke: "black", strokeWidth: 2, dy: layoInput ? 8.5 : 7, x1: 0, x2: layoInput ? 52 + (leapInput && dotwInput === "Sat") : 6}),
    Plot.ruleX(layoInput ? selwee : seldow, {stroke: "black", strokeWidth: 2, dx: 9.5, y1: 0, y2: layoInput ? 6 : 52 + (leapInput && dotwInput === "Sat")}),
    Plot.ruleX(layoInput ? selwee : seldow, {stroke: "black", strokeWidth: 2, dx: -9.5, y1: 0, y2: layoInput ? 6 : 52 + (leapInput && dotwInput === "Sat")}),
    Plot.text(datesCal, {
      x: layoInput ? d => d3.utcWeek.count(d3.utcYear(d), d) : {
        label: "Day of week",
        value: d => d.getUTCDay(),
      },
      y: layoInput ? {
        label: "Day of week",
        value: d => d.getUTCDay(),
      } : d => d3.utcWeek.count(d3.utcYear(d), d),
      fill: (d, i) => coloInput && (i < 90 + leapInput || i > 272 + leapInput) ? "white" : !coloInput && (i < 79 - nOffInput + leapInput || i > 258 - nOffInput + leapInput) ? "white" : "black",
      text: d => d.getUTCDate(),
      channels: {
        dayOfYear: {
          value: (d, i) => (i + 365 - 59 + nOffInput) % (365 + leapInput),
          label: "Day of year"
        },
        month: {
          value: d => d.getUTCMonth() + 1,
          label: "Month"
        },
        dayOfMonth: {
          value: d => d.getUTCDate(),
          label: "Day of month"
        },
      },
      tip: {
        format: {
          dayOfYear: true,
          month: true,
          dayOfMonth: true,
          x: true,
          y: true,
          fill: false,
          text: false,
        }
      },
      monospace: true,
      fontSize: "13px"})
  ]
})

First dow of the Gregorian calendar year

viewof dotwInput = Inputs.radio([
  "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
  ], {value: gregBoyDotwStr})

The distinction between pid and nid can be explained in terms of computer programming. If we think of a year as an array and each day as an array element, dyl is the number of elements in the array, pid is a positive index, and nid is a negative index. Array indexes can be used to obtain specific array elements individually via indexing or in groups via array slicing.

The year+day Dec date format is short for year+day/dyl. Dec truncates dates because the dyl is not needed to specify a date, remains constant for 366, 1095, or 2920 days, has only 2 possible values: 365 or 366, and can be determined by passing Year y to Equation 4 below. Nevertheless, we can use the dyl to convert between different kinds of Dec dates.

\[ \text{leap}=\begin{cases} 1&{\begin{aligned} &\text{ if } (\text{y} + 1)\href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} \ \ \ \ 4=0\\ &\href{https://en.wikipedia.org/wiki/Logical_conjunction}{\land}(\text{y} + 1)\href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 100\neq0\\ &\href{https://en.wikipedia.org/wiki/Logical_disjunction}{\lor}(\text{y} + 1)\href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 400=0\end{aligned}}\\\\ 0&{\text{ otherwise}}\end{cases} \tag{3}\]

\[\text{dyl}=365+\text{leap} \tag{4}\]

  • Julia
  • Observable JavaScript
  • Python
  • R
function leap(year = 0)
    year += 1
    year % 4 == 0 && year % 100 != 0 || year % 400 == 0
end
leap (generic function with 2 methods)
leap(2019)
true
leap(2020)
false
function leap(year = 0) {
  year += 1;
  return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
}
leap(2019)
leap(2020)
def leap(year=2000):
    year += 1
    return year % 4 == 0 and year % 100 != 0 or year % 400 == 0
leap(2019)
True
leap(2020)
False
leap <- function(year = 0) {
  year <- year + 1
  year %% 4 == 0 & year %% 100 != 0 | year %% 400 == 0
}
leap(2019)
[1] TRUE
leap(2020)
[1] FALSE

Dec categorizes each date as a countdown or countup date, depending on whether the date counts up the days since Year y or counts down the days until Year y+1. The current year+day UTC date, +, informs us that Year began days ago, whereas its countdown equivalent, -, lets us know that Year will begin in days.

\[\text{y}+\dfrac{\text{pid}}{\text{dyl}} = \text{y} + 1 + \dfrac{\text{nid}}{\text{dyl}} \tag{5}\]

Both pid and nid can be useful. If we wanted to add 285 days to the doy selected below, for example to predict when a pregnant🤰woman will give birth to a baby👩‍🍼(Jukic et al. 2013+215), we should add 285 to the pid if it is less than 80 in a common year or less than 81 in a leap year, but otherwise we should add 1 to the year and add 285 to the nid: + 285 = .

Inputs.bind(Inputs.range([0, 364 + leapInput], {step: 1, label: "Day of year"}), viewof dotyInput)
Inputs.bind(Inputs.range([-365 - leapInput, -1], {step: 1, label: "Day of year"}), viewof dotyInput1)

First dow of the Gregorian calendar year

Inputs.bind(Inputs.radio(["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], {value: gregBoyDotwStr}), viewof dotwInput)

The radio input beneath the plots selects the dow for d, the first day of the Gregorian calendar year. Changing the d dow shifts every Gregorian calendar date by 1 to 6 days without affecting Decalendar. A leap year that begins on the last dow, Dow 6, has an extra “week of year” (woy), but its first and last woy, Weeks 0 and 53, each contribute only 1 day to the year.

Even though weeks determine the shape of the Gregorian calendar plot, its cell values are “days of month” (dom). We can uniquely identify🪪a specific day in any year with a pid, instead of a month and a dom. Except for d365 in leap years, every year has the same x, h, and months, but not the same weeks. It takes 5, 6, 7, 11, or 12 years for a d dow to recur.

The number of forms that the Gregorian calendar can take, 14, is the product of 7 dow and 2 year lengths. If we set aside an extra copy of a printed🖨️Gregorian calendar on d, we would have to wait 6, 11, 12, 17, 23, 28, or 40 years to use it. We can make the leap year form of Decalendar apply to any year by appending an asterisk (*) to the label for d365: 365*.

The 365* label is short for 365*leap, where leap is the left-hand side of Equation 3. If leap is 1, Year y is a leap year and 365* is d365, the last day of Year y. If leap is 0, Year y is a common year and 365* is d0, the first day of Year y+1. The 365* label unites the common and leap year forms of Decalendar into a perennial calendar that can be reused♻️every year.

1 Day of xún (dox)

As opposed to a week, an x can be split evenly into either 5 pairs of days or 2 equal halves called “pentadays of xún” (pox). Likewise, a common year can be divided evenly into 73 groups of 5 days called “pentadays” (p): p0 to p72. The last p of a leap year, p73, consists of the final day of the leap year, d365, and the first 4 days of the subsequent year: d0 to d3.

In the context of a common year, p73 is synonymous with p0 of the succeeding year. To obtain the current p, we double the current x and add the current pox, which is 1 if the current dox is greater than 4 and 0 otherwise: = × 2 + [ > 4]. If we divide a pid or a dox by 5, the remainder will be its corresponding “day of pentaday” (dop): mod 5 = .

\[\text{x} = \lfloor \text{pid} \div 10\rfloor \tag{6}\] \[\text{dox} = \text{pid} \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 10 \tag{7}\] \[\text{pox} = \href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{[}\text{dox} > 4\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{]} \tag{8}\] \[\text{p = x} \ast 2 + \text{pox} \tag{9}\] \[\text{dop = dox} \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 5 \tag{10}\]

In Diagram 2 below, each row is a pox and each square node is a dox. Diagram 2 visualizes Schedule L, a Dec base schedule that plans for exactly 219 work days per year, which is about an x more than the 208 to 210 work days per year provisioned by a four-day workweek. Schedule L designates Dox 1, 2, 3, 6, 7, and 8 as work days and Dox 0, 4, 5, and 9 as rest days.

Schedule L (Dox 0 to 9)

%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '29px'}}}%%
flowchart LR
  B~~~M[ ]:::empty----N[ ]:::empty
  W---M
  N---O[ ]:::empty
  Q[ ]:::empty---L
  W[ ]:::empty-->A[0]-->B[1]-->C[2]-->D[3]-->E[4]---L[ ]:::empty
  Y[ ]:::empty-->F[5]-->G[6]-->H[7]-->I[8]-->J[9]---O[ ]:::empty
  B~~~P[ ]:::empty---Q
  Y---P
  subgraph workdays[work]
  B
  C
  G
  H
  D
  I
  end
  subgraph restdays[ ]
  A
  F
  E
  J
  workdays
  end
  classDef empty width:0px;

Diagram 2

Dec identifies groups of days between Dop 0 and 4 as “pentaday interquintile ranges” (pir): Dop 1, 2, and 3. Similarly, the days betwixt Dox 0 and 9 are “xún interdecile ranges” (xir). The names for pir and xir are derived from the terms quintile, decile, and interquartile range. If we follow Schedule L, a pir is to a workweek as a p is to a week and as an x is to a fortnight.

The pair of days between two pir is called a “liminal interconnecting margin” (lim). The last lim of a common year, Lim 73, comprises d364 and d0 and is synonymous with Lim 0 of the subsequent year. In a leap year, Lim 73 consists of d364 and d365 and overlaps with Lim 74, which is composed of d365 and d0 and is equivalent to Lim 0 of the ensuing year.

Except for Lim 74, every even-numbered lim is the border that separates two xir. With the exception of Lim 73, every odd-numbered lim is flanked by the two pir within each xir. Diagram 3 below shows the final five doy of a common year and the first five doy of the following year, which include the last day of Lim 72, Pir 72, Lim 0, Pir 0, and the first day of Lim 1.

Schedule L (p72 and p0)

%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '29px'}}}%%
flowchart LR
  W~~~~O[ ]:::empty
  W[ ]:::empty-->A[360]-->B[361]-->C[362]-->D[363]-->E[364]----L[ ]:::empty
  Y[ ]:::empty-->F[0]-->G[1]-->H[2]-->I[3]-->J[4]-->K[ ]:::empty
  Q[ ]:::empty---L
  Y---Q
  subgraph workdays[work]
  B
  C
  G
  H
  D
  I
  end
  subgraph restdays[ ]
  A
  F
  E
  J
  workdays
  end
  classDef empty width:0px;

Diagram 3

The diagrams above illustrate that the transition from a common year preserves the alternating pattern of two-day lim and three-day pir. After 4 or 8 years, this pattern is interrupted by Lim 73 and 74 at the end of a leap year. In Diagram 4 below, this interruption manifests as an extra doy per row which puts Day 364 alongside Day 365 and Day 4 beside Day 5.

Schedule L (d360 to d365 and d0 to d5)

%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '29px'}}}%%
flowchart LR
  W~~~~O[ ]:::empty
  W[ ]:::empty-->A[360]-->B[361]-->C[362]-->D[363]-->E[364]-->L[365]----S[ ]:::empty
  Y[ ]:::empty-->F[0]-->G[1]-->H[2]-->I[3]-->J[4]-->K[5]-->T[ ]:::empty
  Q[ ]:::empty---S
  Y---Q
  subgraph workdays[work]
  B
  C
  G
  H
  D
  I
  end
  subgraph restdays[ ]
  A
  F
  E
  J
  K
  L
  workdays
  end
  classDef empty width:0px;

Diagram 4

According to Schedule L, pir only contain workdays and lim are solely made up of rest days. When we follow Schedule L, a lim is the Dec analog of a weekend. To make lim appear like weekends we can start from Dox 1 instead of Dox 0 as in the Diagram 5 below, which displays its lim as a two-by-two square grid on the right like Lim 73 and 1 in Diagram 4 above.

Schedule L (Dox 1 to 0)

%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '29px'}}}%%
flowchart LR
  B~~~M[ ]:::empty----N[ ]:::empty
  W---M
  N---O[ ]:::empty
  Q[ ]:::empty---L
  W[ ]:::empty-->A[1]-->B[2]-->C[3]-->D[4]-->E[5]---L[ ]:::empty
  Y[ ]:::empty-->F[6]-->G[7]-->H[8]-->I[9]-->J[0]---O[ ]:::empty
  B~~~P[ ]:::empty---Q
  Y---P
  subgraph workdays[work]
  A
  B
  C
  F
  G
  H
  end
  subgraph restdays[ ]
  D
  E
  I
  J
  workdays
  end
  classDef empty width:0px;

Diagram 5

The order of dox in Diagram 5 is different than all of the previous diagrams but all of the diagrams above show Schedule L because the categorization of dox as work or rest days remains unchanged. If we left rotate (↺) the dox categories of Schedule L by 1 day, we get the Schedule X Dec schedule: L ↺ 1 = X. Schedule X groups rest days at the end of each p.

Schedule X (Dox 0 to 9)

%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '29px'}}}%%
flowchart LR
  B~~~M[ ]:::empty----N[ ]:::empty
  W---M
  N---O[ ]:::empty
  Q[ ]:::empty---L
  W[ ]:::empty-->A[0]-->B[1]-->C[2]-->D[3]-->E[4]---L[ ]:::empty
  Y[ ]:::empty-->F[5]-->G[6]-->H[7]-->I[8]-->J[9]---O[ ]:::empty
  B~~~P[ ]:::empty---Q
  Y---P
  subgraph workdays[work]
  A
  B
  C
  F
  G
  H
  end
  subgraph restdays[ ]
  D
  E
  I
  J
  workdays
  end
  classDef empty width:0px;

Diagram 6

If we follow Schedule X, there will be 4 consecutive work days during any transition from a leap year. To limit the number of consecutive work days to 3, we could right rotate (↻) Schedule L and obtain Schedule F: L ↻ 1 = F. Unlike Schedule X, Schedule F handles yearly transitions just as gracefully as Schedule L and provisions the exact same number of work days per year.

Schedule F (Dox 0 to 9)

%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '29px'}}}%%
flowchart LR
  M[ ]:::empty----N[ ]:::empty
  W---M
  N---O[ ]:::empty
  Q[ ]:::empty---L
  W[ ]:::empty-->A[0]-->B[1]-->C[2]-->D[3]-->E[4]---L[ ]:::empty
  Y[ ]:::empty-->F[5]-->G[6]-->H[7]-->I[8]-->J[9]---O[ ]:::empty
  P[ ]:::empty---Q
  Y---P
  subgraph workdays[work]
  C
  D
  E
  H
  I
  J
  end
  subgraph restdays[ ]
  A
  B
  F
  G
  workdays
  end
  classDef empty width:0px;

Diagram 7

Each of the 32 base Dec schedules can be expressed as a five-bit (5b) binary (base2) sequence. Of these 32 binary sequences, 8 are palindromes. If a Dec schedule can be represented by a 5b palindrome, we can identify its work and rest days by the last digit of not only the pid but also either the subsequent nid (nid) in common years or the nid after next (nid) in leap years.

We can sum a nid with 1 to get a nid, nid = nid + 1, or with 2 to get a nid: nid = nid + 2. Table 1 below displays the pid, nid, nid, and “mixed integer doy” (mid) of the first and last 11 days of a common year. We can use the last digit of any mid that is derived from an nid to discern between the work and rest days of any of the 32 base Dec schedules in common years.

The horizontal line above all but the last digit of the mid in Table 1 is called a vinculum. In Dec, a vinculum negates whatever is beneath it, negating all of the digits of an integer flips its sign, and a negative integer is denoted by either a vinculum or a minus sign. For example, d1 and d19 are two equivalent ways to write Day -1, the last day of the Dec year.

pid nid nid mid
0 -365 -364 375
1 -364 -363 376
2 -363 -362 377
3 -362 -361 378
4 -361 -360 379
5 -360 -359 360
6 -359 -358 361
7 -358 -357 362
8 -357 -356 363
9 -356 -355 364
10 -355 -354 365
… … … …
354 -11 -10 29
355 -10 -9 10
356 -9 -8 11
357 -8 -7 12
358 -7 -6 13
359 -6 -5 14
360 -5 -4 15
361 -4 -3 16
362 -3 -2 17
363 -2 -1 18
364 -1 -0 19
pid nid nid mid pid nid nid mid
0 -365 -364 375 354 -11 -10 29
1 -364 -363 376 355 -10 -9 10
2 -363 -362 377 356 -9 -8 11
3 -362 -361 378 357 -8 -7 12
4 -361 -360 379 358 -7 -6 13
5 -360 -359 360 359 -6 -5 14
6 -359 -358 361 360 -5 -4 15
7 -358 -357 362 361 -4 -3 16
8 -357 -356 363 362 -3 -2 17
9 -356 -355 364 363 -2 -1 18
10 -355 -354 365 364 -1 -0 19
Table 1

The correlation between a digit and the absolute value (magnitude) of its mixed integer is positive for positive digits and negative for negative digits. Each negative digit in the mid column of Table 1 pulls the magnitude of its mid towards one, meanwhile each positive digit in that column moves the magnitude of its mid in the opposite direction along the number line.

In a common year, the last digits of pid and nid run antiparallel to each other like complementary strands of deoxyribonucleic acid🧬, but instead of adenine to thymine and cytosine to guanine, the pattern is 0 to 4, 1 to 3, 2 to 2, 3 to 1, 4 to 0, and so on. The final digits of pid and nid follow the same pattern in leap years: 0 to 4, 1 to 3, 2 to 2, 3 to 1, 4 to 0, and so on.

The last digits of pid and mid are misaligned by 4 days in leap years and by 5 days in common years. Dec maintains a constant five-day misalignment by replacing the mid with the next mid (mid) in leap years. The accents above nid and mid both advance the apparent doy by one day. Table 2 below shows the pid, nid, nid, and mid of the first and last 11 days of a leap year.

pid nid nid mid
0 -366 -364 375
1 -365 -363 376
2 -364 -362 377
3 -363 -361 378
4 -362 -360 379
5 -361 -369 360
6 -360 -358 361
7 -359 -357 362
8 -358 -356 363
9 -357 -355 364
10 -356 -354 365
… … … …
355 -11 -9 10
356 -10 -8 11
357 -9 -7 12
358 -8 -6 13
359 -7 -5 14
360 -6 -4 15
361 -5 -3 16
362 -4 -2 17
363 -3 -1 18
364 -2 -0 19
365 -1 -0 00
pid nid nid mid pid nid nid mid
0 -366 -364 375 355 -11 -9 10
1 -365 -363 376 356 -10 -8 11
2 -364 -362 377 357 -9 -7 12
3 -363 -361 378 358 -8 -6 13
4 -362 -360 379 359 -7 -5 14
5 -361 -369 360 360 -6 -4 15
6 -360 -358 361 361 -5 -3 16
7 -359 -357 362 362 -4 -2 17
8 -358 -356 363 363 -3 -1 18
9 -357 -355 364 364 -2 -0 19
10 -356 -354 365 365 -1 -0 00
Table 2

A digit can be negated by a vinculum, augmented by an acute accent, diminished by a grave accent, double augmented by a double acute accent, or double diminished by a double grave accent. The main purpose of these modifications is to change the appearance of the last digit of an nid so that it matches the work or rest day classification of the last digit of a pid.

The Schedule L rule for categorization of work and rest days can be summarized as [dop ∈ {1,2,3}], where ∈ means “is an element of” and {1,2,3} is Set L, a set which contains all of the dop that are Schedule L work days. The Schedule L rule can be applied to the last digit of the mid or nid in common years, of the mid or nid in leap years, or of the pid in all years.

Base32

The Schedule L pattern of rest and work days can be expressed in binary (base2) as 01110, decimal (base10) as 14, or Dec duotrigesimal (base32) as L. Each of the 32 Dec base schedules can be represented by a single letter of the Dec base32 (b32) alphabet. The b32 letters are listed in Table 3 below alongside their base10 (b10) and base2 (b2) values.

A 0 00000 N 16 10000
Á 1 00001 O 17 10001
B 2 00010 Ó 18 10010
C 3 00011 P 19 10011
D 4 00100 Q 20 10100
E 5 00101 R 21 10101
É 6 00110 S 22 10110
F 7 00111 T 23 10111
G 8 01000 U 24 11000
H 9 01001 Ú 25 11001
I 10 01010 V 26 11010
Í 11 01011 W 27 11011
J 12 01100 X 28 11100
K 13 01101 Y 29 11101
L 14 01110 Ý 30 11110
M 15 01111 Z 31 11111
A 0 00000 G 8 01000 N 16 10000 U 24 11000
Á 1 00001 H 9 01001 O 17 10001 Ú 25 11001
B 2 00010 I 10 01010 Ó 18 10010 V 26 11010
C 3 00011 Í 11 01011 P 19 10011 W 27 11011
D 4 00100 J 12 01100 Q 20 10100 X 28 11100
E 5 00101 K 13 01101 R 21 10101 Y 29 11101
É 6 00110 L 14 01110 S 22 10110 Ý 30 11110
F 7 00111 M 15 01111 T 23 10111 Z 31 11111
Table 3

Table 3 above shows that the b32 alphabet includes the 26 letters of the English alphabet and combines the 6 vowels, a, e, i, o, u, and y, with acute accents ( ́) to create 6 additional letters, á, é, í, ó, ú, and ý, for a total of 32 letters. The 6 additional accented letters are included immediately after their unaccented antecedents as per the order of the English alphabet.

Wikimedia

Wikimedia

If we need more work days than those provided by Schedule L, we can switch to the Schedule LM Dec schedule by following Schedule L on even numbered p and Schedule M to odd numbered p. Schedule LM has 1 more work day per x than Schedule L and provisions 255 work days per year without modifying the yearly transition shown in Diagrams 3 and 4 above.

In contrast to weekly schedules, Dec schedules like L and LM produce a consistent🎯number of work days every year. While Days 364, 365, and 0 can be work or rest days in the Gregorian calendar️, these days are always rest days if we follow Schedules L or LM. Therefore, Schedules L and LM do not require any holidays to smooth the transition between years.

There are 11 United States (US) Federal holidays. US Federal holidays that fall on a Gregorian calendar️ rest day, Dow 0 or Dow 6, are observed on the nearest Gregorian calendar️ work day: Dow 1 or Dow 5. Instead of applying this rule to Schedule L and moving holidays from Dox 0 to 1, 4 to 3, 5 to 6, or 9 to 8, we can switch between Dec schedules as needed.

Over the course of a Dec cycle, which consists of 400 years, 20871 weeks, or 146097 days, a five-day workweek provides an average of 260.8875 work days per year. If we round 260.8875 to 261 and then subtract the 11 US Federal holidays, we get an annual total of 250 work days, which is 1 p less than the total work days provided annually by Schedule LM.

We can decrease the annual work day total of Schedule LM to 249 if we reclassify d19, d111, d149, d206, d296, and d316 as rest days. Approximately, d19 is the northward equinox, d111 is the northern solstice, d149 is the hottest doy globally on average, d206 is the southward equinox, d296 is the southern solstice, and d316 is the coldest day globally on average.

The last US Federal holiday of the Gregorian calendar year is Christmas🎄. Although it occurs on d299, which is the last day of Hectoday 2 (h2), Christmas is likely to be celebrated on d300, the first day of Hectoday 3 (h3), by people who do not use Dec and live in a UTC time zone with a negative offset. The Dec analog of the holiday season is Hectoday -1 (h1).

2 Day of hectoday (doh)

Astronomical seasons vary in duration. Meterological seasons are 2 months in the Hindu calendar and 3 months in the Gregorian calendar, but the months in each of these calendars differ in length. The duration of a meterological season is always 3 months, 9 x, or 90 days in the French Revolutionary calendar, 4 months, 12 x, or 120 days in the Egyptian calendar, 13 weeks or 91 days in the World Season Calendar, and 1 h, 10 x, 20 p, or 100 days in Decalendar.

As opposed to seasons in other calendars, the 4 Dec seasons are chosen from 2 overlapping sets of 4 consecutive h, called “positive integer hectodays” (pih) and “negative integer hectodays” (nih), to match daily global mean temperature patterns. Every doy is simultaneously a member of a pih, nih, “positive integer xún” (pix) and “negative integer xún” (nix).

\[\text{pih} = \left\lfloor\dfrac{\text{pid}}{100}\right\rfloor \tag{11}\] \[\text{nih} = \left\lfloor\dfrac{\text{nid}}{100}\right\rfloor \tag{12}\] \[\text{pix} = \left\lfloor\dfrac{\text{pid}}{10}\right\rfloor \tag{13}\] \[\text{nix} = \left\lfloor\dfrac{\text{nid}}{10}\right\rfloor \tag{14}\]

Day 0 is in h0, x0, h4, and x37. Days 364 and 365 are in h3, x36, h1, and x1. While h0 and x0 start at the boy, both h3 and x36 extend beyond the “end of year” (eoy). Conversely, h4 and x37 begin before the boy but h1 and x1 do not go past the eoy. The x37 of any common year is equivalent to and thus has the same color label as the x36 of the prior year.

In Dec, each group of days has the same color label as its first doy. Day 365 does not affect pih and pix color labels but shifts nih and nix color labels by 1 day. If the dyl is unknown, Dec labels nih and nix with common year colors by default. Depending on the year, woy color labels can differ by 1 to 6 days and thus can only be used when the year is known.

The line chart below labels the 4 Dec seasons, h0, h1, h2, and h1, with their respective colors: red, yellow, cyan, and violet. The cyan area denoting h2 is truncated to hide its overlap with the violet area representing h1. Coincidentally, the h2 and h1 overlap begins 1 or 2 days before the soonest possible date of Thanksgiving🦃and ends with Christmas🎄.

{
  // Common properties on the axes and annotations
  const axisCommon = {
    tickSize: 10,
    fontSize: 18,
    fill: "#333"
  };
  const gridY = {
    // We'll also use these properties for the ticks' vector lines on the y-axis
    stroke: "#c0c0c0",
    strokeOpacity: 0.7,
    strokeDasharray: "2,2"
  };
  const annotCommon = { fontSize: 16, fontWeight: 700, pointerEvents: "none" };
  const hideAnnotCommon = {
    ...annotCommon,
    px: "dayOfYear",
    py: "temp",
    strokeWidth: 5,
    maxRadius: 5
  };
  // Highlight line marks on hover
  const pointerInactive = renderFilter(true);
  const pointerContext = renderFilter(false);
  const pointerFocus = renderFilter(false);
  // I prefer to create a standalone color scale to access the range's values
  // (e.g., color.range[0]) and avoid the hassle of repeatedly copying hex codes
  const color = Plot.scale({
    color: {
      type: "categorical",
      domain: [2023, 2024, 2025],
      range: ["#ffc500", "#00f9f6", "#ff09ff"],
      unknown: "#808080"
    }
  });
  const plot = Plot.plot({
    // Dimensions
    width: Math.min(width, 640),
    marginTop: 0,
    marginRight: 10,
    marginBottom: 45,
    marginLeft: 45,
    // Scales
    y: {
      domain: [11, 17.5]
    },
    color: color,
    // Other top-level options
    axis: null,
    label: null,
    style: {
      overflow: "visible"
    },
    // Marks
    marks: [
      Plot.ruleX([100, 200, 264], {stroke: ["#cdff00", "#00bdff", "#4800ff"], strokeWidth: 4, strokeDasharray: "2 2",}),
      Plot.ruleX([100, 200, 264], {stroke: (d, i) => i === 2 ? "#ddd" : "#555", strokeWidth: 4, strokeDasharray: "2 2", strokeDashoffset: 2}),
      Plot.areaY(d3.range(366), {x: d => d, y1: 11, y2: 17.5, fill: d => d < 264 ? piecewiseColor(Math.floor(d / 100) / 4) : "#4800ff", fillOpacity: 0.1}),
      // X-axis
      // The textAnchor option is not a channel so we'll use two axisX marks
            Plot.axisX({
        ...axisCommon,
        // Days of year that correspond to
        // ['Jan 1', 'Apr 1', 'Jul 1', 'Oct 1']
        // and ['Jan 1', 'Mar 1', 'May 1', 'Jul 1', 'Sep 1', 'Nov 1']
        ticks: [0, 50, 100, 150, 200, 250, 300, 350],
        stroke: "#333",
        label: "Day of year",
        labelAnchor: "center",
        labelOffset: 42,
      }),
      // Use different textAnchor for the last tick
      // Y-axis
      // Y-axis gridlines
      Plot.gridY({
        ...gridY,
        ticks: d3.range(12, 18)
      }),
      // Again, two axisY marks because neither textAnchor nor dx are channels
      Plot.axisY({
        ...axisCommon,
        ...gridY,
        ticks: d3.range(12, 18),
        tickFormat: "d",
        strokeDashoffset: 2,
        textAnchor: "end",
        label: "Daily global mean temperatures",
        labelAnchor: "center",
        labelOffset: 40,
        tickPadding: 1,
        dx: 8,
      }),
      // Line marks
      Plot.line(
        temps,
        pointerInactive({
          x: "dayOfYear",
          y: "temp",
          stroke: "year",
          strokeWidth: (d) => (d.year === 2025 ? 3 : d.year === 2024 ? 3 : d.year === 2023 ? 3 : 1),
          strokeOpacity: (d) => ([2023, 2024, 2025].includes(d.year) ? 0.7 : 0.08)
        })
      ),
      Plot.line(
        temps,
        pointerContext({
          x: "dayOfYear",
          y: "temp",
          z: "year",
          stroke: color.unknown,
          strokeWidth: 1,
          strokeOpacity: 0.1
        })
      ),
      Plot.line(
        temps,
        pointerFocus({
          x: "dayOfYear",
          y: "temp",
          stroke: "year",
          strokeWidth: 2
        })
      ),
      // Annotations
      Plot.text(["2025"], {
        ...annotCommon,
        x: () => (width < 400 ? 302 : 320),
        y: 14.5,
        fill: color.range[2],
        stroke: "black",
        strokeWidth: .5,
      }),
      // Trick to hide the "2024" annotation on hover
      // Plot.text(
      //   temps,
      //   Plot.pointer({
      //     ...hideAnnotCommon,
      //     text: (d) => "2025",
      //     x: () => (width < 400 ? 302 : 320),
      //     y: 14.5
      //   })
      // ),
      Plot.text(["2024"], {
        ...annotCommon,
        x: () => (width < 380 ? 45 : 70),
        y: 16.5,
        fill: color.range[1],
        stroke: "black",
        strokeWidth: .5,
      }),
      // Trick to hide the "2024" annotation on hover
      // Plot.text(
      //   temps,
      //   Plot.pointer({
      //     ...hideAnnotCommon,
      //     text: (d) => "2024",
      //     x: () => (width < 380 ? 45 : 85),
      //     y: 16.5
      //   })
      // ),
      Plot.text(["2023"], {
        ...annotCommon,
        x: () => (width < 380 ? 230 : width < 480 ? 210 : 230),
        y: 16.5,
        fill: color.range[0],
        stroke: "black",
        strokeWidth: .5,
      }),
      // Hide the "2023" annotation on hover
      // Plot.text(
      //   temps,
      //   Plot.pointer({
      //     ...hideAnnotCommon,
      //     text: (d) => "2023",
      //     x: () => (width < 380 ? 230 : width < 480 ? 210 : 205),
      //     y: 16.5
      //   })
      // ),
      // Plot.text(["Years 1940 to 2025"], {
      //   ...annotCommon,
      //   x: () => (width < 380 ? 110 : 170),
      //   y: 12.4,
      //   // Different font weight than other annotations
      //   fontWeight: 400
      // }),
      // Hide the "Years 1940 to 2022" annotation on hover
      // Plot.text(
      //   temps,
      //   Plot.pointer({
      //     ...hideAnnotCommon,
      //     text: (d) => "Years 1940 to 2022",
      //     x: () => (width < 380 ? 110 : 170),
      //     y: 12.4
      //   })
      // ),
      // On hover marks
      // Trick to hide x-axis when hovering
      Plot.ruleY(
        temps,
        Plot.pointer({
          px: "dayOfYear",
          py: "temp",
          x1: 0,
          x2: 366,
          y: 10.8,
          stroke: "white",
          className: "hideXaxisRule",
          strokeWidth: 30,
          inset: -25,
          maxRadius: 5
        })
      ),
      // Rule mark
      Plot.ruleX(
        temps,
        Plot.pointer({
          x: "dayOfYear",
          py: "temp",
          stroke: "#333",
          insetTop: 15,
          insetBottom: -10,
          maxRadius: 5
        })
      ),
      // Dot mark
      Plot.dot(
        temps,
        Plot.pointer({
          x: "dayOfYear",
          y: "temp",
          fill: "year",
          r: 4,
          maxRadius: 5
        })
      ),
      // Text on datapoint (tooltip)
      Plot.text(
        temps,
        Plot.pointer({
          x: "dayOfYear",
          y: "temp",
          fill: "currentColor",
          text: (d) => `${d.year}\n${d3.format(".1f")(d.temp)}`,
          fontSize: 16,
          lineHeight: 1.1,
          strokeWidth: 5,
          dy: -30,
          maxRadius: 5
        })
      ),
      // Hovered day on x-axis
      Plot.text(
        temps,
        Plot.pointer({
          ...axisCommon,
          x: "dayOfYear",
          py: "temp",
          text: (d) => "Day " + d.dayOfYear,
          frameAnchor: "bottom",
          dy: 22,
          className: "focusedDayAndTemp",
          maxRadius: 5
        })
      )
    ]
  });
  plot.addEventListener("input", () => {
    if (plot.value === null) {
      pointerInactive.update(true);
      pointerContext.update(false);
      pointerFocus.update(false);
    } else {
      const year = plot.value.year;
      pointerInactive.update(false);
      pointerContext.update((d) => d.year !== year);
      pointerFocus.update((d) => d.year === year);
    }
  });
  return plot;
}

The line chart shows ERA5 daily global mean temperatures for every doy. If we think of the method for assigning doy to Dec seasons in Equation 15 as a classification model, its “goodness of fit” is supported by the fact that the hottest doy on average, d149, is near the middle of h1 and the coldest doy on average, d316, is close to the center of h1: 365 – 316 = 49.

\[\text{season} = \left\lfloor\dfrac{\text{pid} - \text{dyl} * \href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{[}\text{nid} \ge -100\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{]}}{100}\right\rfloor \tag{15}\]

In general, the hottest days are in h1, the coldest days are in h1, temperatures increase with time in h0, and temperatures decrease with time in h2. Therefore, we can refer to h0, h1, h2, and h1 as the rise📈, crest🔥, fall📉, and trough❄️, respectively, of global mean temperatures. Table 4 below shows the Dec season names in the Northern and Southern Hemispheres.

Hemisphere h0 h1 h2 h1
Northern Spring Summer Autumn Winter
Southern Autumn Winter Spring Summer
Table 4

When we keep the remainder after dividing a doy by 100, we obtain a “day of hectoday” (doh), which is the percent of an h that has elapsed. If the doy is a pid, the h is a pih: mod 100 = , but if it is a nid, the h is a nih: mod 100 = . The radix complement of the doh (100–doh) is the percent of the pih, 100 - = , or the nih, 100 - = , that is left.

\[\text{doh} = \text{doy} \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 100 \tag{16}\]

Similarly, a dox is the number of days in an x that have passed and the radix complement of a dox (10–dox) is the number of days in the x that remain. The doy in a year+day Dec date is zero padded to three digits. If the three-digit doy is a pid: , its first digit is a pih: , its last two digits are a doh: , its first two digits are a pix: , and its final digit is a dox: .

Whereas a pid gives us information on the current pix and pih, an nid tells us about the nix and nih that either are coming up next or began today. The three-digit nid in a year+day Dec date, , presents an nih with its first digit: , the days until that nih with its last two digits: , an nix with its first two digits: , and the days until that nix with its final digit: .

An nih mid, , shows the current nih with its first digit: , a doh with its last two digits: , and a dox with its final digit: . Dec recommends switching to nih mid starting with the first day of h1 to avoid uncertainty regarding when the given year will end. The last two nih mid of any year are 198 and 199. In a leap year, we may want to write 198 as 199 and 199 as 000.

and then switching to nix mid beginning with the first day of x1 An nix mid, , displays a nix, , and a dox: . , a pih mid exhibits the next pih and its (100 – doh) mod 100: , a pix mid reveals the succeeding pix and its (10 – doh) mod 10: .

We can see that h is % done from the current pid: , h will begin after the remaining % of h expires from the current pih mid: , h will start once the residual % of h elapses from the current nid: , and h is % finished from the current nih mid: . The last digit of the doh is the dox and the final digit of the 100–doh is the (10 – dox) mod 10.

\[\text{dox} = \text{doh} \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 10 \tag{17}\]

Any kind of doy can each be split into either an x and dox or an h and doh, but the vinculum in a mid can can be used to emphasize one of these two options. If we want to categorize work and rest days based on dow as in the Gregorian calendar instead of dox as in Decalendar, we can translate the “day of era” (doe) equivalent of a year+day Dec date into a dow.

3 Day of era (doe)

Dec refers to midnight on d0 as the “beginning of year” (boy). At the boy, the pid rolls over from 364 or 365 to 0. If the nid did not reset to -365 or -366 at the boy, it would continue from 1 to 0 and thus become a pid. The doe is like a nid that became a pid at the “beginning of era” (boe), midnight on d0 of Year 0 (y0), and never restarted before or after the boe.

Each of the ten Dec time zones has its own boe, doe, boy, and doy. The boe of the Zone 0 (z0) Dec time zone is called the Dec epoch. We can convert Julian day numbers (JDN) to z0 doe by subtracting the number of full days in between the start of the Julian period and the Dec epoch, which is 1721119 if the z0 time is later than noon and 1721120 otherwise.

Dec uses doe for calendrical calculations, such as finding the POSIX zero-based dow of a given date. This year, the dow of Christmas is according to Equation 18: ( + ) mod 7 = . Unlike dow, dox can be found without much effort. The dox is the last digit of the pid or equivalently the remainder after dividing the pid by 10 as per Equation 7: 299 mod 10 = 9.

\[\text{dow} = (\text{doe} + 3 - \href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{[}\text{UTC offset} < 0\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{]}) \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 7 \tag{18}\]

Equation 18 is derived from Howard Hinnant’s weekday_from_days algorithm (2021+185). The Dec epoch dow is 3 = (0 + 3) mod 7. The UNIX epoch dow is 4 = (719468 + 3) mod 7. Depending on how mod is defined, a negative doe could yield a negative dow. We can add 7 to a negative dow in the bottom row of Table 5 to obtain the positive dow above it.

Sun Mon Tue Wed Thu Fri Sat
+ 0 1 2 3 4 5 6
- 7 6 5 4 3 2 1
Table 5

Christmas is an anchored⚓️holiday because it occurs on the same pid every year. In contrast, floating🛟holidays like Thanksgiving are always planned for the same dow and thus can fall on various pid. We can use Equation 19, which is inspired by Howard Hinnant’s weekday_difference algorithm, to find the floating holiday date in a given year (2021+185).

\[\text{dow}_\Delta = (\text{dow}_\text{M} - \text{dow}_\text{S} + 7) \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 7 \tag{19}\]

In Equation 19, dowM is the minuend, dowS is the subtrahend, and dowΔ is the difference between them that ranges from 0 to 6. To get the pid of the first Dow 4 after d266, which is Thanksgiving in the United States🇺🇸and Brazil🇧🇷, we plug 4 as dowM and the dow of d267 as dowS into Equation 19, = (4 - + 7) mod 7, and then add 267: = + 267.

WarningBad Pun Alert

Deckaday the halls with dowS of holly! Fa + la × 8! ’Tis the hectoday to be jolly! Aren’t you thankful that I couldn’t thank of a Thanksgiving pun?

When the current pid is the minuend and 299 is the subtrahend, the difference is the number of days until d299 if it is negative or the days since d299 if it is positive. The current difference tells us that days d299 of this year: +299. We can then subtract the dyl to get the number of days until d299 of next year: +299-.

4 Year of era (yoe)

To obtain a doe that we can plug into Equation 18, we can use the two components of a Dec year+day date, namely a “year of era” (yoe) and a pid, to solve Equations 20, 21, 22, and 23, which are based on the days_from_civil algorithm created by Howard Hinnant and described in his manuscript entitled chrono-Compatible Low-Level Date Algorithms (2021+185).

\[\text{coe} = \biggl \lfloor \frac{\text{yoe}-399\ast\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{[}\text{yoe} \geq 0\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{]}}{400} \biggr \rfloor \tag{20}\]

\[\text{yoc} = \text{yoe} - \text{coe} \ast 400 \tag{21}\]

\[\text{doc} = \text{yoc} \ast 365 + \left\lfloor\frac{\text{yoc}}{4}\right\rfloor - \left\lfloor\frac{\text{yoc}}{100}\right\rfloor + \text{pid} \tag{22}\]

\[\text{doe} = \text{coe} \ast 146097 + \text{doc} \tag{23}\]

  • Julia
  • Observable JavaScript
  • Python
  • R
function doe(year = 1969, pid = 306)
    coe = fld(year, 400)
    yoe = year - coe * 400
    return coe * 146097 +
           yoe * 365 +
           fld(yoe, 4) -
           fld(yoe, 100) +
           pid
end
doe (generic function with 3 methods)
doe()
719468
function doe(year = 1969, pid = 306) {
  const coe = Math.floor(year / 400),
        yoe = year - coe * 400;
  return coe * 146097 +
    yoe * 365 +
    Math.floor(yoe / 4) -
    Math.floor(yoe / 100) +
    pid
}
doe()
def doe(year=1969, pid=306):
    coe = year // 400
    yoe = year - coe * 400
    return (
        coe * 146097
        + yoe * 365
        + yoe // 4
        - yoe // 100
        + pid
    )
doe()
719468
doe <- function(year = 1969, pid = 306) {
  coe <- year %/% 400
  yoe <- year - coe * 400
  coe * 146097 +
    yoe * 365 +
    yoe %/% 4 -
    yoe %/% 100 +
    pid
}
doe()
[1] 719468

Equations 24, 25, 26, 27, and 28 below are based on Howard Hinnant’s civil_from_days algorithm and useful for obtaining Dec dates from doe, UNIX timestamps, and JDN (2021+185). Regardless of whether we convert a yoe and pid to a doe or vice versa, along the way we calculate the “cycle of era” (coe), “year of cycle” (yoc), and “day of cycle” (doc).

\[\text{coe} = \left \lfloor \frac{\text{doe}-146096\ast\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{[}\text{doe} \geq 0\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{]}}{146097} \right \rfloor \tag{24}\]

\[\text{doc} = \text{doe} - \text{coe} \ast 146097 \tag{25}\]

\[\text{yoc} = \Biggl \lfloor \frac{\text{doc} - \left\lfloor \dfrac{\text{doc}}{1460} \right\rfloor + \left\lfloor \dfrac{\text{doc}}{36524} \right\rfloor - \left\lfloor \dfrac{\text{doc}}{146096} \right\rfloor}{365} \Biggr \rfloor \tag{26}\]

\[\text{yoe} = \text{yoc} + \text{coe} \ast 400 \tag{27}\]

\[\text{pid} = \text{doc} - \text{yoc} \ast 365 - \left \lfloor \frac{\text{yoc}}{4} \right \rfloor + \left \lfloor \frac{\text{yoc}}{100} \right \rfloor \tag{28}\]

  • Julia
  • Observable JavaScript
  • Python
  • R
function date(doe = 719468)
    coe = fld(doe, 146097)
    doc = doe - coe * 146097
    yoc = fld(
        doc -
        fld(doc, 1460) +
        fld(doc, 36524) -
        fld(doc, 146096),
        365
    )
    return (
        yoc + coe * 400,
        doc - (
            yoc * 365 +
            fld(yoc, 4) -
            fld(yoc, 100)
        )
    )
end
date (generic function with 2 methods)
date()
(1969, 306)
function date(doe = 719468) {
  const coe = Math.floor(doe / 146097),
    doc = doe - coe * 146097,
    yoc = Math.floor(
      (
        doc
        - Math.floor(doc / 1460)
        + Math.floor(doc / 36524)
        - Math.floor(doc / 146096)
      ) / 365
    );
  return [
    yoc + coe * 400,
    doc - (
      yoc * 365 +
      Math.floor(yoc / 4) -
      Math.floor(yoc / 100)
    )
  ];
}
date()
def date(doe=719468):
    coe = doe // 146097
    doc = doe - coe * 146097
    yoc = (
        doc
        - doc // 1460
        + doc // 36524
        - doc // 146096
    ) // 365
    return (
        yoc + coe * 400,
        doc - (
            yoc * 365 +
            yoc // 4 -
            yoc // 100
        )
    )
date()
(1969, 306)
date <- function(doe = 719468) {
  coe <- doe %/% 146097
  doc <- doe - coe * 146097
  yoc <- (
    doc -
    doc %/% 1460 +
    doc %/% 36524 -
    doc %/% 146096
  ) %/% 365
  c(
    yoc + coe * 400,
    doc - (
      yoc * 365 +
      yoc %/% 4 -
      yoc %/% 100
    )
  )
}
date()
[1] 1969  306

Dates generated by Equations 24, 25, 26, 27, and 28 are guaranteed to be in the standard yoe+pid format. Therefore, we can standardize Dec dates by converting them to doe and then back to dates again. A round-trip “date to doe to date” conversion ensures that the yoe is an integer and the pid is a positive integer less than the dyl: 0 ≤ pid < dyl.

5 Day of week (dow)

Even though Decalendar functions best with x, Dec dates can display dow by splitting a pid into a “beginning of week” (bow) and the POSIX zero-based dow. To obtain the bow, we subtract the dow from the pid: bow = pid - dow. According to the current z0 yoe+bow+dow date, , the most recent Dow 0 was on d and today is Dow .

\[\text{yoe} + \frac{\text{pid}}{\text{dyl}} = \text{yoe} + \frac{\text{bow + dow}}{\text{dyl}} \tag{29}\]

A Dec bow date can have a countup or a countdown bow. The countdown equivalent of is -. Like nid, countdown bow can be useful. We can add up to 52 weeks to any countdown bow without having to take into account the length of the year. The sum of 52 weeks and the last bow+dow of this year is 52 × 7 + + = + .

Based on the calculation above, the Dec bow date that is 52 weeks after -+ is ++. When we see the same dow in two dates, we know that difference between them is a multiple of 7. The bow can be used to refer to the current week in phrases like “the week of d” or “the week that begins with d” and thus can function like a woy.

6 Week of year (woy)

We can convert between the bow+dow in Dec bow dates and the 7×woy+dow-boydow in Dec woy dates. The boydow is the dow of the first day of the Dec year. To obtain the current woy, we sum the boydow with the current bow and then divide by 7: = ( + ) ÷ 7. Dec truncates woy dates so that they only display the yoe, woy, and dow: ++.

\[\text{bow} = 7\ast\text{woy}-\text{boydow} \tag{30}\]

If dow were like doy and reset at the boy, the boydow would always be zero and conversion between woy and bow dates would be straightforward but the reality is that we need the boydow to convert a woy date to a bow date. Dec pads the left side of the woy and bow in dates with zeros so that we can distinguish between two-digit woy and three-digit bow.

\[\text{boydow} = (7 - \text{bow}\href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod}7)\href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod}7 \tag{31}\]

To find the boydow, we first divide the bow by 7 and subtract the remainder from 7. Then, we divide the resulting difference by 7 and keep the remainder. We could also get the boydow without a bow by turning the yoe into a doe and then the doe into a dow. Dec woy dates obfuscate🫣pid much more than bow dates, but may be useful for week-based accounting🧾.

7 Day of month (dom)

Dec year+day dates can be expanded to display the “beginning of month” (bom) and POSIX dom. The bom is the last pid of the previous month because POSIX dom are one-based. We can think of the bom as Dom 0 despite the fact that no such dom exists in POSIX or the Gregorian calendar. To obtain the bom, we can subtract the dom from the pid: = – .

\[\text{bom} = \text{pid} - \text{dom} \tag{32}\]

We can find every possible bom using only a pair of hands🤲by counting index☝️and ring💍fingers as 30 days and other fingers as 31 days, as shown in the pair of images below. We start counting from -1, which is the doy that preceeds the first “month of year” (moy): Moy 0. To cover 12 months with only 10 fingers, the first and last finger each represent 2 months.

Wikimedia

Like the knuckle👊and musical keyboard🎹mnemonics, the finger🖐counting technique described above is an attempt to make sense of the irregular pattern of month lengths in the Gregorian calendar️. We do not need mnemonics, rhymes, tables, dactylonomy, or mental calculations to use h or x, because all of the required information is plainly visible in the pid.

8 Month of year (moy)

To convert a pid to or from a POSIX month and dom, we can use parts of the civil_from_days and days_from_civil algorithms (Hinnant 2021+185). POSIX months are one-based and start at Moy 10, whereas moy are zero-based and thus begin from Moy 0. To obtain a moy, we can plug a pid into Equation 33 or a POSIX month into Equation 37.

\[\text{moy} = \left\lfloor\dfrac{\text{pid} \ast 5 + 2}{153}\right\rfloor \tag{33}\]

\[\text{month} = (\text{moy} + 3) \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 12 \tag{34}\]

\[\text{bom} = \left\lfloor\dfrac{\text{moy} \ast 153 + 2}{5}\right\rfloor - \href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{[}\text{UTC offset} \ge 0\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{]} \tag{35}\]

\[\text{dom} = \text{pid} - \text{bom} \tag{36}\]

\[\text{moy} = (\text{month} + 9) \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 12 \tag{37}\]

\[\text{pid} = \text{bom} + \text{dom} \tag{38}\]

POSIX months and moy are shifted in relation to each other because the Dec epoch, 0000+000, is 2 months later than the Gregorian calendar epoch: -0001+306. To convert years, we add 1 to the yoe or subtract 1 from the Gregorian calendar️ “common era year” (cey) if the pid is greater than 305, the moy is greater than 9, or the POSIX month is less than 3.

\[ \text{cey}=\text{yoe}+\begin{cases} 1&{\begin{aligned} &\text{ if } \text{pid} \,\ \ \ \ \ \gt 305\\ &\href{https://en.wikipedia.org/wiki/Logical_disjunction}{\lor}\text{moy}\ \ \ \ \gt 9\\ &\href{https://en.wikipedia.org/wiki/Logical_disjunction}{\lor}\text{month}\lt 3\end{aligned}}\\\\ 0&{\text{ otherwise}}\end{cases} \tag{39}\]

A similar adjustment in needed when dealing with negative UTC offsets. Dec does not permit “time zone offsets” (tzo) to be negative and therefore adds one day to every negative tzo. Equation 35 takes into account the possibility of a negative UTC offset and adjusts the bom accordingly. Starting from zero, we can count every adjusted bom on our fingers.

Wikimedia

The adjusted bom in the images above are exactly the same as the values in the rightmost column of the first table under the heading “Computing day-of-year from month and day-of-month” in chrono-Compatible Low-Level Date Algorithms (Hinnant 2021+185). The adjusted and unadjusted bom can be generated using Equation 35 whenever necessary.

Dec dates can also be explained in terms of object oriented programming. In this analogy, an object is a blueprint for Dec dates and an instance represents a specific Dec date. When we create an instance, we can specify the date that it will represent by providing either a yoe and pid for it to store or a cey, month, and dom for it to convert into a yoe and pid.

Regardless of the input, only a yoe and pid are stored as instance attributes. Anything else has to be calculated from the yoe and pid by an instance method. Therefore, our instance must contain one method for every potential output that is not a yoe or pid. For example, a method based on Equations 33, 34, 35, and 36 could generate a month and dom.

Diagram 8 below visualizes how an instance that represents the UNIX epoch would convert its yoe and pid into a cey, month, dom, and dow. For simplicity, Diagram 8 omits the coe, yoc, and doc needed to convert a Dec date into a doe, the moy and bom required to split a doy into a month and a dom, and the negative UTC offset adjustment for bom and dow.

%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '20px'}}}%%
flowchart LR
   L[  ]:::empty
   B[  ]:::empty
   A[  ]:::empty
   L---Y
   L---D
   L-->E
   D---A
   D---B
   A-->G
   Y---A
   B-->M
   B-->N
   E-->W
   subgraph decdate[Decalendar]
   Y[yoe<br>1969]
   D[pid<br>306]
   E[doe<br>719468]
   end
   subgraph gregdate[Gregorian calendar]
   W[dow<br>4]
   G[cey<br>1970]
   M[month<br>1]
   N[dom<br>1]
   end
   classDef empty width:0px;
   click E "#doe"
   click W "#dow"
   click Y "#yoe"
   click D "#doy"
   click G "#eya"
   click M "#moy"
   click N "#dom"

Diagram 8

9 Request for comments (rfc)

Dec renders the Gregorian calendar obsolete with time units that supersede both months and weeks, but is also better than the Gregorian calendar at displaying a dow as a part of a date. Whereas Dec can expand pid into bow+dow, , the only standardized way to combine a dow, dom, and month is to truncate an RFC 7231 date to 11 characters: .

While bow+dow are math expressions that evaluate to pid, RFC 7231 dates are character strings that include month and dow names which are abbreviated to 3 letters. Unlike names, the math notation underlying Dec dates is universal. In contrast to the plus sign in a Dec date, , the delimiters in a RFC 9557 date are unrelated to math operators: .

Summary

At its heart❤️, Decalendar is a simple system that measures time solely in integer years and days. A Dec yoe+pid date is essentially an abbreviation of yoe+pid/dyl, which is a math expression that sums the yoe with the fraction of the year that has elapsed. The difference between the denominator and the numerator of this fraction is the number of days left in the year.

Dec can perform math operations on dates to expand them so that they display different kinds of information without changing the decimal year value that they represent. Dec expanded dates can show information relevant to the Gregorian calendar such as dom and dow. In this way, Dec date expansion bridges the gap between the Dec and Gregorian calendars.

Next

After reading this article, you should be able to understand my motivation for customizing Quarto and the examples in my filter and include articles. If you want to see the full extent of the benefits that Dec provides, I recommend that you continue through the Dec section of my site to the time⏳, snap🫰, and span🌈articles. Dec has a lot more to offer than just dates!

%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '32px'}}}%%
flowchart LR
   A[Dec]-->B[date]-->C[time]-->D[snap]-->E[span]
   Z[  ]:::empty~~~F[Quarto]-->G[filter]-->H[include]
   classDef empty width:0px;
   click A "/dec"
   click B "/dec/date"
   click C "/dec/time"
   click D "/dec/snap"
   click E "/dec/span"
   click F "/quarto"
   click G "/quarto/filter"
   click H "/quarto/include"
Diagram 9

In addition to the aforementioned articles, many other articles on my site discuss Dec. Notably, my Jupyter article compares the code underlying Dec in several programming languages, my Reveal article features a presentation that introduces Dec, and my Observable article describes how I demonstrate Dec in action with interactive and animated visualizations.

Thank you for your interest in Dec. You will find citation information for this article below. Please note that the original source of the algorithms underlying the conversion of Dec year+day dates and doe is Hinnant, Howard. 2021+185. “chrono-Compatible Low-Level Date Algorithms.” . https://howardhinnant.github.io/date_algorithms.html.

Cite

Of the bibliography file formats supported by Quarto, I recommend yaml. The yaml bibliography file shown below contains bibliographic records (metadata) about the article you are currently reading and the article entitled chrono-Compatible Low-Level Date Algorithms in which Howard Hinnant (2021+185) describes the algorithms underlying Dec dates.

ref.yml
references:
- id: hinnant2021date
  author:
    - family: Hinnant
      given: Howard
  title: [<code>chrono</code>]{.nocase}-Compatible Low-Level Date Algorithms
  url: https://howardhinnant.github.io/date_algorithms
  issued:
    literal: 2021+185
- id: laptev2026date
  author:
    - family: Laptev
      given: Martin
  title: Decalendar
  url: https://maptv.github.io/dec/date
  issued:
    literal: 2026+128

Quarto configuration files, such as _quarto.yml and _metadata.yml, are written in yaml. Quarto input files, including Quarto markdown, Jupyter notebook, markdown, and specially formatted script files, can start with a yaml header. Therefore, we could put the metadata above directly into a Quarto configuration or input file rather than into a bibliography file.

As an alternative to yaml, I suggest the BibTeX format. The BibTeX bibliography file below can be used by Quarto equally as well as the yaml bibliography file above. Regardless of the bibliography file format we choose, Quarto configuration and input files require that we store the path to our bibliography file, or our list of bibliography file paths, in yaml format.

ref.bib
@misc{hinnant2021date,
  author = "Howard Hinnant",
  title = "\texttt{chrono}-Compatible Low-Level Date Algorithms",
  url = "https://howardhinnant.github.io/date_algorithms",
  year = 2021+185
}
@misc{laptev2026date,
  author = "Martin Laptev",
  title = "Decalendar",
  url = "https://maptv.github.io/dec/date",
  year = 2026+128
}

In addition to storing metadata in a bibliography file, we can keep instructions regarding how to style citations and references in a Citation Style Language (csl) file. If we do not provide a csl file, Quarto will follow the Chicago Manual of Style when processing parenthetical citations: (Hinnant 2021+185), narrative citations: (2021+185), and references:

Hinnant, Howard. 2021+185. chrono-Compatible Low-Level Date Algorithms. https://howardhinnant.github.io/date_algorithms.html.

When provided with nature.csl, american-medical-association.csl, or a similar csl file, Quarto will produce superscript numeric citations, which look just like Quarto footnotes: 1. Unlike Quarto citations, Quarto footnotes do not require any additional files or configuration. A Quarto output file can have both a Footnotes and References section.

Glossary

  • a: arcbeat, a hundred thousandth of a circle, 0.0036 degrees, 0.216 arcminutes, 12.96 arcseconds
  • b: beat, centimilliday, a hundred thousandth of an day, 864 milliseconds
    • mb: millibeat, centimicroday, a thousandth of a beat, a hundred millionth of a day, 864 microseconds
  • bpc: a musical or heart beat per centiday, a tenth of a beat per milliday, 0.0694 beats per minute, 100 beats per day
  • bpm: a musical or heart beat per milliday, ten beats per centiday, 0.694 beats per minute, 1000 beats per day
  • bmi: body mass index, kilograins of body mass divided by height in zem squared (kg/z²)
  • c: taur, 𝜏r, 100000 kilozem, 40000 kilometers, nearly the circumference of the Earth, roughly the product of 𝜏 and the radius of the Earth, approximately the dividend of the surface area and the diameter of the Earth
    • mc: millitaur, m𝜏r, a thousandth of a taur, 100 kilozem, 40 kilometers
    • nc: nanotaur, n𝜏r, a thousandth of a taur, 100 millizem, 1 decizem, 4 centimeters
    • nc³: cubic nanotaur, n𝜏r³, 1 cubic decizem
  • d: day, a tenth of a decaday, a seventh of week, a fifth of a pentaday, 10 decidays, 24 hours, 100 centidays, 1000 millidays, 1440 minutes, 86400 seconds, 100000 beats, the inverse of a quotidie
    • dox: day of xún
    • dop: day of pentaday
    • dom: day of month
    • dow: day of week
    • doy: day of year, xún * 10 + dox
    • dd: deciday, a tenth of a day, 2.4 hours, 144 minutes
    • cd: centiday, a hundredth of a day, 0.24 hours, 14.4 minutes
    • md: milliday, a thousandth of a day, 1.44 minutes
    • cmd: centimilliday, a hundred thousandth of a day, 1 beat, 864 milliseconds
    • µd: microday, a millionth of a day, 86.4 milliseconds
    • nd: nanoday, a billionth of a day, 86.4 microseconds
  • °: degree, 1/360 turns, 180/𝜋 or 360/𝜏 radians
    • c°: compass degree
    • h°: hue degree
  • e: egg, 1000 grains, 2 ounces, 64 grams
  • ℓ: ell, cubit, 10/9 zem
  • f: foot, 0.75 zem, 75 millimeter
  • g: drop (gutta in Latin) or grain (granum in Latin), 64 microliters or 64 milligrams
    • kg: kilograin or kilodrop, 64 grams or 64 milliliters
    • Mg: megagrain or megadrop, 64 kilograms or 64 liters
  • h: a Dec season, represented by h, because Dec seasons, except for Season 3, are 1 hectoday, 10 decadays, or one hundred days long
  • hex: hexadecimal, base 16
  • hsl: hue saturation lightness
  • hsv: hue saturation value
  • i: inch, a sixteenth of a zem, 25 millimeter
  • k: keg, cubic zem, 64 liters, 1000 wine glasses, a million drops, half a barrel
  • kmph: kilometers per hour, thousands of meters per hour, 1 kmph = 0.6 mv
  • L: liter, 15625 drops, a cubic decimeter
    • mL: milliliter, a cubic centimeter, a thousandth of a liter, 15.625 drops
    • µL: microliter, a cubic millimeter, a millionth of a liter, 0.015625 drops
  • m: meridian, a full circle around the Earth moving North or South; used in the abbreviations a.m. (antemeridian) and p.m. (postmeridian); the letter “m” in meridian can be vertically flipped to get the letter “w” in wěi
    • dm: decimeridian, a tenth of a meridian
    • mm: millimeridian, a thousandth of a meridian
  • m²: square meter, 6.25 square zem
    • cm²: square centimeter, 6.25 square centizem
    • dm²: square decimeter, 6.25 square decizem
    • km²: square kilometer, 6.25 square kilozem
    • cm³: cubic centimeter, 1 millilter, a thousandth of a liter, 15.625 drops
  • p: pentaday, a group of five days, half a decaday
  • n: note, a specific frequency within an octave
  • o: octave, a two fold change in frequency
    • do: decioctave, a tenth of a two fold change in frequency
  • þ: perbeat, the inverse of a beat, 1/beat, once per beat, every beat, 100000 q; symbolized by thorn (þ), which looks like a combination of the letters “p” and “b”; not to be confused with a picobeat (pb)
    • Tþ: teraperbeat, 1012 perbeat, the inverse of a picobeat, 1/picobeat, once per picobeat, every picobeat
  • q: quotidie, the inverse of a day, a hundred thousandth of a perbeat; the letter “q” in quotidie can be flipped vertically to produce the letter “d” in day
  • r: compass rose, a full circle along the horizon, 360 compass degress
    • mr: compass millirose, a thousandth of a circle along the horizon, .36 compass degress
  • rad: radian, \(1\over\tau\) turns, \(360\over\tau\) degrees, \(1\over 2\pi\) turns, \(180\over\pi\) degrees
  • rgb: red green blue
  • s: second, 1/90 millidays, 0.9 beats, 1 Dec second = 0.96 SI seconds
  • SI: International System of Units
  • sol: speed of light, 647.55170928 kiloomegars, 299792458 meters per second
  • sos: speed of sound, 735.048 milliomegars, 340.3 meters per second
  • 𝜏: 2𝜋 or approximately 6.2831853
  • Tenet: ten equal temperament
    • Xet: Tenet
    • 12et: twelve equal temperance
  • tod: time of day
  • t: turn, 360 degrees, 𝜏 or 2𝜋 radians
    • ct: centiturn, a hundredth of a turn, 3.6 degrees, 𝜏/100 or 𝜋/50 radians
    • dt: deciturn, a tenth of a turn, 36 degrees, 𝜏/10 or 𝜋/5 radians
    • mt: milliturn, a thousandth of a turn, .36 degrees, 𝜏/1000 or 𝜋/500 r \(\pi\over 500\) radians
  • tzo: time zone offset
  • u: ounce (uncia in Latin), 500 grains, 32 grams, 500 drops, 32 milliliters
  • utc: Coordinated Universal Time
  • US: United States
  • v: omegar, ωr, 1041.6 miles per hour, 1.6 megameters per hour, 0.4629 kilometers per second, roughly 1.36 times the speed of sound
    • kv: kiloomegar, kωr, 1.6 gigameters per hour, 0.4629 megameters per second, approximately 0.1544% of the speed of light
    • mv: milliomegar, mωr, 1.0416 miles per hour, 1.6 kilometers per hour, 0.4629 meters per second, approximately 0.136% the speed of sound
  • w: wěi (纬), parallel, a measure of longitude; can be thought of as a measure of the width of a meridian on Earth; the letter “w” in wěi can be vertically flipped to get the letter “m” in meridian
    • dw: deciwěi, a tenth of a wěi (纬), a tenth of a parallel
    • mw: milliwěi, a thousanth of a wěi (纬), a thousanth of a parallel
  • x: xún (旬), decaday, a group of ten days, 2 pentadays, represented by x like the Roman numeral X
  • y: year
    • my: milliyear, a thousandth of a year
    • yoe: year of era, integer years since the Dec epoch
  • z: zem, zone equatorial meter, 4 decimeters, 16 inches
    • kz²: square kilozem, a million square zem, megahexamilliare, Mx, hexakilare, 16 hectares, 1600 ares, 40 acres, 0.16 square kilometers, 0.0625 square miles
    • kz: kilozem, 1000 zem, 400 meters, a quarter mile
    • z²: square zem, hexamilliare, 16 square decimeters, 1.7 square feet, 256 square inches
    • Dz²: square decazem, 1 hexadeciare, 16 square meters, 19.75 square yards, 100 square zem
    • z³: cubic zem, 1 keg, 64 liters, 1000 wine glasses, a million drops, half a barrel
    • dz³: cubic decizem, 1000 drops, 64 milliliters, 2 ounces, 1 wine glass
    • cz³: cubic centizem, 1 drop, 64 microliters
    • dz: decizem, a tenth of a zem, 4 centimeters
    • cz: centizem, a hundredth of a zem, 4 millimeters
    • mz: millizem, a thousandth of a zem, 0.4 millimeters
function unix2dote(unix, zone, offset = 719468) {
  return [(unix ?? Date.now()) / 86400000 + (
    zone = zone ?? -Math.round(
      (new Date).getTimezoneOffset() / 144)
    ) / 10 + offset, zone]
}
function dote2date(dote, zone = 0) {
  const cote = Math.floor((
      dote >= 0 ? dote
      : dote - 146096
    ) / 146097),
  dotc = dote - cote * 146097,
  yotc = Math.floor((dotc
    - Math.floor(dotc / 1460)
    + Math.floor(dotc / 36524)
    - Math.floor(dotc / 146096)
  ) / 365);
  return [
    yotc + cote * 400,
    dotc - (yotc * 365
      + Math.floor(yotc / 4)
      - Math.floor(yotc / 100)
  ), zone]}
function dotw2diff(x, y) {
  return (x - y + 7) % 7;
}
dz = unix2dote(Date.now())
ydz = dote2date(...dz)
function year2leap(year = 1970) {
  return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
function dote2dotw(d = 719468) {
  return d >= -3 ? (d + 3) % 7 : (d + 4) % 7 + 6
}
function unix2doty(unix) {
  const dote = (
    unix ?? Date.now()
  ) / 86400000 + 719468,
    cote = Math.floor((
      dote >= 0 ? dote
      : dote - 146096
    ) / 146097),
  dotc = dote - cote * 146097,
  yotc = Math.floor((dotc
    - Math.floor(dotc / 1460)
    + Math.floor(dotc / 36524)
    - Math.floor(dotc / 146096)
  ) / 365);
  return dotc - (yotc * 365
      + Math.floor(yotc / 4)
      - Math.floor(yotc / 100)
  )}
function date2dote(year = 1969, doty = 306, zone = 0) {
    const cote = Math.floor((year >= 0 ? year : year - 399) / 400),
      yote = year - cote * 400;
    return [cote * 146097 + yote * 365 + Math.floor(yote / 4) - Math.floor(yote / 100) + doty, zone]
}
function addN(d) { return d + 365 + leapInput }
function subN(d) { return d - 365 - leapInput }
// https://observablehq.com/@observablehq/synchronized-inputs
// https://observablehq.com/@juang1744/transform-input/1
transformInput = function(target, {bind: source, transform = identity, involutory = false, invert = involutory ? transform : inverse(transform)} = {}){
  if (source === undefined) {
    source = target;
    target = html`<div>${source}</div>`;
  }
  function sourceInputHandler() {
    target.removeEventListener("input", targetInputHandler);
    setTransform(target).to(transform(source.value)).andDispatchEvent();
    target.addEventListener("input", targetInputHandler);
  }
  function targetInputHandler() {
    source.removeEventListener("input", sourceInputHandler);
    setTransform(source).to(invert(target.value)).andDispatchEvent();
    source.addEventListener("input", sourceInputHandler);
  }
  source.addEventListener("input", sourceInputHandler);
  target.addEventListener("input", targetInputHandler);
  invalidation.then(() => {
    source.removeEventListener("input", sourceInputHandler);
    target.removeEventListener("input", targetInputHandler);
  });
  sourceInputHandler();
  return target;
}
nDaysInput = 365 + leapInput
nDaysnOffInput = nDaysInput - nOffInput
function doty2greg(doty = 0) {
    const m = Math.floor((5 * doty + 2) / 153);
    return new Date(calYear, Math.floor(m < 10 ? m + 3 : m - 9) - 1, doty - Math.floor((153 * m + 2) / 5) + 1);
}
function doty2month(doty = 1) {
    return doty2greg((doty + nDaysnOffInput) % nDaysInput).getUTCMonth() + 1
}
function doty2dotm(doty = 1) {
    return doty2greg((doty + nDaysnOffInput) % nDaysInput).getUTCDate()
}
function month2doty(month = 1) {
    return Math.floor(
        (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + nOffInput
) % nDaysInput}
function set(input, value) {
  input.value = value;
  input.dispatchEvent(new Event("input", {bubbles: true}));
}
setTransform = (input) => ({to: (value) => (input.value = value, {andDispatchEvent: (event = new Event("input")) => input.dispatchEvent(event)})});
function inverse(f) {
  switch (f) {
    case identity:  return identity;
    case Math.sqrt: return square;
    case Math.log:  return Math.exp;
    case Math.exp:  return Math.log;
    default:        return (x => solve(f, x, x));
  }
  function solve(f, y, x = 0) {
    const dx = 1e-6;
    let steps = 100, deltax, fx, dfx;
    do {
      fx = f(x)
      dfx = (f(x + dx) - fx) || dx;
      deltax = dx * (fx - y)/dfx
      x -= deltax;
    } while (Math.abs(deltax) > dx && --steps > 0);
    return steps === 0 ? NaN : x;
  }
function square(x) {
    return x * x;
  }
}
function identity(x) {
  return x;
}
// https://observablehq.com/@mbostock/scrubber
function Scrubber(values, {
  format = value => value,
  initial = 0,
  direction = 1,
  delay = null,
  autoplay = true,
  loop = true,
  loopDelay = null,
  alternate = false,
  inputStyle = ""
} = {}) {
  values = Array.from(values);
  const form = html`<form style="font: 18px var(--monospace); font-variant-numeric: tabular-nums; display: flex; height: 33px; align-items: center;">
  <button name=b type=button style="margin-right: 0.4em; width: 5em;"></button>
  <label style="display: flex; align-items: center;">
    <input name=i type=range min=0 max=${values.length - 1} value=${initial} step=1 style=${inputStyle}>
    <output name=o style="margin-left: 0.4em;"></output>
  </label>
</form>`;
  let frame = null;
  let timer = null;
  let interval = null;
  function start() {
    form.b.textContent = "Stop";
    if (delay === null) frame = requestAnimationFrame(tick);
    else interval = setInterval(tick, delay);
  }
  function stop() {
    form.b.textContent = "Play";
    if (frame !== null) cancelAnimationFrame(frame), frame = null;
    if (timer !== null) clearTimeout(timer), timer = null;
    if (interval !== null) clearInterval(interval), interval = null;
  }
  function running() {
    return frame !== null || timer !== null || interval !== null;
  }
  function tick() {
    if (form.i.valueAsNumber === (direction > 0 ? values.length - 1 : direction < 0 ? 0 : NaN)) {
      if (!loop) return stop();
      if (alternate) direction = -direction;
      if (loopDelay !== null) {
        if (frame !== null) cancelAnimationFrame(frame), frame = null;
        if (interval !== null) clearInterval(interval), interval = null;
        timer = setTimeout(() => (step(), start()), loopDelay);
        return;
      }
    }
    if (delay === null) frame = requestAnimationFrame(tick);
    step();
  }
  function step() {
    form.i.valueAsNumber = (form.i.valueAsNumber + direction + values.length) % values.length;
    form.i.dispatchEvent(new CustomEvent("input", {bubbles: true}));
  }
  form.i.oninput = event => {
    if (event && event.isTrusted && running()) stop();
    form.value = values[form.i.valueAsNumber];
    form.o.value = format(form.value, form.i.valueAsNumber, values);
  };
  form.b.onclick = () => {
    if (running()) return stop();
    direction = alternate && form.i.valueAsNumber === values.length - 1 ? -1 : 1;
    form.i.valueAsNumber = (form.i.valueAsNumber + direction) % values.length;
    form.i.dispatchEvent(new CustomEvent("input", {bubbles: true}));
    start();
  };
  form.i.oninput();
  if (autoplay) start();
  else stop();
  Inputs.disposal(form).then(stop);
  return form;
}
loadUnix = Date.now();
loadDote = unix2dote(loadUnix)
loadDate = new Date()
loadStr = loadDate.toUTCString().slice(0, 11)
loadIso = loadDate.toISOString().slice(0, 10)
loadYdz = dote2date(...loadDote)
loadLeap = year2leap(loadYdz[0])
vertic = width > 500
negtzo = loadDate.getTimezoneOffset() > 0
march1doy = 0 + nOffInput
december31doy = 305 + nOffInput
january1doy = 306 + nOffInput
november21doy = 265 + nOffInput
november22doy = 266 + nOffInput
december25doy = 299 + nOffInput
decYear = ydz[0]
nextYear = decYear + 1
decYearLeap = year2leap(decYear)
decYearLength = 365 + decYearLeap
decYearLastDoy = decYearLength - 1
decYearLastDoe = date2dote(decYear, decYearLastDoy)[0]
decYearLastDow = (decYearLastDoe + 3) % 7
decYearLastBow = decYearLastDoy - decYearLastDow
decYearLastBowNeg = Math.abs(decYearLastBow - decYearLength)
decYearLastBowNegPad = decYearLastBowNeg.toString().padStart(3, "0")
decYearLastBowSum = 364 - decYearLastBowNeg
decYearLastBowSumPad = decYearLastBowSum.toString().padStart(3, "0")
decDoty = Math.floor(ydz[1])
decDotyPad = String(decDoty).padStart(3, "0")
decNid = decDoty - decYearLength
decNidPad = decNid.toString().padStart(3, "0")
decNidAbs = Math.abs(decNid)
decNidAbsPad = decNidAbs.toString().padStart(3, "0")
decDek = Math.floor(decDoty / 10)
decDekPlus1 = decDek + 1
decPih = Math.floor(decDoty / 100)
decPihPlus1 = decPih + 1
decNix = Math.abs(Math.floor(decNid / 10))
decNih = Math.abs(Math.floor(decNid / 100))
decNihPlus1 = decNih - 1
decNixPlus1 = decNix - 1
decNixPlus1Abs = Math.abs(decNixPlus1)
decNihPlus1Abs = Math.abs(decNihPlus1)
decDohPid = decDoty % 100
decDohNid = Math.abs(decNid % 100)
decDoxNid = decDohNid % 10
decDohPidPad = decDohPid.toString().padStart(2, "0")
decDohNidPad = decDohNid.toString().padStart(2, "0")
decDohPidMid = (100 - decDohPid) % 100
decDohNidMid = (100 - decDohNid) % 100
decDoxPidMid = decDohPidMid % 10
decDoxNidMid = decDohNidMid % 10
decDohPidMidPad = decDohPidMid.toString().padStart(2, "0")
decDohNidMidPad = decDohNidMid.toString().padStart(2, "0")
decDotd = decDoty % 10
decDotdComp = 10 - decDotd
decDotdModComp = decDotdComp % 10
decDotp = decDotd % 5
decPent = decDek * 2 + (decDotd > 4)
xmasDoy = 299 + nOffInput
xmasPir = 298 + nOffInput * 3
negOrPos = nOffInput ? "negative" : "positive"
xmasDiff = decDoty - 299
xmasNext = xmasDiff - daysInYear
xmasDiffSign = xmasDiff < 0 ? "-" : "+"
xmasDiffSince = xmasDiff < 0 ? "are left until" : "have passed since"
xmasDiffResult = xmasDiff < 0 ? "-" : ""
xmasDote = date2dote(decYear, 299)[0]
xmasDotw = dote2dotw(xmasDote)
gregBoyDote = date2dote(loadYdz[0] - (loadYdz[1] < 306), 306)[0]
gregBoyDotw = (gregBoyDote + 3) % 7
loadDateStr = loadDate.toUTCString().split(" ", 4).join(" ")
dotwArr = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] 
gregBoyDotwStr = dotwArr[gregBoyDotw]
dotw = Math.floor(dote2dotw(dz[0]))
day266dotw = dote2dotw(date2dote(decYear, 266)[0])
day266dotwDiff = dotw2diff(4, day266dotw)
dotm = doty2dotm(Math.floor(ydz[1]))
dotm0 = String(dotm - 1).padStart(2, "0")
monthNumber = Math.floor(ydz[1] - dotm)
monthNumber0 = String(monthNumber + 1).padStart(3, "0")
monthNumber1 = monthNumber.toString().padStart(3, "0")
dotw0doty = Math.floor(ydz[1]) - dotw
dotw0dotyNeg = Math.abs(dotw0doty - daysInYear)
dotw0dotyPad = dotw0doty.toString().padStart(3, "0")
dotw0dotyNegPad = dotw0dotyNeg.toString().padStart(3, "0")
doty0dote = date2dote(decYear, 0)[0]
doty0dotw = dote2dotw(doty0dote)
hybridMonthWeek = monthNumber - dotw
hybridMonthWeekPad = hybridMonthWeek.toString().padStart(3, "0")
week = Math.floor((ydz[1] + doty0dotw) / 7)
weekPad = week.toString().padStart(2, "0")
dotw0sign = dotw0doty < 0 ? "-" : "+"
dotw0signIfNeg = dotw0doty < 0 ? "-" : ""
nDaysInYear = 365 + year2leap(decYear + 1)
Tminus = nDaysInYear - decDoty
TminusPadded = Tminus.toString().padStart(3, "0")
TminusPaddedNeg = "-" + TminusPadded
fracYear = decYear + ydz[1] / nDaysInYear
fullfracYear = (fracYear).toFixed(4)
mod1FracYear = (fracYear % 1).toFixed(4)
months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
monthNums = ["305", "336", "", "31", "61", "92", "122", "153", "184", "214", "245", "275"];
calYear = !leapInput && dotwInput == "Mon" ? 6 : !leapInput && dotwInput == "Tue" ? 7 : !leapInput && dotwInput == "Wed" ? 2 : !leapInput && dotwInput == "Thu" ? 3 : !leapInput && dotwInput == "Fri" ? 9 : !leapInput && dotwInput == "Sat" ? 10 : !leapInput && dotwInput == "Sun" ? 11 : leapInput && dotwInput == "Mon" ? 12 : leapInput && dotwInput == "Tue" ? 24 : leapInput && dotwInput == "Wed" ? 8 : leapInput && dotwInput == "Thu" ? 20 : leapInput && dotwInput == "Fri" ? 4 : leapInput && dotwInput == "Sat" ? 16 : leapInput && dotwInput == "Sun" ? 28 : 0;
datesCal = d3.utcDays(new Date(calYear, 0, 0), new Date(calYear, 12, 0));
leapInput = leapscrub[0]
nOffInput = leapscrub[1]
coloInput = leapscrub[2]
layoInput = leapscrub[3]
dates = d3.utcDays(new Date(1999, 2, 0), new Date(2000, 1, 28 + leapInput));
numbers = Array.from({length: 366}, (_, i) => i)
set(viewof dotyInput, leapscrub[4])
daysInYear = parseInt(365 + leapInput)
dotyInputNeg = dotyInput - daysInYear 
dotyInputDek = Math.floor(dotyInput / 10)
dotyInputDod = dotyInput % 10
piecewiseColor = d3.piecewise(d3.interpolateRgb, [
  "#f00",    //  0   0 red
  "#f50",    //  0.25  20 yr
  "#f60",    //  0.5   24 yr orangered
  "#f70",    //  0.75  28 yr
  "#f90",    //  1     36 yr orange
  "#fb0",    //  1.25  44 yr
  "#fc0",    //  1.5   48 yr yelloworange
  "#fd0",    //  1.75  52 yr
  "#ff0",    //  2     60 yellow
  "#ef0",    //  2.25  64 gy
  "#df0",    //  2.5   68 gy limeyellow
  "#cf0",    //  2.75  72 gy
  "#af0",    //  3     80 gy lime
  "#8f0",    //  3.25  88 gy
  "#7f0",    //  3.5   92 gy greenlime
  "#6f0",    //  3.75  96 gy
  "#0f0",    //  4    120 green
  "#0f7",    //  4.25 148 cg
  "#0f9",    //  4.5  156 cg cyangreen
  "#0fb",    //  4.75 164 cg
  "#0ff",    //  5    180 cyan
  "#0cf",    //  5.25 192 bc
  "#0bf",    //  5.5  196 bc azurecyan
  "#0af",    //  5.75 200 bc
  "#08f",    //  6    208 bc azure
  "#06f",    //  6.25 216 bc
  "#05f",    //  6.5  220 bc blueazure
  "#04f",    //  6.75 224 bc
  "#00f",    //  7    240 blue
  "#50f",    //  7.25 260 mb
  "#60f",    //  7.5  264 mb purpleblue
  "#70f",    //  7.75 268 mb
  "#90f",    //  8    276 mb purple
  "#b0f",    //  8.25 284 mb
  "#c0f",    //  8.5  288 mb violetpurple
  "#d0f",    //  8.75 292 mb
  "#f0f",    //  9    300 magenta
  "#f0a",    //  9.25 320 rm
  "#f08",    //  9.5  328 rm
  "#f06",    //  9.75 336 rm
  "#f00",    //  0        0 red
])
function yiq(color) {
  const {r, g, b} = d3.rgb(color);
  return (r * 299 + g * 587 + b * 114) / 1000 / 255; // returns values between 0 and 1
}
day364rgb = piecewiseColor(364 / 365)
day365rgb = piecewiseColor(365 / 366)
seldow = seldat.map(x => x.getUTCDay())
selwee = seldat.map(d => d3.utcWeek.count(d3.utcYear(d), d))
seldat = datesCal.filter((d, i) => ((i + 365 - 59 + nOffInput) % (365 + leapInput)) === dotyInput)
dekLeapColors = d3.range(37).map(x => piecewiseColor(x * 10 / 366))
dekCommColors = d3.range(37).map(x => piecewiseColor(x * 10 / 365))
leaps = d3.range(366).map(x => piecewiseColor(x / 366))
comms = d3.range(365).map(x => piecewiseColor(x / 365))
moty = ["March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "January", "February"];
motyColors = d3.range(12).map(moty2doty).map(x => piecewiseColor(x / daysInYear))
function moty2doty(moy = 1) {
  return (Math.floor(
    (153 * moy + 2) / 5
) + nOffInput) % daysInYear}
easyDoy = dotyInput < (80 + leapInput) ? dotyInput : dotyInputNeg
easySum = easyDoy + 285
binopttop = ({
  type: 'uint16',
  value: ranintop,
  displayParts: false,
  format: false,
  byteSeparation: false
})
binoptbtm = ({
  type: 'uint16',
  value: raninbtm,
  displayParts: false,
  format: false,
  byteSeparation: false
})
templateFunction = inputs => htl.html`<div style="display: flex;">${inputs}</div>`
b32js = "0123456789abcdefghijklmnopqrstuv";
b32pl = "AÁBCDEÉFGHIÍJKLMNOÓPQRSTUÚVWXYÝZ";
toPolishMap = Object.fromEntries(
  [...b32js].map((c, i) => [c, b32pl[i]])
);
toBase32map = Object.fromEntries(
  [...b32pl].map((c, i) => [c, b32js[i]])
);
function toPolish(str) {
  return [...str.toLowerCase()]
    .map(c => toPolishMap[c] ?? c)
    .join("");
}
function toBase32(str) {
  return [...str]
    .map(c => toBase32map[c] ?? c)
    .join("");
}
function leftShift() {
  const [top, btm] = rotatePair(ranintop, raninbtm, multiplier, true, true)
  set(viewof ranintop, top)
  set(viewof raninbtm, btm)
}
function leftRotate() {
  const [top, btm] = rotatePair(ranintop, raninbtm, multiplier, true, false)
  set(viewof ranintop, top)
  set(viewof raninbtm, btm)
}
function rightShift() {
  const [top, btm] = rotatePair(ranintop, raninbtm, multiplier, false, true)
  set(viewof ranintop, top)
  set(viewof raninbtm, btm)
}
function rightRotate() {
  const [top, btm] = rotatePair(ranintop, raninbtm, multiplier, false, false)
  set(viewof ranintop, top)
  set(viewof raninbtm, btm)
}
function reverseBits() {
  const [top, btm] = reverseSplit(ranintop, raninbtm, multiplier, 5)
  set(viewof ranintop, top)
  set(viewof raninbtm, btm)
}
function stepPattern() {
  const [top, btm] = stepGenerate(ranintop, raninbtm, multiplier, 5)
  set(viewof ranintop, top)
  set(viewof raninbtm, btm)
}
function reverseSplit(top, btm, split = 1, halflen = 5) {
  const len = halflen * 2;
  const mask = (1 << halflen) - 1;
  let combined = ((top & mask) << halflen) | (btm & mask);
  let out = 0;
  const baseSize = Math.floor(len / split);
  const remainder = len % split;
  let pos = 0;
  for (let i = 0; i < split; i++) {
    const size = baseSize + (i >= split - remainder ? 1 : 0);
    for (let j = 0; j < size; j++) {
      const from = pos + j;
      const to = pos + (size - 1 - j);
      const bit = (combined >>> (len - 1 - from)) & 1;
      out |= bit << (len - 1 - to);
    }
    pos += size;
  }
  return [
    (out >>> halflen) & mask,
    out & mask
  ];
}
function stepGenerate(top, btm, step = 1, halflen = 5) {
  const length = halflen * 2;
  const mask = (1 << halflen) - 1;
  const combined = ((top & mask) << halflen) | (btm & mask);
  let out = 0;
  for (let i = 0; i < length; i++) {
    const bit = (i % step === 0) ? 1 : 0;
    out |= bit << (length - 1 - i);
  }
  return [
    (out >>> halflen) & mask,
    out & mask
  ];
}
schedBase10 = ranintop === raninbtm ? ranintop : ranintop << 5 | raninbtm
schedBinary = ranintop === raninbtm ? ranintop.toString(2).padStart(5, "0") : schedBase10.toString(2).padStart(10, "0")
schedBase32 = selintop === selinbtm ? selintop : selintop + selinbtm
function rotatePair(top, btm, distance = 1, left = true, shift = true) {
  const combined = top << 5 | btm;
  distance = (distance % 10 + 10) % 10;
  const rotated = left
    ? (shift ? combined << distance : ((combined << distance) | (combined >>> (10 - distance)))) & 1023
    : (shift ? combined >> distance : ((combined >>> distance) | (combined << (10 - distance)))) & 1023;
  return [rotated >>> 5, rotated & 31];
}
// https://observablehq.com/@rreusser/binary-input
function binaryInput(opts) {
  var type = opts.type;
  var byteSeparation =
    opts.byteSeparation === undefined ? '5px' : opts.byteSeparation;
  var format = opts.format === undefined ? x => x : opts.format;
  var displayParts =
    opts.displayParts === undefined ? false : opts.displayParts;
  var fractionalSignificand =
    opts.fractionalSignificand === undefined
      ? false
      : !!opts.fractionalSignificand;
  var outputAsBytes =
    opts.outputAsBytes === undefined ? false : !!opts.outputAsBytes;
  var BigInt64Array = window.BigInt64Array;
  var BigUint64Array = window.BigUint64Array;
  var BigInt = window.BigInt;
  var Ctor;
  var length;
  var signLength = 0;
  var exponentLength = 0;
  var offset = 0;
  switch (type) {
    case 'float16':
      Ctor = Float32Array;
      length = 16;
      signLength = 1;
      exponentLength = 5;
      offset = 15;
      break;
    case 'float':
    case 'float32':
      Ctor = Float32Array;
      length = 32;
      signLength = 1;
      exponentLength = 8;
      offset = 127;
      break;
    case 'double':
    case 'float64':
      Ctor = Float64Array;
      length = 64;
      signLength = 1;
      exponentLength = 11;
      offset = 1023;
      break;
    case 'uint8':
      Ctor = Uint8Array;
      length = 8;
      break;
    case 'int8':
      Ctor = Int8Array;
      length = 8;
      signLength = 1;
      break;
    case 'uint16':
      Ctor = Uint16Array;
      length = 16;
      break;
    case 'int16':
      Ctor = Int16Array;
      length = 16;
      signLength = 1;
      break;
    case 'uint32':
      Ctor = Uint32Array;
      length = 32;
      break;
    case 'int32':
      Ctor = Int32Array;
      length = 32;
      signLength = 1;
      break;
    case 'uint64':
      Ctor = BigUint64Array;
      length = 64;
      signLength = 0;
      break;
    case 'int64':
      Ctor = BigInt64Array;
      length = 64;
      signLength = 1;
      break;
    default:
      throw new Error(
        `Unexpected type "${type}". Options are 'float' ('float32'), 'double' ('float64'), 'uint8', 'int8', 'uint16', 'int16', 'uint32', and 'int32'`
      );
  }
  if (
    !window.BigInt &&
    exponentLength &&
    fractionalSignificand &&
    length > 32
  ) {
    throw new Error(
      'BigInt support must be present to display fractions for single or double precision floats'
    );
  }
  // If we don't need anything special, fake it with a pass-through
  var BigInt =
    window.BigInt ||
    function(x) {
      return x;
    };
  var valueAsArray;
  var bytes;
  if (type === 'float16') {
    // Typed array interpretation-style casting doesn't work for float16 since
    // JavaScript doesn't support it. Instead we'll have to do this manually.
    bytes = new Uint8Array(2);
    if (opts.literalValue !== undefined) {
      bytes[0] = opts.literalValue & 0x00ff;
      bytes[1] = (opts.literalValue & 0xff00) >> 8;
    } else if (opts.value !== undefined) {
      var floatValue = new Float32Array([opts.value]);
      var floatBytes = new Uint8Array(floatValue.buffer);
      var signBit = (floatBytes[3] & 0b10000000) >> 7;
      var exponent32 =
        ((floatBytes[3] & 0b01111111) << 1) |
        ((floatBytes[2] & 0b10000000) >> 7);
      var exponent16 = exponent32 - 127 + 15;
      var significand =
        ((floatBytes[2] & 0b01111111) << 3) |
        ((floatBytes[1] & 0b11100000) >> 5);
      bytes[1] =
        (signBit << 7) |
        (exponent16 << 2) |
        ((significand & 0b1100000000) >> 8);
      bytes[0] = significand & 0b11111111;
    }
  } else {
    if (opts.literalValue === undefined) {
      var value = opts.value === undefined ? 0 : opts.value;
      valueAsArray = new Ctor([
        Ctor === BigInt64Array || Ctor === BigUint64Array
          ? BigInt(value)
          : value
      ]);
      bytes = new Uint8Array(valueAsArray.buffer);
    } else {
      valueAsArray = new Ctor([
        Ctor === BigInt64Array || Ctor === BigUint64Array ? BigInt(0) : 0
      ]);
      bytes = new Uint8Array(valueAsArray.buffer);
      for (var i = 0; i < length >> 3; i++) {
        bytes[i] = (opts.literalValue & (0xff << (i * 8))) >> (i * 8);
      }
    }
  }
  const container = document.createElement('div');
  if (opts.title) {
    const title = document.createElement('div');
    title.style.font = '700 0.9rem sans-serif';
    title.textContent = opts.title;
    title.style.marginBottom = '0.2rem';
    container.appendChild(title);
  }
  const editor = document.createElement('div');
  container.appendChild(editor);
  editor.style.fontFamily = 'monospace';
  editor.style.fontSize = '0.9rem';
  // Debatable. It's easy to accidentally select when trying to toggle bits.
  editor.style.userSelect = 'none';
  let debugEl;
  if (true) {
    debugEl = document.createElement('div');
    editor.appendChild(debugEl);
  }
  let output, partsDisplay;
  const outputContainer = document.createElement('div');
  container.append(outputContainer);
  if (format) {
    output = document.createElement('output');
    output.style.font = '14px Menlo, Consolas, monospace';
    outputContainer.appendChild(output);
  }
  if (displayParts) {
    partsDisplay = document.createElement('span');
    outputContainer.appendChild(partsDisplay);
  }
  if (opts.description) {
    const description = document.createElement('div');
    description.style.fontSize = '0.85rem';
    description.style.fontStyle = 'italic';
    description.textContent = opts.description;
    container.appendChild(description);
  }
  function getBit(bit) {
    // bit >> 3 divides by eight and tells which byte this belongs to
    // bit & 0x7 gives the rest of the location. So basically we shift
    // the value right to isolate the correct byte, then and it with the
    // particular bit we want.
    return bytes[bit >> 3] & (0x1 << (bit & 0x7)) ? 1 : 0;
  }
  function getSignBit() {
    if (!signLength) return 0;
    return bytes[bytes.length - 1] & 0x80;
  }
  function getMantissaBits() {
    if (!exponentLength) return valueAsArray[0] & ~(1 << (length - 1));
    switch (length) {
      case 16:
        return bytes[0] | ((bytes[1] & 0x3) << 8);
      case 32:
        return ((bytes[2] & 0x7f) << 16) | (bytes[1] << 8) | bytes[0];
      case 64:
        return (
          ((BigInt(bytes[6]) & BigInt(0xf)) << BigInt(48)) +
          (BigInt(bytes[5]) << BigInt(40)) +
          (BigInt(bytes[4]) << BigInt(32)) +
          BigInt(
            (bytes[3] << 24) + (bytes[2] << 16) + (bytes[1] << 8) + bytes[0]
          )
        );
    }
  }
  function getExponentBits() {
    if (!exponentLength) return 0;
    switch (length) {
      case 64:
        return ((bytes[7] & 0x7f) << 4) | (bytes[6] >> 4);
      case 32:
        return ((bytes[3] & 0x7f) << 1) | (bytes[2] >> 7);
      case 16:
        return (bytes[1] & 0x7c) >> 2;
    }
  }
  function getSign() {
    return getSignBit() ? -1 : 1;
  }
  function isDenormal() {
    if (!exponentLength) return false;
    switch (length) {
      case 64:
        return (
          !(bytes[bytes.length - 1] & 0x7f) && !(bytes[bytes.length - 2] & 0xf0)
        );
      case 32:
        return (
          !(bytes[bytes.length - 1] & 0x7f) && !(bytes[bytes.length - 2] & 0x80)
        );
      case 16:
        return !(bytes[1] & 0x7c);
    }
  }
  function getMantissa() {
    if (type === 'float16') {
      return (
        (bytes[0] | ((bytes[1] & 0x3) << 8)) / 1024 + (isDenormal() ? 1 : 0)
      );
    }
    var bytesCopy = new Uint8Array(bytes.slice());
    var normalOffset = 0;
    var typedMantissa = new Ctor(bytesCopy.buffer);
    if (exponentLength) {
      bytesCopy[bytesCopy.length - 1] = 0x3f;
      bytesCopy[bytesCopy.length - 2] =
        bytesCopy[bytesCopy.length - 2] | (length === 32 ? 0x80 : 0xf0);
    } else if (signLength) {
      if (!exponentLength && getSign() === -1) {
        for (var i = 0; i < bytesCopy.length; i++) {
          bytesCopy[i] = ~bytesCopy[i];
        }
        normalOffset = 1;
      }
      // Unset the sign bit
      bytesCopy[bytesCopy.length - 1] = bytesCopy[bytesCopy.length - 1] & 0x7f;
    }
    if (normalOffset) {
      typedMantissa[0] += normalOffset;
    }
    return typedMantissa[0];
  }
  function getExponentBits() {
    if (!exponentLength) return 0;
    switch (length) {
      case 64:
        return ((bytes[7] & 0x7f) << 4) | (bytes[6] >> 4);
      case 32:
        return ((bytes[3] & 0x7f) << 1) | (bytes[2] >> 7);
      case 16:
        return (bytes[1] & 0x7c) >> 2;
    }
  }
  function getExponent() {
    if (!exponentLength) return 0;
    switch (length) {
      case 64:
        return Math.max(-1022, getExponentBits() - 0x3ff);
      case 32:
        return Math.max(-126, getExponentBits() - 0x7f);
      case 16:
        return Math.max(-14, getExponentBits() - 0xf);
    }
  }
  function getValue() {
    if (type === 'float16') {
      // Javascript doesn't support half-float, so we'll tease it apart and insert
      // the corresponding parts into a float32 instead.
      var floatBytes = new Uint8Array(4);
      // Isolate the sign bit:
      var signBit = (bytes[1] & 0b10000000) >> 7;
      // Isolate the mantissa
      var mantissa = ((bytes[1] & 0b00000011) << 8) | bytes[0];
      // Isolate the exponent:
      var exponent16 = (bytes[1] & 0b01111100) >> 2;
      var exponent32 = exponent16 - 15 + 127;
      if (exponent16 === 0) {
        // Subnormal. This one is tricky so we'll just do it mathematically instead of bitwise
        return (signBit > 0 ? -1 : 1) * Math.pow(2, -14) * (mantissa / 1024);
      } else if (exponent16 === 31) {
        // Transfer this special case into the 32-bit exponent
        exponent32 = 255;
      }
      // Combine the sign and exponent into the first byte
      floatBytes[3] = (signBit << 7) | ((exponent32 & 0b11111110) >> 1);
      floatBytes[2] =
        ((exponent32 & 0b1) << 7) | ((mantissa & 0b1111111000) >> 3);
      floatBytes[1] = (mantissa & 0b00000111) << 5;
      floatBytes[0] = 0;
      return new Float32Array(floatBytes.buffer)[0];
    }
    return valueAsArray[0];
  }
  const bitSpans = [];
  function writeBits() {
    for (var i = 0; i < length; i++) {
      bitSpans[i].textContent = getBit(i);
    }
    if (output) output.textContent = format(getValue());
    if (partsDisplay) {
      let el = document.createElement('span');
      el.appendChild(tex`\; = \;`);
      if (signLength) {
        let signContainer = document.createElement('span');
        signContainer.appendChild(tex`${getSign()}`);
        signContainer.style.backgroundColor = 'rgba(0, 0, 210, 0.25)';
        signContainer.style.padding = '0 0.15em';
        el.append(signContainer);
        el.appendChild(tex`\; \times \;`);
      }
      if (exponentLength) {
        let exponentContainer = document.createElement('span');
        exponentContainer.appendChild(tex`2^{${getExponent()}}`);
        exponentContainer.style.backgroundColor = 'rgba(0, 210, 0, 0.25)';
        exponentContainer.style.padding = '0 0.15em';
        el.append(exponentContainer);
        el.appendChild(tex`\; \times \;`);
      }
      var mantissaContainer = document.createElement('span');
      if (exponentLength && fractionalSignificand) {
        mantissaContainer.appendChild(
          tex`\left(${
            isDenormal() ? 0 : 1
          } + \frac{${getMantissaBits()}}{${BigInt(1) <<
            BigInt(length - signLength - exponentLength)}}\right)`
        );
      } else {
        var mantissaStr = getMantissa().toString();
        if (isDenormal()) mantissaStr = mantissaStr.replace(/^1/, '0');
        mantissaContainer.appendChild(tex`${mantissaStr}`);
      }
      mantissaContainer.style.backgroundColor = 'rgba(210, 0, 0, 0.25)';
      mantissaContainer.style.padding = '0 0.15em';
      el.appendChild(mantissaContainer);
      if (partsDisplay.firstChild) partsDisplay.firstChild.remove();
      partsDisplay.appendChild(el);
    }
    container.value = outputAsBytes ? bytes : getValue();
  }
  var curBit = 0;
  function toggleBit(bit, event) {
    curBit = bit;
    bitSpans[curBit].focus();
    // Similar to above, we isolate the bit we're interested in, then
    // construct the bit we want to toggle. Typed array casting via buffer
    // views magically handles interpretation for us.
    bytes[bit >> 3] = bytes[bit >> 3] ^ (0x1 << (bit & 0x7));
    writeBits();
    container.dispatchEvent(new CustomEvent('input'));
  }
  function setBit(bit, value) {
    curBit = bit;
    if (value) {
      bytes[bit >> 3] = bytes[bit >> 3] | (0x1 << (bit & 0x7));
    } else {
      bytes[bit >> 3] = bytes[bit >> 3] & ~(0x1 << (bit & 0x7));
    }
    writeBits();
    container.dispatchEvent(new CustomEvent('input'));
  }
  function nextBit() {
    curBit++;
    bitSpans[curBit].focus();
  }
  function prevBit() {
    if (curBit === length - 1) return false;
    curBit++;
    bitSpans[curBit].focus();
    return true;
  }
  function nextBit() {
    if (curBit === 0) return false;
    curBit--;
    bitSpans[curBit].focus();
    return true;
  }
  function focusBit(i) {
    curBit = i;
  }
  function handleKeypress(event) {
    switch (event.keyCode) {
      case 8:
        setBit(curBit, 0);
        prevBit();
        event.preventDefault();
        break;
      case 9:
        if (event.shiftKey) {
          if (prevBit()) event.preventDefault();
        } else {
          if (nextBit()) event.preventDefault();
        }
        break;
      case 37:
        if (prevBit()) event.preventDefault();
        break;
      case 39:
        if (nextBit()) event.preventDefault();
        break;
      case 48:
        setBit(curBit, 0);
        nextBit();
        event.preventDefault();
        break;
      case 49:
        setBit(curBit, 1);
        nextBit();
        event.preventDefault();
        break;
    }
  }
  let bit = length - 1;
  for (let byte = bytes.length - 1; byte >= 0; byte--) {
    const byteSpan = document.createElement('span');
    byteSpan.style.display = 'inline-block';
    byteSpan.style.marginRight = byteSeparation;
    byteSpan.style.marginBottom = '2px';
    for (let i = 0; i < 8; i++) {
      const bitSpan = document.createElement('button');
      byteSpan.append(bitSpan);
      bitSpans.unshift(bitSpan);
      bitSpan.style.width = '15px';
      bitSpan.style.height = '20px';
      bitSpan.style.display = 'inline';
      bitSpan.style.border = '1px solid black';
      bitSpan.style.verticalAlign = 'middle';
      bitSpan.style.padding = '0';
      bitSpan.style.textAlign = 'center';
      bitSpan.style.marginRight = '-1px';
      bitSpan.style.lineHeight = '20px';
      bitSpan.style.cursor = 'pointer';
      bitSpan.style.fontFamily = 'monospace';
      bitSpan.style.borderRadius = 0;
      bitSpan.style.fontSize = '0.9rem';
      bitSpan.style.backgroundColor = 'transparent';
      if (signLength > 0 || exponentLength > 0) {
        if (bit < length - signLength - exponentLength) {
          bitSpan.style.backgroundColor = 'rgba(210, 0, 0, 0.25)';
        } else if (bit < length - signLength) {
          bitSpan.style.backgroundColor = 'rgba(0, 210, 0, 0.25)';
        } else {
          bitSpan.style.backgroundColor = 'rgba(0, 0, 210, 0.25)';
        }
      }
      bitSpan.addEventListener('focus', focusBit.bind(null, bit));
      bitSpan.addEventListener('click', toggleBit.bind(null, bit));
      bit--;
    }
    editor.append(byteSpan);
  }
  editor.addEventListener('keydown', handleKeypress);
  writeBits();
  container.value = outputAsBytes ? bytes : getValue();
  return container;
}
temps = await FileAttachment("temps.json").json()
// Adapted from https://observablehq.com/@observablehq/filtering-several-charts-1871
function renderFilter(initialTest = true) {
  const updates = new Array(); // 🌶🌶 support sharing across charts; needs invalidation
  // see https://observablehq.com/@observablehq/plot-brush-crossfilter-1653#analyzer for a technique
  return Object.assign(
    function apply(options) {
      return {
        ...options,
        render(index, scales, values, dimensions, context, next) {
          const data = temps;
          //const { data } = values;
          const filter = (test) =>
            typeof test === "function"
              ? index.filter((i) => test(data[i], i, data))
              : test
              ? index
              : [];
          let g = next(
            filter(initialTest),
            scales,
            values,
            dimensions,
            context
          );
          updates.push((test) => {
            const transform = g.getAttribute("transform");
            g.replaceWith(
              (g = next(filter(test), scales, values, dimensions, context))
            );
            g.setAttribute("transform", transform); // facet translate
          });
          return g;
        }
      };
    },
    {
      update(test) {
        return updates.map((update) => update?.(test));
      }
    }
  );
}
html`
<style>
#calplots {
  gap: 3px ${!layoInput * 9}px;
}
#decplot figure h2 {
  transform: translateX(${!layoInput * 15}px);
}
#greplot figure h2 {
  transform: translate(${!layoInput * 18}px, ${(!layoInput && (!leapInput || dotwInput !== "Sat")) * 6}px);
}
p:has(.radiotitle) {
  margin-top: -${layoInput ? 16 : 24}px;
  margin-bottom: -${width > 500 ? 6 : 9}px;
}
#calplots > div.cell {
  width: ${layoInput ? "100%" : "unset"};
}
#calplots > div.cell svg {
  width: ${layoInput ? "100%" : "unset"};
}
#fig-zerocomm.doxdiagram > figure {
  margin-top: -${width > 500 ? 21 : 9}px;
}
#fig-zeroleap.doxdiagram > figure {
  margin-top: -${width > 500 ? 18 : 5}px;
}
</style>
`
Back to top

References

Hinnant, Howard. 2021+185. chrono-Compatible Low-Level Date Algorithms. https://howardhinnant.github.io/date_algorithms.
Jukic, A.M., D.D. Baird, C.R. Weinberg, D.R. McConnaughey, and A.J. Wilcox. 2013+215. “Length of Human Pregnancy and Contributors to Its Natural Variation.” Human Reproduction 28 (10): 2848–55. https://doi.org/10.1093/humrep/det297.

Footnotes

  1. Hinnant, Howard. 2021+185. chrono-Compatible Low-Level Date Algorithms. https://howardhinnant.github.io/date_algorithms.html.↩︎

Reuse

CC BY-SA 4.0
Dec
Time
Source Code
---
title: Decalendar
description: >
  Introducing Decalendar, a solar calendar
  which measures time in years and days
  without the need for months or weeks.
image: /asset/cal16.svg
url: https://maptv.github.io/dec/date
decdate: 2026+128
path: /dec/date
slug: date
aliases:
  - /date
  - /dd
engine: knitr
crossref:
  fig-prefix: Diagram
  fig-title: Diagram
---

:::{.datenav #fig-topdatenav}
{{< include /asset/_decnav.qmd >}}
:::

# Decalendar {#decalendar .unnumbered .hiddenheading}

My website serves as a demonstration of both the [Quarto](https://quarto.org) publishing📤system and the [Dec](/dec) measurement📐system. I use several clever hacks to get Quarto to display all of the dates on my website in the Dec year+day format. Knowing the basics of the Dec calendar🗓️(Decalendar) will help you to understand the [filter](https://quarto.org/docs/extensions/filters.html) and [include](https://quarto.org/docs/output-formats/html-basics.html#includes) articles in the [Quarto section](/quarto) of my site.

Among its many features, Quarto offers support for the [Observable](https://observablehq.com/) data visualization system. Observable is my top choice for interactive graphics. We can interact with the two Observable [calendar plots](https://observablehq.com/@observablehq/plot-calendar)
below⬇️using the adjacent Observable [inputs](https://observablehq.com/documentation/inputs/overview). The [scrubber](https://observablehq.com/@mbostock/scrubber)🧽input is a great place to start because it cycles🔄through every value of the [range](https://observablehq.com/@observablehq/input-range)🎚️inputs beneath it.

# Day of year (doy) {#sec-doy}

To activate the scrubber input, press the "Play"▶️button above⬆️the range inputs. Upon activation, the box around the selected day in each plot will move back and forth between the first "day of year" ([doy](#doy){#dayofyear .tool data-bs-toggle="tooltip" data-bs-title="day of year"}), [d]{#day .tool data-bs-toggle="tooltip" data-bs-title="day"}[0]{.color0}, and the last [doy](#doy){.tool data-bs-toggle="tooltip" data-bs-title="day of year"}, which is either [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[364]{.color364by365} or [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[365]{.color365by366}. To insert or remove [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[365]{.color365by366}, use the "Year length" [radio](https://observablehq.com/@observablehq/input-radio)📻input to set the number of days in the year.

The insertion of [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[365]{.color365by366} shifts 306 dates, [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}\${march1doy} to [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}\${december31doy}, in the [Gregorian calendar](https://en.wikipedia.org/wiki/Gregorian_calendar#:~:text=the%20calendar%20used%20in%20most%20parts%20of%20the%20world) by 1 day, but does not change the order of any Dec dates, because [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[365]{.color365by366} is the last day of any Dec leap year and is always followed by [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[0]{.color0} of the subsequent Dec year ([y]{.tool data-bs-toggle="tooltip" data-bs-title="year"}+1). The "Year length" radio input also changes the value of the negative "Day of year" range input by 1 day.

Similarly, the "[Coordinated Universal Time](https://en.wikipedia.org/wiki/Coordinated_Universal_Time#:~:text=the%20primary%20time%20standard%20globally%20used%20to%20regulate%20clocks%20and%20time) ([UTC](#utc){#coordinateduniversaltime .tool data-bs-toggle="tooltip" data-bs-title="Coordinated Universal Time"}) [offset](https://en.wikipedia.org/wiki/UTC_offset#:~:text=the%20difference%20in%20hours%20and%20minutes%20between%20Coordinated%20Universal%20Time%20(UTC)%20and%20the%20standard%20time%20at%20a%20particular%20place)" radio input shifts the Gregorian calendar date selected by the "Month" and "Day of month" range inputs by 1 day. The "UTC offset" radio input will also shift the Decalendar plot [cell](https://observablehq.com/plot/marks/cell) colors🎨by 1 day if the "[Color scheme](https://en.wikipedia.org/wiki/Color_scheme#:~:text=a%20combination%20of%202%20or%20more%20colors%20used%20in%20aesthetic%20or%20practical%20design)" radio input is set to the "Month" [discrete scheme](https://en.wikipedia.org/wiki/Color_scheme#:~:text=feature%20only%20a%20certain%20subset%20of%20a%20continuous%20color%20scheme) instead of the "Day" [continuous scheme](https://en.wikipedia.org/wiki/Color_scheme#:~:text=display%20sets%20of%20continuous%2C%20ordered%20data).

From the perspective of Dec, month color labels🏷️are only useful if we want to compare the Dec and Gregorian calendars. In contrast, Dec day color labels can help us sort days into groups of 100 called [hectodays]{.tool data-bs-toggle="tooltip" data-bs-title="hundreds of days"} ([h](#h){#hectoday .tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}) and groups of 10 named [xún](https://en.wikipedia.org/wiki/Chinese_calendar#:~:text=into%20nine%2D%20or-,ten%2Dday%20weeks,-known%20as%20x%C3%BAn) ([x](#x){#xun .tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"}). Dec defines [meterological seasons](https://en.wikipedia.org/wiki/Season#Meteorological:~:text=reckoned%20by%20temperature) in terms of [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"} and uses [x]{.tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"} instead of Gregorian calendar months and weeks.

The "Plot layout" radio input rotates the calendar plots by a quarter turn, interchanging the horizontal (↔) and vertical (↕) axes. The axis labels demonstrate that [x]{.tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"} and "days of xún" ([dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"}) are analogous to weeks and "days of week" ([dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}). If we multiply an [x]{.tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"} \${layoInput ? "↔" : "↕"} axis label by ten and add it to a [dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} \${layoInput ? "↕" : "↔"} axis label, we get a "positive integer [doy]{.tool data-bs-toggle="tooltip" data-bs-title="day of year"}" ([pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"}) cell value: \${dotyInputDek} &times; 10 + \${dotyInputDod} = ${dotyInput}.

::: {.column-margin .overflowequation}
$$\text{pid} = \text{x} \ast 10 + \text{dox}$$ {#eq-pid}
$$\text{dyl} = \text{pid} - \text{nid}$$ {#eq-dyl}
:::

There are two range inputs labelled "Day of year" because every [doy]{.tool data-bs-toggle="tooltip" data-bs-title="day of year"} can be expressed as either a positive or a negative integer. The [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} is the number of days that have passed in the year, the [absolute value](https://en.wikipedia.org/wiki/Absolute_value#:~:text=non%2Dnegative%29-,magnitude%20of,measured%20without%20regard%20to%20its%20sign,-.%20Namely%2C) of the "negative integer [doy]{.tool data-bs-toggle="tooltip" data-bs-title="day of year"}" ([nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"}) is the number of days left in the year, and their [difference](https://en.wikipedia.org/wiki/Subtraction#Notation_and_terminology:~:text=The%20result%20is%20the%20difference) is the "Decalendar year length" ([dyl]{.tool data-bs-toggle="tooltip" data-bs-title="Decalendar year length"}), which can be [365]{.color364by365} or [366]{.color365by366}.

:::{#calobservable}
{{< include /dec/date/_calplots.qmd >}}
:::

The distinction between [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} and [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} can be explained in terms of [computer programming](https://en.wikipedia.org/wiki/Computer_programming#:~:text=the%20composition%20of%20sequences%20of%20instructions%2C%20called%20programs%2C%20that%20computers%20can%20follow%20to%20perform%20tasks). If we think of a year as an [array](https://en.wikipedia.org/wiki/Array_(data_structure)#Element_identifier_and_addressing_formulas:~:text=a%20data%20structure%20consisting%20of%20a%20collection%20of%20elements%20(values%20or%20variables)%2C%20of%20same%20memory%20size%2C%20each%20identified%20by%20at%20least%20one%20array%20index) and each day as an array element, [dyl]{.tool data-bs-toggle="tooltip" data-bs-title="Decalendar year length"} is the number of elements in the array, [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} is a [positive](https://en.wikipedia.org/wiki/Zero-based_numbering#:~:text=a%20way%20of%20numbering%20in%20which%20the%20initial%20element%20of%20a%20sequence%20is%20assigned%20the%20index%C2%A00) index, and [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} is a [negative index](https://en.wikipedia.org/wiki/Array_slicing#:~:text=specify%20an%20offset%20from%20the%20end%20of%20the%20array). Array [indexes](https://en.wikipedia.org/wiki/Array_(data_structure)#Element_identifier_and_addressing_formulas:~:text=individual%20objects%20are%20selected%20by%20an%20index) can be used to obtain specific array elements individually via indexing or in groups via [array slicing](https://en.wikipedia.org/wiki/Array_slicing#:~:text=an%20operation%20that%20extracts%20a%20subset%20of%20elements%20from%20an%20array). 

The year+day Dec date format is short for [year+day/[dyl]{.tool data-bs-toggle="tooltip" data-bs-title="Decalendar year length"}]{.nowrap}. Dec truncates dates because the [dyl]{.tool data-bs-toggle="tooltip" data-bs-title="Decalendar year length"} is not needed to specify a date, remains constant for 366, 1095, or 2920 days, has only 2 possible values: [365]{.color364by365} or [366]{.color365by366}, and can be determined by passing Year [y]{.tool data-bs-toggle="tooltip" data-bs-title="year"} to @eq-leap2dyl below. Nevertheless, we can use the [dyl]{.tool data-bs-toggle="tooltip" data-bs-title="Decalendar year lengths"} to convert between different kinds of Dec dates.

::: {.overflowequation}
$$
\text{leap}=\begin{cases}
  1&{\begin{aligned}
    &\text{ if } (\text{y} + 1)\href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} \ \ \ \ 4=0\\
    &\href{https://en.wikipedia.org/wiki/Logical_conjunction}{\land}(\text{y} + 1)\href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 100\neq0\\
    &\href{https://en.wikipedia.org/wiki/Logical_disjunction}{\lor}(\text{y} + 1)\href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 400=0\end{aligned}}\\\\
  0&{\text{ otherwise}}\end{cases}
$$ {#eq-leap}

$$\text{dyl}=365+\text{leap}$$ {#eq-leap2dyl}
:::

:::{.panel-tabset group="language"}
### Julia

```{julia}
function leap(year = 0)
    year += 1
    year % 4 == 0 && year % 100 != 0 || year % 400 == 0
end
leap(2019)
leap(2020)
```

### Observable JavaScript

```{ojs}
function leap(year = 0) {
  year += 1;
  return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
}
leap(2019)
leap(2020)
```

### Python

```{python}
def leap(year=2000):
    year += 1
    return year % 4 == 0 and year % 100 != 0 or year % 400 == 0
leap(2019)
leap(2020)
```

### R

```{r}
leap <- function(year = 0) {
  year <- year + 1
  year %% 4 == 0 & year %% 100 != 0 | year %% 400 == 0
}
leap(2019)
leap(2020)
```

:::

Dec categorizes each date as a [countdown](https://en.wikipedia.org/wiki/Countdown#:~:text=a%20sequence%20of%20backward%20counting%20to%20indicate%20the%20time%20remaining%20before%20an%20event%20is%20scheduled%20to%20occur) or countup date, depending on whether the date counts **up** the days **since** Year [y]{.tool data-bs-toggle="tooltip" data-bs-title="year"} or counts **down** the days **until** Year [y]{.tool data-bs-toggle="tooltip" data-bs-title="year"}+1. The current year+day [UTC](#utc){.tool data-bs-toggle="tooltip" data-bs-title="Coordinated Universal Time"} date, [\${decYear}[+]{.mono}\${decDotyPad}]{.nowrap}, informs us that Year \${decYear} began \${decDoty} days ago, whereas its countdown equivalent, [\${nextYear}[-]{.mono}\${TminusPadded}]{.nowrap}, lets us know that Year \${nextYear} will begin in \${Tminus} days.

::: {.overflowequation}
$$\text{y}+\dfrac{\text{pid}}{\text{dyl}} = \text{y} + 1 + \dfrac{\text{nid}}{\text{dyl}}$$ {#eq-updown}
:::

Both [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} and [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer days of year"} can be useful. If we wanted to add 285 days to the [doy]{.tool data-bs-toggle="tooltip" data-bs-title="day of year"} selected below, for example to predict when a pregnant🤰woman will give birth to a baby👩‍🍼[@jukicLengthHumanPregnancy2013], we should add 285 to the [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} if it is less than 80 in a common year or less than 81 in a leap year, but otherwise we should add 1 to the year and add 285 to the [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"}: \${easyDoy} + 285 = \${easySum}.

```{ojs}
//| echo: false
//| label: boundsliders
//| className: sliders
Inputs.bind(Inputs.range([0, 364 + leapInput], {step: 1, label: "Day of year"}), viewof dotyInput)
Inputs.bind(Inputs.range([-365 - leapInput, -1], {step: 1, label: "Day of year"}), viewof dotyInput1)
```

[First [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} of the Gregorian calendar year]{.radiotitle}

```{ojs}
//| echo: false
//| label: boundradio
//| className: radiobuttons
Inputs.bind(Inputs.radio(["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], {value: gregBoyDotwStr}), viewof dotwInput)
```

The [radio](https://observablehq.com/@observablehq/input-radio) input beneath the plots selects the [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} for [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}\${january1doy}, the first day of the Gregorian calendar year. Changing the [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}\${january1doy} [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} shifts every Gregorian calendar date by 1 to 6 days without affecting Decalendar. A leap year that begins on the last [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}, [Dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} [6]{.color6by7}, has an extra "week of year" ([woy]{.tool data-bs-toggle="tooltip" data-bs-title="week of year"}), but its first and last [woy]{.tool data-bs-toggle="tooltip" data-bs-title="week of year"}, Weeks 0 and 53, each contribute only 1 day to the year.

Even though weeks determine the shape of the Gregorian calendar plot, its cell values are "days of month" ([dom]{.tool data-bs-toggle="tooltip" data-bs-title="days of month"}). We can uniquely identify🪪a specific day in any year with a [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"}, instead of a month and a [dom]{.tool data-bs-toggle="tooltip" data-bs-title="day of month"}. Except for [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[365]{.color365by366} in leap years, every year has the same [x]{.tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"}, [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}, and months, but not the same weeks. It takes 5, 6, 7, 11, or 12 years for a [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}\${january1doy} [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} to recur.

The number of forms that the Gregorian calendar can take, 14, is the product of 7 [dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"} and 2 year lengths. If we set aside an extra copy of a printed🖨️Gregorian calendar on [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}\${january1doy}, we would have to wait 6, 11, 12, 17, 23, 28, or 40 years to use it. We can make the leap year form of Decalendar apply to any year by appending an asterisk (\*) to the label for [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[365]{.color365by366}: [365]{.color0}\*.

The [365]{.color0}\* label is short for [365]{.color0}\*leap, where leap is the [left-hand side](https://en.wikipedia.org/wiki/Sides_of_an_equation#:~:text=the%20expression%20on%20the%20left%20of%20the%20%22%3D%22%20is%20the%20left%20side%20of%20the%20equation) of @eq-leap. If leap is 1, Year [y]{.tool data-bs-toggle="tooltip" data-bs-title="year"} is a leap year and [365]{.color0}\* is [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[365]{.color365by366}, the last day of Year [y]{.tool data-bs-toggle="tooltip" data-bs-title="year"}. If leap is 0, Year [y]{.tool data-bs-toggle="tooltip" data-bs-title="year"} is a common year and [365]{.color0}\* is [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[0]{.color0}, the first day of Year [y]{.tool data-bs-toggle="tooltip" data-bs-title="year"}+1. The [365]{.color0}\* label unites the common and leap year forms of Decalendar into a [perennial calendar](https://en.wikipedia.org/wiki/Perennial_calendar#:~:text=a%20calendar%20that%20applies%20to%20any%20year%2C%20keeping%20the%20same%20dates) that can be reused♻️every year.

# Day of xún (dox) {#sec-dox}

As opposed to a week, an [x]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"} can be split evenly into either 5 pairs of days or 2 equal halves called "pentadays of xún" ([pox]{.tool data-bs-toggle="tooltip" data-bs-title="pentadays of xún"}). Likewise, a common year can be divided evenly into 73 groups of 5 days called "pentadays" ([p](#p){#pentaday .tool data-bs-toggle="tooltip" data-bs-title="pentadays"}): [p]{#pentaday .tool data-bs-toggle="tooltip" data-bs-title="pentadays"}0 to [p]{#pentaday .tool data-bs-toggle="tooltip" data-bs-title="pentadays"}[72]{.color72by73}. The last [p]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday"} of a leap year, [p]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday"}[73]{.color73by74}, consists of the final day of the leap year, [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[365]{.color365by366}, and the first 4 days of the subsequent year: [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[0]{.color0} to [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[3]{.color3by365}.

In the context of a common year, [p]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday"}[73]{.color73by74} is synonymous with [p]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday"}0 of the succeeding year. To obtain the current [p]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday"}, we double the current [x]{.tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"} and add the current [pox]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday of xún"}, which is 1 if the current [dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} is greater than 4 and 0 otherwise: ${decPent} = \${decDek} &times; 2 + [\[](https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise)\${decDotd} > 4[\]](https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise). If we divide a [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} or a [dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} by 5, the remainder will be its corresponding "day of pentaday" ([dop]{.tool data-bs-toggle="tooltip" data-bs-title="days of pentaday"}): \${decDoty} [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 5 = \${decDotp}. 

::: {.column-margin .overflowequation}
$$\text{x} = \lfloor \text{pid} \div 10\rfloor$$ {#eq-xun}
$$\text{dox} = \text{pid} \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 10$$ {#eq-dox}
$$\text{pox} = \href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{[}\text{dox} > 4\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{]}$$ {#eq-pox}
$$\text{p = x} \ast 2 + \text{pox}$$ {#eq-poy}
$$\text{dop = dox} \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 5$$ {#eq-dop}
:::

In @fig-zero below, each row is a [pox]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday of xún"} and each square node is a [dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"}. @fig-zero visualizes Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"}, a Dec base schedule that plans for exactly 219 work days per year, which is about an [x](#x){.tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"} more than the 208 to 210 work days per year provisioned by a [four-day workweek](https://en.wikipedia.org/wiki/Four-day_workweek#:~:text=an%20arrangement%20where%20a%20workplace%20or%20place%20of%20education%20has%20its%20employees%20or%20students%20work%20or%20attend%20school%2C%20college%20or%20university%20over%20the%20course%20of%20four%20days%20per%20week). Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} designates [Dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} [1]{.color1}, [2]{.color2}, [3]{.color3}, [6]{.color6}, [7]{.color7}, and [8]{.color8} as work days and [Dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} [0]{.color0}, [4]{.color4}, [5]{.color5}, and [9]{.color9} as rest days. 

::: {.centered}
### Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} ([Dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} [0]{.color0} to [9]{.color9}) {.diagtitle}
:::

::: {#fig-zero .doxdiagram}
```{mermaid}
%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '29px'}}}%%
flowchart LR
  B~~~M[ ]:::empty----N[ ]:::empty
  W---M
  N---O[ ]:::empty
  Q[ ]:::empty---L
  W[ ]:::empty-->A[0]-->B[1]-->C[2]-->D[3]-->E[4]---L[ ]:::empty
  Y[ ]:::empty-->F[5]-->G[6]-->H[7]-->I[8]-->J[9]---O[ ]:::empty
  B~~~P[ ]:::empty---Q
  Y---P
  subgraph workdays[work]
  B
  C
  G
  H
  D
  I
  end
  subgraph restdays[ ]
  A
  F
  E
  J
  workdays
  end
  classDef empty width:0px;
```
:::

Dec identifies groups of days between [Dop]{.tool data-bs-toggle="tooltip" data-bs-title="day of pentaday"} [0]{.color0} and [4]{.color8} as "pentaday interquintile ranges" ([pir]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday interquintile ranges"}): [Dop]{.tool data-bs-toggle="tooltip" data-bs-title="day of pentaday"} [1]{.color2}, [2]{.color4}, and [3]{.color6}. Similarly, the days betwixt [Dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} [0]{.color0} and [9]{.color9} are "xún interdecile ranges" ([xir]{.tool data-bs-toggle="tooltip" data-bs-title="xún interdecile ranges"}). The names for [pir]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday interquintile range"} and [xir]{.tool data-bs-toggle="tooltip" data-bs-title="xún interdecile range"} are derived from the terms [quintile](https://en.wiktionary.org/wiki/quintile#:~:text=quantiles%20which%20divide%20an%20ordered%20sample%20population%20into%20five%20equally%20numerous%20subsets), [decile](https://en.wikipedia.org/wiki/Decile#:~:text=nine%20values%20that%20divide%20the%20sorted%20data%20into%20ten%20equal%20parts), and [interquartile range](https://en.wikipedia.org/wiki/Interquartile_range#:~:text=a%20measure%20of%20statistical%20dispersion). If we follow Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"}, a [pir]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday interquintile ranges"} is to a [workweek](https://en.wikipedia.org/wiki/Workweek_and_weekend#:~:text=the%20part%20of%20the%20seven%2Dday%20week%20devoted%20to%20working) as a [p](#p){.tool data-bs-toggle="tooltip" data-bs-title="pentaday"} is to a week and as an [x]{.tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"} is to a [fortnight](https://en.wikipedia.org/wiki/Fortnight#:~:text=a%20unit%20of%20time%20equal%20to%2014%20days).

The pair of days between two [pir]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday interquintile ranges"} is called a "[liminal](https://en.wikipedia.org/wiki/Liminality#:~:text=the%20quality%20of%20ambiguity%20or%20disorientation%20that%20occurs%20in%20the%20middle%20stage%20of%20a%20rite%20of%20passage) interconnecting margin" ([lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"}). The last [lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} of a common year, [Lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} [73]{.color364andahalfby365}, comprises [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[364]{.color364by365} and [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[0]{.color0} and is synonymous with [Lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} [0]{.color0} of the subsequent year. In a leap year, [Lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} [73]{.color364andahalfby365} consists of [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[364]{.color364by366} and [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[365]{.color365by366} and overlaps with [Lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} [74]{.color365andahalfby366}, which is composed of [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[365]{.color365by366} and [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[0]{.color0} and is equivalent to [Lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} [0]{.color0} of the ensuing year.

Except for [Lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} [74]{.color365andahalfby366}, every even-numbered [lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} is the border that separates two [xir]{.tool data-bs-toggle="tooltip" data-bs-title="xún interdecile ranges"}. With the exception of [Lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} [73]{.color364andahalfby365}, every odd-numbered [lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} is flanked by the two [pir]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday interquintile ranges"} within each [xir]{.tool data-bs-toggle="tooltip" data-bs-title="xún interdecile range"}. @fig-zerocomm below shows the final five [doy]{.tool data-bs-toggle="tooltip" data-bs-title="days of year"} of a common year and the first five [doy]{.tool data-bs-toggle="tooltip" data-bs-title="days of year"} of the following year, which include the last day of [Lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} [72]{.color359andahalfby365}, Pir [72]{.color72by73}, [Lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} [0]{.color0}, Pir [0]{.color0}, and the first day of [Lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} [1]{.color4andahalfby365}.

::: {.centered}
### Schedule L ([p]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday"}[72]{.color72by73} and [p]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday"}[0]{.color0}) {.diagtitle}
:::

::: {#fig-zerocomm .doxdiagram}
```{mermaid}
%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '29px'}}}%%
flowchart LR
  W~~~~O[ ]:::empty
  W[ ]:::empty-->A[360]-->B[361]-->C[362]-->D[363]-->E[364]----L[ ]:::empty
  Y[ ]:::empty-->F[0]-->G[1]-->H[2]-->I[3]-->J[4]-->K[ ]:::empty
  Q[ ]:::empty---L
  Y---Q
  subgraph workdays[work]
  B
  C
  G
  H
  D
  I
  end
  subgraph restdays[ ]
  A
  F
  E
  J
  workdays
  end
  classDef empty width:0px;
```
:::

The diagrams above illustrate that the transition from a common year preserves the alternating pattern of two-day [lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} and three-day [pir]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday interquintile ranges"}. After 4 or 8 years, this pattern is interrupted by [Lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} [73]{.color364andahalfby365} and [74]{.color365andahalfby366} at the end of a leap year. In @fig-zeroleap below, this interruption manifests as an extra [doy]{.tool data-bs-toggle="tooltip" data-bs-title="days of year"} per row which puts Day [364]{.color364by366} alongside Day [365]{.color365by366} and Day [4]{.color4by365} beside Day [5]{.color5by365}. 

::: {.centered}
### Schedule L ([d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[360]{.color360by366} to [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[365]{.color365by366} and [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[0]{.color0} to [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[5]{.color5by365}) {.diagtitle}
:::

::: {#fig-zeroleap .doxdiagram}
```{mermaid}
%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '29px'}}}%%
flowchart LR
  W~~~~O[ ]:::empty
  W[ ]:::empty-->A[360]-->B[361]-->C[362]-->D[363]-->E[364]-->L[365]----S[ ]:::empty
  Y[ ]:::empty-->F[0]-->G[1]-->H[2]-->I[3]-->J[4]-->K[5]-->T[ ]:::empty
  Q[ ]:::empty---S
  Y---Q
  subgraph workdays[work]
  B
  C
  G
  H
  D
  I
  end
  subgraph restdays[ ]
  A
  F
  E
  J
  K
  L
  workdays
  end
  classDef empty width:0px;
```
:::

According to Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"}, [pir]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday interquintile ranges"} only contain workdays and [lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} are solely made up of rest days. When we follow Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"}, a [lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminals"} is the Dec analog of a weekend. To make [lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} appear like weekends we can start from [Dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} [1]{.color1} instead of [Dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} [0]{.color0} as in the @fig-one below, which displays its [lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} as a two-by-two square grid on the right like [Lim]{.tool data-bs-toggle="tooltip" data-bs-title="liminal interconnecting margin"} [73]{.color364andahalfby365} and [1]{.color4andahalfby365} in @fig-zeroleap above.

::: {.centered}
### Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} ([Dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} [1]{.color1} to [0]{.color0}) {.diagtitle}
:::

::: {#fig-one .doxdiagram}
```{mermaid}
%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '29px'}}}%%
flowchart LR
  B~~~M[ ]:::empty----N[ ]:::empty
  W---M
  N---O[ ]:::empty
  Q[ ]:::empty---L
  W[ ]:::empty-->A[1]-->B[2]-->C[3]-->D[4]-->E[5]---L[ ]:::empty
  Y[ ]:::empty-->F[6]-->G[7]-->H[8]-->I[9]-->J[0]---O[ ]:::empty
  B~~~P[ ]:::empty---Q
  Y---P
  subgraph workdays[work]
  A
  B
  C
  F
  G
  H
  end
  subgraph restdays[ ]
  D
  E
  I
  J
  workdays
  end
  classDef empty width:0px;
```
:::

The order of [dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} in @fig-one is different than all of the previous diagrams but all of the diagrams above show Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} because the categorization of [dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} as work or rest days remains unchanged. If we left [rotate](https://en.wikipedia.org/wiki/Circular_shift#:~:text=moving%20the%20final%20entry%20to%20the%20first%20position%2C%20while%20shifting%20all%20other%20entries%20to%20the%20next%20position%2C%20or%20by%20performing%20the%20inverse%20operation) (↺) the [dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} categories of Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} by 1 day, we get the Schedule [X]{.color28by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal X is decimal 28 or binary 11100"} Dec schedule: [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} ↺ 1 = [X]{.color28by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal X is decimal 28 or binary 11100"}. Schedule [X]{.color28by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal X is decimal 28 or binary 11100"} groups rest days at the end of each [p]{.tool data-bs-toggle="tooltip" data-bs-title="pentaday"}.

::: {.centered}
### Schedule [X]{.color28by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal X is decimal 28 or binary 11100"} ([Dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} [0]{.color0} to [9]{.color9}) {.diagtitle}
:::

::: {#fig-xpos .doxdiagram}
```{mermaid}
%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '29px'}}}%%
flowchart LR
  B~~~M[ ]:::empty----N[ ]:::empty
  W---M
  N---O[ ]:::empty
  Q[ ]:::empty---L
  W[ ]:::empty-->A[0]-->B[1]-->C[2]-->D[3]-->E[4]---L[ ]:::empty
  Y[ ]:::empty-->F[5]-->G[6]-->H[7]-->I[8]-->J[9]---O[ ]:::empty
  B~~~P[ ]:::empty---Q
  Y---P
  subgraph workdays[work]
  A
  B
  C
  F
  G
  H
  end
  subgraph restdays[ ]
  D
  E
  I
  J
  workdays
  end
  classDef empty width:0px;
```
:::

If we follow Schedule [X]{.color28by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal X is decimal 28 or binary 11100"}, there will be 4 consecutive work days during any transition from a leap year. To limit the number of consecutive work days to 3, we could right rotate (↻) Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} and obtain Schedule [F]{.color7by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal F is decimal 7 or binary 00111"}: [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} ↻ 1 = [F]{.color7by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal F is decimal 7 or binary 00111"}. Unlike Schedule [X]{.color28by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal X is decimal 28 or binary 11100"}, Schedule [F]{.color7by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal F is decimal 7 or binary 00111"} handles yearly transitions just as gracefully as Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} and provisions the exact same number of work days per year.

::: {.centered}
### Schedule [F]{.color7by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal F is decimal 7 or binary 00111"} ([Dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} [0]{.color0} to [9]{.color9}) {.diagtitle}
:::

::: {#fig-fpos .doxdiagram}
```{mermaid}
%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '29px'}}}%%
flowchart LR
  M[ ]:::empty----N[ ]:::empty
  W---M
  N---O[ ]:::empty
  Q[ ]:::empty---L
  W[ ]:::empty-->A[0]-->B[1]-->C[2]-->D[3]-->E[4]---L[ ]:::empty
  Y[ ]:::empty-->F[5]-->G[6]-->H[7]-->I[8]-->J[9]---O[ ]:::empty
  P[ ]:::empty---Q
  Y---P
  subgraph workdays[work]
  C
  D
  E
  H
  I
  J
  end
  subgraph restdays[ ]
  A
  B
  F
  G
  workdays
  end
  classDef empty width:0px;
```
:::

Each of the 32 base Dec schedules can be expressed as a five-bit (5b) [binary](https://en.wikipedia.org/wiki/Binary_number#:~:text=only%20two%20symbols%20for%20the%20natural%20numbers%3A%20typically%200%20%28zero%29%20and%201%20%28one%29) ([base2]{.tool data-bs-toggle="tooltip" data-bs-title="binary"}) sequence. Of these 32 binary sequences, 8 are palindromes. If a Dec schedule can be represented by a 5b palindrome, we can identify its work and rest days by the last digit of not only the [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} but also either the subsequent [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} ([ni[d]{.acute}]{.tool data-bs-toggle="tooltip" data-bs-title="next negative integer day of year"}) in common years or the [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} after next ([ni[d]{.doubleacute}]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"}) in leap years.

We can sum a [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} with 1 to get a [ni[d]{.acute}]{.tool data-bs-toggle="tooltip" data-bs-title="next negative integer day of year"}, [ni[d]{.acute}]{.tool data-bs-toggle="tooltip" data-bs-title="next negative integer day of year"} = [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} + 1, or with 2 to get a [ni[d]{.doubleacute}]{.tool data-bs-toggle="tooltip" data-bs-title="next negative integer day of year"}: [ni[d]{.doubleacute}]{.tool data-bs-toggle="tooltip" data-bs-title="next negative integer day of year"} = [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} + 2. @tbl-vincommon below displays the [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"}, [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"}, [ni[d]{.acute}]{.tool data-bs-toggle="tooltip" data-bs-title="next negative integer day of year"}, and "mixed integer [doy]{.tool data-bs-toggle="tooltip" data-bs-title="day of year"}" ([mid]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"}) of the first and last 11 days of a common year. We can use the last digit of any [mid]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} that is derived from an [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer days of year"} to discern between the work and rest days of any of the 32 base Dec schedules in common years.

The horizontal line above all but the last digit of the [mid]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer days of year"} in @tbl-vincommon is called a [vinculum](https://en.wikipedia.org/wiki/Vinculum_(symbol)#:~:text=a%20horizontal%20line%20used%20in%20mathematical%20notation%20for%20various%20purposes). In Dec, a vinculum negates whatever is beneath it, negating all of the digits of an integer flips its [sign](https://en.wikipedia.org/wiki/Sign_(mathematics)#:~:text=property%20of%20being%20either%20positive%2C%20negative%2C%20or%200), and a negative integer is denoted by either a vinculum or a [minus sign](https://en.wikipedia.org/wiki/Plus_and_minus_signs#Minus_sign:~:text=When%20it%20is%20placed%20immediately%20before%20an%20unsigned%20number%2C%20the%20combination%20names%20a%20negative%20number%2C%20the%20additive%20inverse%20of%20the%20positive%20number%20that%20the%20numeral%20would%20otherwise%20name). For example, [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[1]{.overline} and [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[1]{.overline}9 are two equivalent ways to write Day -1, the last day of the Dec year.

::::: {#tbl-vincommon}

::: {.d-block .d-xl-none}
| [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} | | | [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} | | | [ni[d]{.acute}]{.tool data-bs-toggle="tooltip" data-bs-title="next negative integer day of year"} | [[mi]{.overline}d]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} |
|-----|-|-|------|-|-|------------------|------------------|
| [0]{.color0}   | | | -365 | | | -36[4]{.acute} | [37]{.overline}5 |
| 1   | | | -364 | | | -36[3]{.acute} | [37]{.overline}6 |
| 2   | | | -363 | | | -36[2]{.acute} | [37]{.overline}7 |
| 3   | | | -362 | | | -36[1]{.acute} | [37]{.overline}8 |
| 4   | | | -361 | | | -36[0]{.acute} | [37]{.overline}9 |
| 5   | | | -360 | | | -35[9]{.acute} | [36]{.overline}0 |
| 6   | | | -359 | | | -35[8]{.acute} | [36]{.overline}1 |
| 7   | | | -358 | | | -35[7]{.acute} | [36]{.overline}2 |
| 8   | | | -357 | | | -35[6]{.acute} | [36]{.overline}3 |
| 9   | | | -356 | | | -35[5]{.acute} | [36]{.overline}4 |
| 10  | | | -355 | | | -35[4]{.acute} | [36]{.overline}5 |
| ... | | | ...  | | | ...            | ...              |
| 354 | | | -11  | | | -1[0]{.acute}  | [2]{.overline}9  |
| 355 | | | -10  | | | -[9]{.acute}   | [1]{.overline}0  |
| 356 | | | -9   | | | -[8]{.acute}   | [1]{.overline}1  |
| 357 | | | -8   | | | -[7]{.acute}   | [1]{.overline}2  |
| 358 | | | -7   | | | -[6]{.acute}   | [1]{.overline}3  |
| 359 | | | -6   | | | -[5]{.acute}   | [1]{.overline}4  |
| 360 | | | -5   | | | -[4]{.acute}   | [1]{.overline}5  |
| 361 | | | -4   | | | -[3]{.acute}   | [1]{.overline}6  |
| 362 | | | -3   | | | -[2]{.acute}   | [1]{.overline}7  |
| 363 | | | -2   | | | -[1]{.acute}   | [1]{.overline}8  |
| 364 | | | -1   | | | -[0]{.acute}   | [1]{.overline}9  |
:::

::: {.d-none .d-xl-block}
| [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} | | [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} | | [ni[d]{.acute}]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} | [[mi]{.overline}d]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} | | | | | | | | | | [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} | | [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} | | [ni[d]{.acute}]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} | [[mi]{.overline}d]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} |
|----|-|------|-|----------------|------------------|-|-|-|-|-|-|-|-|-|-----|-|-----|-|---------------|------------------|
| 0  | | -365 | | -36[4]{.acute} | [37]{.overline}5 | | | | | | | | | | 354 | | -11 | | -1[0]{.acute} | [2]{.overline}9  |
| 1  | | -364 | | -36[3]{.acute} | [37]{.overline}6 | | | | | | | | | | 355 | | -10 | | -[9]{.acute}  | [1]{.overline}0  |
| 2  | | -363 | | -36[2]{.acute} | [37]{.overline}7 | | | | | | | | | | 356 | | -9  | | -[8]{.acute}  | [1]{.overline}1  |
| 3  | | -362 | | -36[1]{.acute} | [37]{.overline}8 | | | | | | | | | | 357 | | -8  | | -[7]{.acute}  | [1]{.overline}2  |
| 4  | | -361 | | -36[0]{.acute} | [37]{.overline}9 | | | | | | | | | | 358 | | -7  | | -[6]{.acute}  | [1]{.overline}3  |
| 5  | | -360 | | -35[9]{.acute} | [36]{.overline}0 | | | | | | | | | | 359 | | -6  | | -[5]{.acute}  | [1]{.overline}4  |
| 6  | | -359 | | -35[8]{.acute} | [36]{.overline}1 | | | | | | | | | | 360 | | -5  | | -[4]{.acute}  | [1]{.overline}5  |
| 7  | | -358 | | -35[7]{.acute} | [36]{.overline}2 | | | | | | | | | | 361 | | -4  | | -[3]{.acute}  | [1]{.overline}6  |
| 8  | | -357 | | -35[6]{.acute} | [36]{.overline}3 | | | | | | | | | | 362 | | -3  | | -[2]{.acute}  | [1]{.overline}7  |
| 9  | | -356 | | -35[5]{.acute} | [36]{.overline}4 | | | | | | | | | | 363 | | -2  | | -[1]{.acute}  | [1]{.overline}8  |
| 10 | | -355 | | -35[4]{.acute} | [36]{.overline}5 | | | | | | | | | | 364 | | -1  | | -[0]{.acute}  | [1]{.overline}9  |

:::
:::::

The [correlation](https://en.wikipedia.org/wiki/Correlation#:~:text=the%20extent%20to%20which%20a%20pair%20of%20quantities%20are%20linearly%20related) between a digit and the [absolute value](https://en.wikipedia.org/wiki/Absolute_value#:~:text=measured%20without%20regard%20to%20its%20sign) ([magnitude](https://en.wikipedia.org/wiki/Magnitude_(mathematics)#:~:text=The%20magnitude%20of,its%20absolute%20value)) of its mixed integer is positive for positive digits and negative for negative digits. Each negative digit in the [[mi]{.overline}d]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} column of @tbl-vincommon pulls the magnitude of its [[mi]{.overline}d]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} towards one, meanwhile each positive digit in that column moves the magnitude of its [[mi]{.overline}d]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} in the opposite direction along the [number line](https://en.wikipedia.org/wiki/Number_line#:~:text=spatial%20representation%20of%20numbers).

In a common year, the last digits of [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} and [ni[d]{.acute}]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} run antiparallel to each other like complementary strands of [deoxyribonucleic acid](https://en.wikipedia.org/wiki/DNA#:~:text=a%20polymer%20composed%20of%20two%20polynucleotide%20chains%20that%20coil%20around%20each%20other%20to%20form%20a%20double%20helix)🧬, but instead of [adenine](https://en.wikipedia.org/wiki/Adenine#:~:text=a%20purine%20nucleotide%20base%20that%20is%20found%20in%20DNA) to [thymine](https://en.wikipedia.org/wiki/Thymine#:~:text=one%20of%20the%20four%20nucleotide%20bases%20in%20the%20nucleic%20acid%20of%20DNA) and [cytosine](https://en.wikipedia.org/wiki/Cytosine#:~:text=one%20of%20the%20four%20nucleotide%20bases%20found%20in%20DNA) to [guanine](https://en.wikipedia.org/wiki/Guanine#:~:text=one%20of%20the%20four%20main%20nucleotide%20bases), the pattern is 0 to [4]{.acute}, 1 to [3]{.acute}, 2 to [2]{.acute}, 3 to [1]{.acute}, 4 to [0]{.acute}, and so on. The final digits of [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} and [ni[d]{.doubleacute}]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer days of year"} follow the same pattern in leap years: 0 to [4]{.doubleacute}, 1 to [3]{.doubleacute}, 2 to [2]{.doubleacute}, 3 to [1]{.doubleacute}, 4 to [0]{.doubleacute}, and so on.

The last digits of [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} and [[mi]{.overline}d]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer days of year"} are misaligned by 4 days in leap years and by 5 days in common years. Dec maintains a constant five-day misalignment by replacing the [[mi]{.overline}d]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer days of year"} with the next [[mi]{.overline}d]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer days of year"} ([[mi]{.overline}[d]{.grave}]{.tool data-bs-toggle="tooltip" data-bs-title="next mixed integer day of year"}) in leap years. The accents above [ni[d]{.acute}]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} and [[mi]{.overline}[d]{.grave}]{.tool data-bs-toggle="tooltip" data-bs-title="next mixed integer day of year"} both advance the apparent [doy]{.tool data-bs-toggle="tooltip" data-bs-title="day of year"} by one day. @tbl-vinculeap below shows the [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"}, [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"}, [ni[d]{.doubleacute}]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"}, and [[mi]{.overline}[d]{.grave}]{.tool data-bs-toggle="tooltip" data-bs-title="next mixed integer day of year"} of the first and last 11 days of a leap year.

::::: {#tbl-vinculeap}

::: {.d-block .d-xl-none}
| [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} | | | [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} | | | [ni[d]{.doubleacute}]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} | [[mi]{.overline}[d]{.grave}]{.tool data-bs-toggle="tooltip" data-bs-title="next mixed integer day of year"} |
|-----|-|-|------|-|-|----------------------|----------------------------|
| 0   | | | -366 | | | -36[4]{.doubleacute} | [37]{.overline}[5]{.grave} |
| 1   | | | -365 | | | -36[3]{.doubleacute} | [37]{.overline}[6]{.grave} |
| 2   | | | -364 | | | -36[2]{.doubleacute} | [37]{.overline}[7]{.grave} |
| 3   | | | -363 | | | -36[1]{.doubleacute} | [37]{.overline}[8]{.grave} |
| 4   | | | -362 | | | -36[0]{.doubleacute} | [37]{.overline}[9]{.grave} |
| 5   | | | -361 | | | -36[9]{.doubleacute} | [36]{.overline}[0]{.grave} |
| 6   | | | -360 | | | -35[8]{.doubleacute} | [36]{.overline}[1]{.grave} |
| 7   | | | -359 | | | -35[7]{.doubleacute} | [36]{.overline}[2]{.grave} |
| 8   | | | -358 | | | -35[6]{.doubleacute} | [36]{.overline}[3]{.grave} |
| 9   | | | -357 | | | -35[5]{.doubleacute} | [36]{.overline}[4]{.grave} |
| 10  | | | -356 | | | -35[4]{.doubleacute} | [36]{.overline}[5]{.grave} |
| ... | | | ...  | | | ...                  | ...                        |
| 355 | | | -11  | | | -[9]{.doubleacute}   | [1]{.overline}[0]{.grave}  |
| 356 | | | -10  | | | -[8]{.doubleacute}   | [1]{.overline}[1]{.grave}  |
| 357 | | | -9   | | | -[7]{.doubleacute}   | [1]{.overline}[2]{.grave}  |
| 358 | | | -8   | | | -[6]{.doubleacute}   | [1]{.overline}[3]{.grave}  |
| 359 | | | -7   | | | -[5]{.doubleacute}   | [1]{.overline}[4]{.grave}  |
| 360 | | | -6   | | | -[4]{.doubleacute}   | [1]{.overline}[5]{.grave}  |
| 361 | | | -5   | | | -[3]{.doubleacute}   | [1]{.overline}[6]{.grave}  |
| 362 | | | -4   | | | -[2]{.doubleacute}   | [1]{.overline}[7]{.grave}  |
| 363 | | | -3   | | | -[1]{.doubleacute}   | [1]{.overline}[8]{.grave}  |
| 364 | | | -2   | | | -[0]{.doubleacute}   | [1]{.overline}[9]{.grave}  |
| 365 | | | -1   | | | -[0]{.acute}         | [0]{.overline}[0]{.grave}  |
:::

::: {.d-none .d-xl-block}
| [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} | | [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} | | [ni[d]{.doubleacute}]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} | [[mi]{.overline}[d]{.grave}]{.tool data-bs-toggle="tooltip" data-bs-title="next mixed integer day of year"} | | | | | | | | | | [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} | | [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} | | [ni[d]{.doubleacute}]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} | [[mi]{.overline}[d]{.grave}]{.tool data-bs-toggle="tooltip" data-bs-title="next mixed integer day of year"} |
|----|-|------|-|----------------------|----------------------------|-|-|-|-|-|-|-|-|-|-----|-|-----|-|--------------------|----------------------------|
| 0  | | -366 | | -36[4]{.doubleacute} | [37]{.overline}[5]{.grave} | | | | | | | | | | 355 | | -11 | | -[9]{.doubleacute} | [1]{.overline}[0]{.grave}  |
| 1  | | -365 | | -36[3]{.doubleacute} | [37]{.overline}[6]{.grave} | | | | | | | | | | 356 | | -10 | | -[8]{.doubleacute} | [1]{.overline}[1]{.grave}  |
| 2  | | -364 | | -36[2]{.doubleacute} | [37]{.overline}[7]{.grave} | | | | | | | | | | 357 | | -9  | | -[7]{.doubleacute} | [1]{.overline}[2]{.grave}  |
| 3  | | -363 | | -36[1]{.doubleacute} | [37]{.overline}[8]{.grave} | | | | | | | | | | 358 | | -8  | | -[6]{.doubleacute} | [1]{.overline}[3]{.grave}  |
| 4  | | -362 | | -36[0]{.doubleacute} | [37]{.overline}[9]{.grave} | | | | | | | | | | 359 | | -7  | | -[5]{.doubleacute} | [1]{.overline}[4]{.grave}  |
| 5  | | -361 | | -36[9]{.doubleacute} | [36]{.overline}[0]{.grave} | | | | | | | | | | 360 | | -6  | | -[4]{.doubleacute} | [1]{.overline}[5]{.grave}  |
| 6  | | -360 | | -35[8]{.doubleacute} | [36]{.overline}[1]{.grave} | | | | | | | | | | 361 | | -5  | | -[3]{.doubleacute} | [1]{.overline}[6]{.grave}  |
| 7  | | -359 | | -35[7]{.doubleacute} | [36]{.overline}[2]{.grave} | | | | | | | | | | 362 | | -4  | | -[2]{.doubleacute} | [1]{.overline}[7]{.grave}  |
| 8  | | -358 | | -35[6]{.doubleacute} | [36]{.overline}[3]{.grave} | | | | | | | | | | 363 | | -3  | | -[1]{.doubleacute} | [1]{.overline}[8]{.grave}  |
| 9  | | -357 | | -35[5]{.doubleacute} | [36]{.overline}[4]{.grave} | | | | | | | | | | 364 | | -2  | | -[0]{.doubleacute} | [1]{.overline}[9]{.grave}  |
| 10 | | -356 | | -35[4]{.doubleacute} | [36]{.overline}[5]{.grave} | | | | | | | | | | 365 | | -1  | | -[0]{.acute}       | [0]{.overline}[0]{.grave}  |

:::

:::::

A digit can be negated by a vinculum, augmented by an [acute accent](https://en.wikipedia.org/wiki/Acute_accent#:~:text=a%20diacritic%20used%20in%20many%20modern%20written%20languages%20with%20alphabets%20based%20on%20the%20Latin%2C%20Cyrillic%2C%20and%20Greek%20scripts), diminished by a [grave accent](https://en.wikipedia.org/wiki/Grave_accent#:~:text=a%20diacritical%20mark%20used%20to%20varying%20degrees%20in%20French%2C%20Dutch%2C%20Portuguese%2C%20Italian%2C%20Catalan%20and%20many%20other%20Western%20European%20languages), double augmented by a double acute accent, or double diminished by a double grave accent. The main purpose of these modifications is to change the appearance of the last digit of an [nid](#nid){.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} so that it matches the work or rest day classification of the last digit of a [pid](#pid){.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"}.

The Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} rule for categorization of work and rest days can be summarized as [\[](https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise)[dop](#dop){.tool data-bs-toggle="tooltip" data-bs-title="day of pentaday"} ∈ {1,2,3}[\]](https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise), where ∈ means "is an element of" and {1,2,3} is Set [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"}, a [set](https://en.wikipedia.org/wiki/Set_(mathematics)#:~:text=a%20set%20is-,a%20collection%20of%20different%20things,-%5B1%5D) which contains all of the [dop]{.tool data-bs-toggle="tooltip" data-bs-title="days of pentaday"} that are Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} work days. The Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} rule can be applied to the last digit of the [[mi]{.overline}d]{.tool data-bs-toggle="tooltip" data-bs-title="next mixed integer day of year"} or [ni[d]{.acute}]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} in common years, of the [[mi]{.overline}[d]{.grave}]{.tool data-bs-toggle="tooltip" data-bs-title="next mixed integer day of year"} or [ni[d]{.doubleacute}]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} in leap years, or of the [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} in all years.

## Base32 {#b32 .hiddenheading}

The Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} pattern of rest and work days can be expressed in [binary](https://en.wikipedia.org/wiki/Binary_number#:~:text=only%20two%20symbols%20for%20the%20natural%20numbers%3A%20typically%200%20%28zero%29%20and%201%20%28one%29) ([base2]{.tool data-bs-toggle="tooltip" data-bs-title="binary"}) as 01110, [decimal](https://en.wikipedia.org/wiki/Decimal#:~:text=a%20numeral%20system%20that%20uses%20ten%20as%20its%20radix%20%28base%29) ([base10]{.tool data-bs-toggle="tooltip" data-bs-title="decimal"}) as 14, or Dec [duotrigesimal](https://en.wiktionary.org/wiki/duotrigesimal#:~:text=Based%20upon%20the%20number%20thirty%2Dtwo) ([base32]{.tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal"}) as [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"}. Each of the 32 Dec base schedules can be represented by a single letter of the Dec base32 ([b32]{.tool data-bs-toggle="tooltip" data-bs-title="Dec base32"}) alphabet. The [b32]{.tool data-bs-toggle="tooltip" data-bs-title="Dec base32"} letters are listed in @tbl-b32 below alongside their base10 ([b10]{.tool data-bs-toggle="tooltip" data-bs-title="Dec base10"}) and base2 ([b2]{.tool data-bs-toggle="tooltip" data-bs-title="Dec base2"}) values.

::::: {#tbl-b32}

::: {.d-block .d-xl-none}
|   |    |       | | | |   |    |       |
|---|----|-------|-|-|-|---|----|-------|
| A | 0  | 00000 | | | | N | 16 | 10000 |
| Á | 1  | 00001 | | | | O | 17 | 10001 |
| B | 2  | 00010 | | | | Ó | 18 | 10010 |
| C | 3  | 00011 | | | | P | 19 | 10011 |
| D | 4  | 00100 | | | | Q | 20 | 10100 |
| E | 5  | 00101 | | | | R | 21 | 10101 |
| É | 6  | 00110 | | | | S | 22 | 10110 |
| F | 7  | 00111 | | | | T | 23 | 10111 |
| G | 8  | 01000 | | | | U | 24 | 11000 |
| H | 9  | 01001 | | | | Ú | 25 | 11001 |
| I | 10 | 01010 | | | | V | 26 | 11010 |
| Í | 11 | 01011 | | | | W | 27 | 11011 |
| J | 12 | 01100 | | | | X | 28 | 11100 |
| K | 13 | 01101 | | | | Y | 29 | 11101 |
| L | 14 | 01110 | | | | Ý | 30 | 11110 |
| M | 15 | 01111 | | | | Z | 31 | 11111 |
:::

::: {.d-none .d-xl-block}
|   |    |       | | | |   |    |       | | | |   |    |       | | | |   |    |       |
|---|----|-------|-|-|-|---|----|-------|-|-|-|---|----|-------|-|-|-|---|----|-------|
| A | 0  | 00000 | | | | G | 8  | 01000 | | | | N | 16 | 10000 | | | | U | 24 | 11000 |
| Á | 1  | 00001 | | | | H | 9  | 01001 | | | | O | 17 | 10001 | | | | Ú | 25 | 11001 |
| B | 2  | 00010 | | | | I | 10 | 01010 | | | | Ó | 18 | 10010 | | | | V | 26 | 11010 |
| C | 3  | 00011 | | | | Í | 11 | 01011 | | | | P | 19 | 10011 | | | | W | 27 | 11011 |
| D | 4  | 00100 | | | | J | 12 | 01100 | | | | Q | 20 | 10100 | | | | X | 28 | 11100 |
| E | 5  | 00101 | | | | K | 13 | 01101 | | | | R | 21 | 10101 | | | | Y | 29 | 11101 |
| É | 6  | 00110 | | | | L | 14 | 01110 | | | | S | 22 | 10110 | | | | Ý | 30 | 11110 |
| F | 7  | 00111 | | | | M | 15 | 01111 | | | | T | 23 | 10111 | | | | Z | 31 | 11111 |
:::

:::::

@tbl-b32 above shows that the [b32]{.tool data-bs-toggle="tooltip" data-bs-title="the Dec base32"} alphabet includes the 26 letters of the [English alphabet](https://en.wikipedia.org/wiki/English_alphabet#:~:text=a%20Latin%2Dscript%20alphabet%20consisting%20of%2026%C2%A0letters) and combines the 6 [vowels](https://en.wikipedia.org/wiki/Vowel#:~:text=a%20speech%20sound%20pronounced%20without%20any%20stricture%20in%20the%20vocal%20tract), a, e, i, o, u, and y, with acute accents ( ́) to create 6 additional letters, á, é, í, ó, ú, and ý, for a total of 32 letters. The 6 additional accented letters are included immediately after their unaccented antecedents as per the order of the English alphabet.

::::: {.column-margin}

::: {.hand #fingerbinarysvg}
![](../../asset/Hand_apaumy_couped_base32.svg)
:::
[[Wikimedia](https://commons.wikimedia.org/wiki/File:Hand_apaumy_couped.svg)]{.handlabel}


::: {.hand #fingerbinarygif}
![](../../asset/Finger_binary.gif)
:::
[[Wikimedia](https://commons.wikimedia.org/wiki/File:Finger_binary.gif)]{.handlabel}

:::::

If we need more work days than those provided by Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"}, we can switch to the Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"}[M]{.color15by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal M is decimal 15 or binary 01111"} Dec schedule by following Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} on even numbered [p]{.tool data-bs-toggle="tooltip" data-bs-title="pentadays"} and Schedule [M]{.color15by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal M is decimal 17 or binary 01111"} to odd numbered [p]{.tool data-bs-toggle="tooltip" data-bs-title="pentadays"}. Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"}[M]{.color15by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal M is decimal 15 or binary 01111"} has 1 more work day per [x]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"} than Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} and provisions 255 work days per year without modifying the yearly transition shown in Diagrams -@fig-zerocomm and -@fig-zeroleap above.

In contrast to weekly schedules, Dec schedules like [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="L in base32 is 14 in base10 and 01110 in base2"} and [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="L in base32 is 14 in base10 and 01110 in base2"}[M]{.color15by32 .tool data-bs-toggle="tooltip" data-bs-title="M in base32 is 15 in base10 and 01111 in base2"} produce a consistent🎯number of work days every year. While Days [364]{.color364by365}, [365]{.color365by366}, and [0]{.color0} can be work or rest days in the Gregorian calendar️, these days are always rest days if we follow Schedules [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="L in base32 is 14 in base10 and 01110 in base2"} or [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="L in base32 is 14 in base10 and 01110 in base2"}[M]{.color15by32 .tool data-bs-toggle="tooltip" data-bs-title="M in base32 is 15 in base10 and 01111 in base2"}. Therefore, Schedules [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="L in base32 is 14 in base10 and 01110 in base2"} and [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="L in base32 is 14 in base10 and 01110 in base2"}[M]{.color15by32 .tool data-bs-toggle="tooltip" data-bs-title="M in base32 is 15 in base10 and 01111 in base2"} do not require any holidays to smooth the transition between years.

There are 11 United States (US) [Federal holidays](https://www.opm.gov/policy-data-oversight/pay-leave/federal-holidays/). US Federal holidays that fall on a Gregorian calendar️ rest day, [Dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} [0]{.color0 .tool data-bs-toggle="tooltip" data-bs-title="Sunday"} or [Dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} [6]{.color6by7 .tool data-bs-toggle="tooltip" data-bs-title="Saturday"}, are observed on the nearest Gregorian calendar️ work day: [Dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} [1]{.tool data-bs-toggle="tooltip" data-bs-title="Monday"} or [Dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} [5]{.color5by7 .tool data-bs-toggle="tooltip" data-bs-title="Friday"}. Instead of applying this rule to Schedule [L]{.color14by32 .tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"} and moving holidays from [Dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} [0]{.color0} to [1]{.color1}, [4]{.color4} to [3]{.color3}, [5]{.color5} to [6]{.color6}, or [9]{.color9} to [8]{.color8}, we can switch between Dec schedules as needed.

Over the course of a Dec cycle, which consists of 400 years, 20871 weeks, or 146097 days, a five-day workweek provides an average of 260.8875 work days per year. If we round 260.8875 to 261 and then subtract the 11 US Federal holidays, we get an annual total of 250 work days, which is 1 [p](#p){.tool data-bs-toggle="tooltip" data-bs-title="pentaday"} less than the total work days provided annually by Schedule [L]{.tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"}[M]{.tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal M is decimal 15 or binary 01111"}.

We can decrease the annual work day total of Schedule [L]{.tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal L is decimal 14 or binary 01110"}[M]{.tool data-bs-toggle="tooltip" data-bs-title="duotrigesimal M is decimal 15 or binary 01111"} to 249 if we reclassify [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[19]{.color19by365}, [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[111]{.color111by365}, [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[149]{.color149by365}, [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[206]{.color206by365}, [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[296]{.color296by365}, and [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[316]{.color316by365} as rest days. Approximately, [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[19]{.color19by365} is the [northward equinox](https://en.wikipedia.org/wiki/March_equinox#:~:text=the%20equinox%20on%20the%20Earth%20when%20the%20subsolar%20point%20appears%20to%20leave%20the%20Southern%20Hemisphere%20and%20cross%20the%20celestial%20equator%2C%20heading%20northward%20as%20seen%20from%20Earth), [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[111]{.color111by365} is the [northern solstice](https://en.wikipedia.org/wiki/June_solstice#:~:text=the%20solstice%20on%20Earth%20that%20occurs%20annually%20between%2020%20and%2022%20June%20according%20to%20the%20Gregorian%20calendar), [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[149]{.color149by365} is the hottest doy globally on average, [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[206]{.color206by365} is the [southward equinox](https://en.wikipedia.org/wiki/September_equinox#:~:text=the%20moment%20when%20the%20Sun%20appears%20to%20cross%20the%20celestial%20equator%2C%20heading%20southward), [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[296]{.color296by365} is the [southern solstice](https://en.wikipedia.org/wiki/December_solstice#:~:text=the%20solstice%20that%20occurs%20each%20December%20%E2%80%93%20typically%20on%2021%20December), and [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[316]{.color316by365} is the coldest day globally on average.

The last US Federal holiday of the Gregorian calendar year is [Christmas](https://en.wikipedia.org/wiki/Christmas#:~:text=annual%20festival%20commemorating%20the%20birth%20of%20Jesus%20Christ)🎄. Although it occurs on [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[299]{.color299by365}, which is the last day of [Hectoday]{.tool data-bs-toggle="tooltip" data-bs-title="hundreds of days"} 2 ([h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}2), Christmas is likely to be celebrated on [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[300]{.color300by365}, the first day of [Hectoday]{.tool data-bs-toggle="tooltip" data-bs-title="hundreds of days"} [3]{.color300by365} ([h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}[3]{.color300by365}), by people who do not use Dec and live in a UTC time zone with a negative offset. The Dec analog of the [holiday season](https://en.wikipedia.org/wiki/Christmas_and_holiday_season#:~:text=an%20annual%20period%20generally%20spanning%20from%20November%20or%20December%20to%20early%20January%20incorporating%20Christmas%20Day%20and%20New%20Year%27s%20Day) is [Hectoday]{.tool data-bs-toggle="tooltip" data-bs-title="hundreds of days"} [-1]{.color265by365} ([h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}[1]{.overline .color265by365}). 

# Day of hectoday (doh) {#sec-doh}

[Astronomical seasons](https://en.wikipedia.org/wiki/Season#Astronomical) vary in duration. Meterological seasons are 2 months in the Hindu calendar and 3 months in the Gregorian calendar, but the months in each of these calendars differ in length. The duration of a meterological season is always 3 months, 9 [x](#x){.tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"}, or 90 days in the [French Revolutionary](https://en.wikipedia.org/wiki/French_Republican_calendar#Design:~:text=There%20were%20twelve%20months%2C%20each%20divided%20into%20three%2010%2Dday%20weeks%20called%20d%C3%A9cades) calendar, 4 months, 12 [x](#x){.tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"}, or 120 days in the [Egyptian](https://en.wikipedia.org/wiki/Egyptian_calendar#:~:text=Each%20season%20was%20divided%20into%20four%20months%20of%2030%20days.%20These%20twelve%20months%20were%20initially%20numbered%20within%20each%20season%20but%20came%20to%20also%20be%20known%20by%20the%20names%20of%20their%20principal%20festivals.%20Each%20month%20was%20divided%20into%20three%2010%2Dday%20periods%20known%20as%20decans%20or%20decades) calendar, 13 weeks or 91 days in the [World Season Calendar](https://en.wikipedia.org/wiki/Isaac_Asimov#Calendar:~:text=divides%20the%20year%20into%20four%20seasons%20%28named%20A%E2%80%93D%29%20of%2013%20weeks%20%2891%20days%29%20each), and 1 [h](#h){.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}, 10 [x](#x){.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"}, 20 [p](#p){.tool data-bs-toggle="tooltip" data-bs-title="pentadays"}, or 100 days in Decalendar.

As opposed to seasons in other calendars, the 4 Dec seasons are chosen from 2 overlapping sets of 4 consecutive [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}, called "positive integer hectodays" ([pih]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer hectodays"}) and "negative integer hectodays" ([nih]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectodays"}), to match [daily global mean temperature](https://pulse.climate.copernicus.eu) patterns. Every [doy]{.tool data-bs-toggle="tooltip" data-bs-title="days of year"} is simultaneously a member of a [pih]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer hectodays"}, [nih]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectodays"}, "positive integer xún" ([pix](#pix){.tool data-bs-toggle="tooltip" data-bs-title="positive integer xún"}) and "negative integer xún" ([nix](#nix){.tool data-bs-toggle="tooltip" data-bs-title="negative integer xún"}).

::: {.column-margin .overflowequation}
$$\text{pih} = \left\lfloor\dfrac{\text{pid}}{100}\right\rfloor$$ {#eq-pih}
$$\text{nih} = \left\lfloor\dfrac{\text{nid}}{100}\right\rfloor$$ {#eq-nih}
$$\text{pix} = \left\lfloor\dfrac{\text{pid}}{10}\right\rfloor$$ {#eq-pix}
$$\text{nix} = \left\lfloor\dfrac{\text{nid}}{10}\right\rfloor$$ {#eq-nix}
:::

Day [0]{.color0} is in [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[0]{.color0}, [x]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"}[0]{.color0}, [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[4]{.overline .color330by365}, and [x]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"}[37]{.overline .color360by365}. Days [364]{.color364by365} and [365]{.color365by366} are in [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[3]{.color300by365}, [x]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"}[36]{.color360by365}, [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[1]{.overline .color265by365}, and [x]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"}[1]{.overline .color355by365}. While [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[0]{.color0} and [x]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"}[0]{.color0} start at the [boy](#boy){.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"}, both [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[3]{.color300by365} and [x]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"}36 extend beyond the "end of year" ([eoy](#eoy){.tool data-bs-toggle="tooltip" data-bs-title="end of year"}). Conversely, [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[4]{.overline .color330by365} and [x]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"}[37]{.overline .color360by365} begin before the [boy](#boy){.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"} but [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[1]{.overline .color265by365} and [x]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"}[1]{.overline .color355by365} do not go past the [eoy](#eoy){.tool data-bs-toggle="tooltip" data-bs-title="end of year"}. The [x](#x){.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"}[37]{.overline} of any common year is equivalent to and thus has the same color label as the [x](#x){.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"}36 of the prior year.

In Dec, each group of days has the same color label as its first [doy](#doy){.tool data-bs-toggle="tooltip" data-bs-title="days of year"}. Day [365]{.color365by366} does not affect pih and pix color labels but shifts [nih]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectodays"} and [nix](#nix){.tool data-bs-toggle="tooltip" data-bs-title="negative integer xún"} color labels by 1 day. If the [dyl]{.tool data-bs-toggle="tooltip" data-bs-title="Decalendar year length"} is unknown, Dec labels [nih]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectoday"} and [nix](#nix){.tool data-bs-toggle="tooltip" data-bs-title="negative integer xún"} with common year colors by default. Depending on the year, [woy](#woy){.tool data-bs-toggle="tooltip" data-bs-title="week of year"} color labels can differ by 1 to 6 days and thus can only be used when the year is known.


The [line](https://observablehq.com/plot/marks/line) chart below labels the 4 Dec seasons, [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}[0]{.color0}, [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}[1]{.color100by365}, [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}[2]{.color200by365}, and [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}[1]{.overline .color265by365}, with their respective colors: red, yellow, cyan, and violet. The cyan area denoting [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}[2]{.color200by365} is truncated to hide its overlap with the violet area representing [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}[1]{.overline .color265by365}. Coincidentally, the [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}[2]{.color200by365} and [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}[1]{.overline .color265by365} overlap begins 1 or 2 days before the soonest possible date of [Thanksgiving](https://en.wikipedia.org/wiki/Thanksgiving#:~:text=Thanksgiving%20is-,a%20national%20holiday,-celebrated%20on%20various)🦃and ends with [Christmas](https://en.wikipedia.org/wiki/Christmas#:~:text=annual%20festival%20commemorating%20the%20birth%20of%20Jesus%20Christ)🎄.

{{< include /dec/date/_season.qmd >}}

The line chart shows [ERA5](https://cds.climate.copernicus.eu/datasets/reanalysis-era5-single-levels?tab=overview#:~:text=the%20fifth%20generation%20ECMWF%20reanalysis%20for%20the%20global%20climate%20and%20weather%20for%20the%20past%208%20decades) daily global mean temperatures for every doy.
If we think of the method for assigning [doy]{.tool data-bs-toggle="tooltip" data-bs-title="days of year"} to Dec seasons in @eq-season as a [classification](https://en.wikipedia.org/wiki/Classification#:~:text=the%20activity%20of%20assigning%20objects%20to%20some%20pre%2Dexisting%20classes%20or%20categories) [model](https://en.wikipedia.org/wiki/Statistical_model#:~:text=a%20mathematical%20model%20that%20embodies%20a%20set%20of%20statistical%20assumptions%20concerning%20the%20generation%20of%20sample%20data), its "[goodness of fit](https://en.wikipedia.org/wiki/Goodness_of_fit#:~:text=a%20statistical%20model%20describes%20how%20well%20it%20fits%20a%20set%20of%20observations)" is supported by the fact that the hottest [doy]{.tool data-bs-toggle="tooltip" data-bs-title="days of year"} on average, [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[149]{.color149by365}, is near the middle of [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}[1]{.color100by365} and the coldest [doy]{.tool data-bs-toggle="tooltip" data-bs-title="days of year"} on average, [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[316]{.color316by365}, is close to the center of [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}[1]{.overline}: 365 -- 316 = 49.

::: {.noscrollequation}
$$\text{season} = \left\lfloor\dfrac{\text{pid} - \text{dyl} * \href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{[}\text{nid} \ge -100\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{]}}{100}\right\rfloor$$ {#eq-season}
:::

In general, the hottest days are in [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[1]{.color100by365}, the coldest days are in [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[1]{.overline .color265by365}, temperatures increase with time in [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[0]{.color0}, and temperatures decrease with time in [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[2]{.color200by365}. Therefore, we can refer to [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[0]{.color0}, [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[1]{.color100by365}, [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[2]{.color200by365}, and [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"}[1]{.overline .color265by365} as the rise📈, [crest](https://en.wikipedia.org/wiki/Crest_and_trough#:~:text=is%20the%20highest%20point%20of%20the%20wave)🔥, fall📉, and [trough](https://en.wikipedia.org/wiki/Crest_and_trough#:~:text=lowest%20point%20of%20the%20wave)❄️, respectively, of global mean temperatures. @tbl-hoy below shows the Dec season names in the [Northern](https://en.wikipedia.org/wiki/Northern_Hemisphere#:~:text=half%20of%20Earth%20that%20is%20north%20of%20the%20equator) and [Southern](https://en.wikipedia.org/wiki/Southern_Hemisphere#:~:text=Earth%20that%20is-,south%20of%20the%20equator,-.%20It%20contains%20all) [Hemispheres](https://en.wikipedia.org/wiki/Hemispheres_of_Earth#:~:text=any%20division%20of%20the%20globe%20into%20two%20equal%20halves). 

::: {#tbl-hoy .overflowtable}
| Hemisphere |    [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}0    |    [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}1    |    [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}2    |    [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[1]{.overline}    |
| ---------- | -------- | -------- | -------- | -------- |
|  Northern  |  Spring  |  Summer  |  Autumn  |  Winter  |
|  Southern  |  Autumn  |  Winter  |  Spring  |  Summer  |
:::

When we keep the remainder after dividing a [doy](#doy){.tool data-bs-toggle="tooltip" data-bs-title="day of year"} by 100, we obtain a "day of hectoday" ([doh](#doh){#dayofhectoday .tool data-bs-toggle="tooltip" data-bs-title="day of hectoday"}), which is the percent of an [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"} that has elapsed. If the [doy](#doy){.tool data-bs-toggle="tooltip" data-bs-title="day of year"} is a [pid](#pid){.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"}, the [h](#h){.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"} is a [pih]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer hectoday"}: \${decDoty} mod 100 = \${decDohPid}, but if it is a [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"}, the [h](#h){.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"} is a [nih](#nih){.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectoday"}: [\${Tminus}]{.overline} mod 100 = \${decDohNidMid}. The [radix complement](https://en.wikipedia.org/wiki/Method_of_complements#:~:text=The%20radix%20complement%20of,is%20defined%20as) of the [doh](#doh){#dayofhectoday .tool data-bs-toggle="tooltip" data-bs-title="day of hectoday"} (100--[doh](#doh){#dayofhectoday .tool data-bs-toggle="tooltip" data-bs-title="day of hectoday"}) is the percent of the [pih]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer hectoday"}, 100 - \${decDohPid} = \${decDohPidMid}, or the [nih](#nih){.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectoday"}, 100 - \${decDohNidMid} = \${decDohNid}, that is left.

::: {.column-margin .overflowequation}
$$\text{doh} = \text{doy} \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 100$$ {#eq-doh}
:::

Similarly, a [dox](#dox){.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} is the number of days in an [x]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"} that have passed and the radix complement of a [dox](#dox){.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} (10--[dox](#dox){.tool data-bs-toggle="tooltip" data-bs-title="days of xún"}) is the number of days in the [x]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"} that remain. The [doy](#doy){.tool data-bs-toggle="tooltip" data-bs-title="day of year"} in a year+day Dec date is [zero padded](https://en.wikipedia.org/wiki/Padding_(cryptography)#Zero_padding:~:text=be%20padded%20are-,padded%20with%20zero,-.%20The%20zero%20padding) to three digits. If the three-digit [doy](#doy){.tool data-bs-toggle="tooltip" data-bs-title="day of year"} is a [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"}:  \${decDotyPad}, its first digit is a [pih]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer hectoday"}: \${decPih}, its last two digits are a [doh](#doh){.tool data-bs-toggle="tooltip" data-bs-title="days of hectoday"}: \${decDohPid}, its first two digits are a [pix](#pix){.tool data-bs-toggle="tooltip" data-bs-title="positive integer xún"}: \${decDek}, and its final digit is a [dox](#dox){.tool data-bs-toggle="tooltip" data-bs-title="days of xún"}: \${decDotd}.

Whereas a pid gives us information on the current [pix](#pix){.tool data-bs-toggle="tooltip" data-bs-title="positive integer xún"} and [pih]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer hectoday"}, an [nid](#nid){.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} tells us about the [nix](#nix){.tool data-bs-toggle="tooltip" data-bs-title="negative integer xún"} and [nih](#nih){.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectoday"} that either are coming up next or began today. The three-digit [nid](#nid){.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} in a year+day Dec date, [\${decNidAbsPad}]{.overline}, presents an [nih](#nih){.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectoday"} with its first digit: [\${decNihPlus1Abs}]{.overline}, 
the days until that [nih](#nih){.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectoday"} with its last two digits: [\${decDohNid}]{.overline}, an [nix](#nix){.tool data-bs-toggle="tooltip" data-bs-title="negative integer xún"} with its first two digits: [\${decNixPlus1Abs}]{.overline}, and the days until that [nix](#nix){.tool data-bs-toggle="tooltip" data-bs-title="negative integer xún"} with its final digit: [\${decDoxNid}]{.overline}.

An [nih](#nih){.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectoday"} [mid]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"}, [\${decNih}]{.overline}\${decDohNidMidPad}, shows the current [nih](#nih){.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectoday"} with its first digit: [\${decNih}]{.overline}, a [doh](#doh){.tool data-bs-toggle="tooltip" data-bs-title="days of hectoday"} with its last two digits: \${decDohNidMidPad}, and a [dox](#dox){.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} with its final digit: \${decDoxNidMid}. Dec recommends switching to nih [mid]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} starting with the first day of [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[1]{.overline .color265by365} to avoid uncertainty regarding when the given year will end. The last two [nih](#nih){.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectoday"} [mid]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} of any year are [1]{.overline}98 and [1]{.overline}99. In a leap year, we may want to write [1]{.overline}98 as [1]{.overline}9[9]{.grave} and [1]{.overline}99 as [0]{.overline}0[0]{.grave}.

and then switching to nix [mid]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} beginning with the first day of [x]{.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"}[1]{.overline .color360by365} 
An [nix](#nix){.tool data-bs-toggle="tooltip" data-bs-title="negative integer xún"} [mid]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"}, [\${decNix}]{.overline}\${decDoxNidMid}, displays a [nix](#nih){.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectoday"}, [\${decNix}]{.overline}\${decDoxNidMid}, and a [dox](#dox){.tool data-bs-toggle="tooltip" data-bs-title="days of xún"}: \${decDoxNidMid}. 
, a [pih]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer hectoday"} [mid]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} exhibits the next [pih]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer hectoday"} and its (100 -- [doh](#doh){.tool data-bs-toggle="tooltip" data-bs-title="days of hectoday"}) [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 100: \${decPihPlus1}[\${decDohPidMidPad}]{.overline}, a [pix](#pix){.tool data-bs-toggle="tooltip" data-bs-title="positive integer xún"} [mid]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} reveals the succeeding [pix](#pix){.tool data-bs-toggle="tooltip" data-bs-title="positive integer xún"} and its (10 -- [doh](#doh){.tool data-bs-toggle="tooltip" data-bs-title="days of hectoday"}) [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 10: \${decDekPlus1}[\${decDotdModComp}]{.overline}.


We can see that [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}\${decPih} is \${decDohPid}% done from the current [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"}: \${decDoty}, [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}\${decPihPlus1} will begin after the remaining \${decDohPidMid}% of [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}\${decPih} expires from the current [pih]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer hectoday"} [mid]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"}: \${decPihPlus1}[\${decDohPidMidPad}]{.overline}, [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[\${decNihPlus1}]{.overline} will start once the residual \${decDohNid}% of [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[\${decNih}]{.overline} elapses from the current [nid](#nid){.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"}: [\${Tminus}]{.overline}, and [h]{.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"}[\${decNih}]{.overline} is \${decDohNidMidPad}% finished from the current [nih](#nih){.tool data-bs-toggle="tooltip" data-bs-title="negative integer hectoday"} [mid]{.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"}: [\${decNih}]{.overline}\${decDohNidMidPad}. The last digit of the [doh](#doh){.tool data-bs-toggle="tooltip" data-bs-title="days of hectoday"} is the [dox](#dox){.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} and the final digit of the 100--[doh](#doh){.tool data-bs-toggle="tooltip" data-bs-title="days of hectoday"} is the (10 -- [dox](#dox){.tool data-bs-toggle="tooltip" data-bs-title="days of xún"}) [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 10.

::: {.column-margin .overflowequation}
$$\text{dox} = \text{doh} \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 10$$ {#eq-doh2dox}
:::

Any kind of [doy](#doy){.tool data-bs-toggle="tooltip" data-bs-title="days of year"} can each be split into either an [x](#x){.tool data-bs-toggle="tooltip" data-bs-title="group of ten days"} and [dox](#dox){.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} or an [h](#h){.tool data-bs-toggle="tooltip" data-bs-title="group of one hundred days"} and [doh](#doh){.tool data-bs-toggle="tooltip" data-bs-title="days of hectoday"}, but the vinculum in a [mid](#mid){.tool data-bs-toggle="tooltip" data-bs-title="mixed integer day of year"} can can be used to emphasize one of these two options. If we want to categorize work and rest days based on [dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"} as in the Gregorian calendar instead of [dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} as in Decalendar, we can translate the "day of [era](https://en.wikipedia.org/wiki/Calendar_era#:~:text=the%20period%20of%20time%20elapsed%20since%20one%20epoch%20of%20a%20calendar)" ([doe](#doe){.tool data-bs-toggle="tooltip" data-bs-title="day of era"}) equivalent of a year+day Dec date into a [dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"}. 

# Day of era (doe) {#sec-doe}

Dec refers to midnight on [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[0]{.color0} as the "beginning of year" ([boy]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"}). At the [boy]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"}, the [pid](#pid){.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} [rolls over](https://en.wikipedia.org/wiki/Rollover#:~:text=the%20act%20of%20a%20counter%20restarting%20its%20count%20sequence) from [364]{.color364by365} or [365]{.color365by366} to [0]{.color0}. If the [nid](#nid){.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} did not reset to [-365]{.color0} or [-366]{.color0} at the [boy]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"}, it would continue from [1]{.overline .color364by365} to [0]{.color0} and thus become a [pid](#pid){.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"}. The [doe]{.tool data-bs-toggle="tooltip" data-bs-title="day of era"} is like a [nid](#nid){.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"} that became a [pid](#pid){.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} at the "beginning of era" ([boe]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of era"}), midnight on [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[0]{.color0} of Year [0]{.color0} (y[0]{.color0}), and never restarted before or after the [boe]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of era"}.

Each of the ten Dec time zones has its own [boe]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of era"}, [doe]{.tool data-bs-toggle="tooltip" data-bs-title="day of era"}, [boy]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"}, and [doy]{.tool data-bs-toggle="tooltip" data-bs-title="day of year"}. The [boe]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of era"} of the Zone [0]{.color0} ([z]{.tool data-bs-toggle="tooltip" data-bs-title="zone"}[0]{.color0}) Dec time zone is called the Dec [epoch](https://en.wikipedia.org/wiki/Epoch#:~:text=an%20instant%20in%20time%20chosen%20as%20the%20origin%20of%20a%20particular%20calendar%20era). We can convert [Julian day numbers](https://en.wikipedia.org/wiki/Julian_day#:~:text=a%20continuous%20count%20of%20days%20from%20the%20beginning%20of%20the%20Julian%20period) ([JDN]{.tool data-bs-toggle="tooltip" data-bs-title="Julian day numbers"}) to [z]{.tool data-bs-toggle="tooltip" data-bs-title="zone"}[0]{.color0} [doe]{.tool data-bs-toggle="tooltip" data-bs-title="days of era"} by subtracting the number of full days in between the start of the [Julian period](https://en.wikipedia.org/wiki/Julian_day#Terminology:~:text=a%20chronological%20interval%20of%207980%C2%A0years) and the Dec epoch, which is 1721119 if the [z]{.tool data-bs-toggle="tooltip" data-bs-title="zone"}[0]{.color0} time is later than noon and 1721120 otherwise.

Dec uses [doe]{.tool data-bs-toggle="tooltip" data-bs-title="days of era"} for [calendrical calculations](https://en.wikipedia.org/wiki/Calendrical_calculation#:~:text=a%20calculation%20concerning%20calendar%20dates), such as finding the [POSIX](https://en.wikipedia.org/wiki/POSIX#:~:text=a%20family%20of%20standards%20specified%20by%20the%20IEEE%20Computer%20Society%20for%20maintaining%20compatibility%20between%20operating%20systems) [zero-based [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}](https://pubs.opengroup.org/onlinepubs/007904875/utilities/date.html#:~:text=weekday%20as%20a%20decimal%20number%20%5B0%2C6%5D%20(0%3Dsunday)) of a given date. This year, the [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} of Christmas is \${xmasDotw} according to @eq-dow: (\${xmasDote} + \${3 - nOffInput}) [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 7 = \${xmasDotw}. Unlike [dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"}, [dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} can be found without much effort. The [dox]{.tool data-bs-toggle="tooltip" data-bs-title="days of xún"} is the last digit of the [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} or equivalently the remainder after dividing the [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} by 10 as per @eq-dox: [299]{.color299by365} [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 10 = [9]{.color9}.

::: {.noscrollequation}
$$\text{dow} = (\text{doe} + 3 - \href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{[}\text{UTC offset} < 0\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{]}) \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 7$$ {#eq-dow}
:::

@eq-dow is derived from [Howard Hinnant](https://howardhinnant.github.io)'s [`weekday_from_days`](https://howardhinnant.github.io/date_algorithms.html#weekday_from_days) algorithm -@hinnant2021date. The Dec epoch [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} is 3 = (0 + 3) [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 7. The [UNIX epoch](https://en.wikipedia.org/wiki/Unix_time#:~:text=00%3A00%3A00%20UTC%20on%201%C2%A0January%201970) [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} is 4 = (719468 + 3) [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 7. Depending on how [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) is [defined](https://en.wikipedia.org/wiki/Modulo#Variants_of_the_definition), a negative [doe]{.tool data-bs-toggle="tooltip" data-bs-title="day of era"} could yield a negative [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}. We can add 7 to a negative [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} in the bottom row of @tbl-dow to obtain the positive [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} above it.

::: {#tbl-dow .overflowtable}
|             | Sun | Mon | Tue | Wed | Thu | Fri | Sat |
| ----------- | --- | --- | --- | --- | --- | --- | --- |
|  [+]{.mono} |  0  |  1  |  2  |  3  |  4  |  5  |  6  |
|  [-]{.mono} |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
:::

Christmas is an anchored⚓️holiday because it occurs on the same [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} every year. In contrast, floating🛟holidays like Thanksgiving are always planned for the same [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} and thus can fall on various [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"}. We can use @eq-dowdif, which is inspired by [Howard Hinnant](https://howardhinnant.github.io)'s [`weekday_difference`](https://howardhinnant.github.io/date_algorithms.html#weekday_difference) algorithm, to find the floating holiday date in a given year -@hinnant2021date.

::: {.overflowequation}
$$\text{dow}_\Delta = (\text{dow}_\text{M} - \text{dow}_\text{S} + 7) \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 7$$ {#eq-dowdif}
:::

In @eq-dowdif, [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}~M~ is the [minuend](https://en.wiktionary.org/wiki/minuend#:~:text=A%20number%20or%20quantity%20from%20which%20another%20is%20to%20be%20subtracted), [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}~S~ is the [subtrahend](https://en.wikipedia.org/wiki/Subtraction#:~:text=number%20being%20subtracted), and [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}~Δ~ is the [difference](https://en.wikipedia.org/wiki/Subtraction#Notation_and_terminology:~:text=The%20result%20is%20the%20difference) between them that ranges from 0 to 6. To get the [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} of the first [Dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} [4]{.color4by7 .tool data-bs-toggle="tooltip" data-bs-title="Thursday"} after [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[266]{}, which is Thanksgiving in the United States🇺🇸and Brazil🇧🇷, we plug [4]{.color4by7} as [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}~M~ and the [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} of [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[267]{.color267by365} as [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}~S~ into @eq-dowdif, \${day266dotwDiff} = (4 [-]{.mono} \${day266dotw} + 7) [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 7, and then add 267: \${day266dotwDiff + 267} = \${day266dotwDiff} + 267.

::: {.callout-warning}
# Bad Pun Alert
[**Deck**aday the halls](https://en.wikipedia.org/wiki/Deck_the_Halls#:~:text=a%20traditional%20Christmas%20carol.) with [**dow~S~**]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"} of holly! Fa + la &times; 8! 'Tis the **[hectoday]{.tool data-bs-toggle="tooltip" data-bs-title="hundred days"}** to be jolly! Aren't you thankful that I couldn’t *thank* of a Thanksgiving pun?
:::

When the current pid is the minuend and 299 is the subtrahend, the difference is the number of days *until* [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[299]{.color299by365} if it is negative or the days *since* [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[299]{.color299by365} if it is positive. The current difference tells us that \${Math.abs(xmasDiff)} days \${xmasDiffSince} [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[299]{.color299by365} of this year: \${decYear}+[299]{.color299by365}[\${xmasDiffSign}]{.mono}\${Math.abs(xmasDiff)}. We can then subtract the [dyl]{.tool data-bs-toggle="tooltip" data-bs-title="Decalendar year length"} to get the number of days until [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}[299]{.color299by365} of next year: \${nextYear}+[299]{.color299by365}[-]{.mono}\${Math.abs(xmasNext)}.

# Year of era (yoe) {#sec-yoe}

To obtain a [doe]{.tool data-bs-toggle="tooltip" data-bs-title="day of era"} that we can plug into @eq-dow, we can use the two components of a Dec year+day date, namely a "year of era" ([yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"}) and a [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"}, to solve Equations -@eq-yoe2coe, -@eq-yoe2yoc, -@eq-date2doc, and -@eq-doe, which are based on the [`days_from_civil`](https://howardhinnant.github.io/date_algorithms.html#days_from_civil){.mono .under} algorithm created by [Howard Hinnant](https://howardhinnant.github.io) and described in his manuscript entitled [[`chrono`]{.mono .under}-Compatible Low-Level Date Algorithms](https://howardhinnant.github.io/date_algorithms.html) -@hinnant2021date.

$$\text{coe} = \biggl \lfloor \frac{\text{yoe}-399\ast\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{[}\text{yoe} \geq 0\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{]}}{400} \biggr \rfloor$$ {#eq-yoe2coe}

$$\text{yoc} = \text{yoe} - \text{coe} \ast 400$$ {#eq-yoe2yoc}

:::{.overflowequation}
$$\text{doc} = \text{yoc} \ast 365 + \left\lfloor\frac{\text{yoc}}{4}\right\rfloor - \left\lfloor\frac{\text{yoc}}{100}\right\rfloor + \text{pid}$$ {#eq-date2doc}
:::

$$\text{doe} = \text{coe} \ast 146097 + \text{doc}$$ {#eq-doe}

:::{.panel-tabset group="language"}
### Julia

```{julia}
function doe(year = 1969, pid = 306)
    coe = fld(year, 400)
    yoe = year - coe * 400
    return coe * 146097 +
           yoe * 365 +
           fld(yoe, 4) -
           fld(yoe, 100) +
           pid
end
doe()
```

### Observable JavaScript

```{ojs}
function doe(year = 1969, pid = 306) {
  const coe = Math.floor(year / 400),
        yoe = year - coe * 400;
  return coe * 146097 +
    yoe * 365 +
    Math.floor(yoe / 4) -
    Math.floor(yoe / 100) +
    pid
}
doe()
```

### Python

```{python}
def doe(year=1969, pid=306):
    coe = year // 400
    yoe = year - coe * 400
    return (
        coe * 146097
        + yoe * 365
        + yoe // 4
        - yoe // 100
        + pid
    )
doe()
```

### R

```{r}
doe <- function(year = 1969, pid = 306) {
  coe <- year %/% 400
  yoe <- year - coe * 400
  coe * 146097 +
    yoe * 365 +
    yoe %/% 4 -
    yoe %/% 100 +
    pid
}
doe()
```

:::

Equations -@eq-doe2coe, -@eq-doe2doc, -@eq-doe2yoc, -@eq-yoe, and -@eq-doe2pid below are based on [Howard Hinnant](https://howardhinnant.github.io)'s [`civil_from_days`](https://howardhinnant.github.io/date_algorithms.html#civil_from_days){.mono} algorithm and useful for obtaining Dec dates from [doe]{.tool data-bs-toggle="tooltip" data-bs-title="days of era"}, [UNIX timestamps](https://en.wikipedia.org/wiki/Unix_time#:~:text=the%20number%20of%20seconds%20that%20have%20elapsed%20since%2000%3A00%3A00%20UTC%20on%201%C2%A0January%201970), and [JDN]{.tool data-bs-toggle="tooltip" data-bs-title="Julian day numbers"} -@hinnant2021date. Regardless of whether we convert a [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"} and [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} to a [doe]{.tool data-bs-toggle="tooltip" data-bs-title="day of era"} or *vice versa*, along the way we calculate the "[cycle](https://en.wikipedia.org/wiki/Solar_cycle_(calendar)#:~:text=the%20Gregorian%20cycle%20of%20400%20years%20has%20exactly%20146%2C097%20days%2C%20i.e.%20exactly%2020%2C871%20weeks%2C%20one%20can%20say%20that%20the%20Gregorian%20so%2Dcalled%20solar%20cycle%20lasts%20400%20years) of era" ([coe]{.tool data-bs-toggle="tooltip" data-bs-title="cycle of era"}), "year of cycle" ([yoc]{.tool data-bs-toggle="tooltip" data-bs-title="year of cycle"}), and "day of cycle" ([doc]{.tool data-bs-toggle="tooltip" data-bs-title="day of cycle"}).

$$\text{coe} = \left \lfloor \frac{\text{doe}-146096\ast\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{[}\text{doe} \geq 0\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{]}}{146097} \right \rfloor$$ {#eq-doe2coe}

$$\text{doc} = \text{doe} - \text{coe} \ast 146097$$ {#eq-doe2doc}

$$\text{yoc} = \Biggl \lfloor \frac{\text{doc} - \left\lfloor \dfrac{\text{doc}}{1460} \right\rfloor + \left\lfloor \dfrac{\text{doc}}{36524} \right\rfloor - \left\lfloor \dfrac{\text{doc}}{146096} \right\rfloor}{365} \Biggr \rfloor$$ {#eq-doe2yoc}

$$\text{yoe} = \text{yoc} + \text{coe} \ast 400$$ {#eq-yoe}

$$\text{pid} = \text{doc} - \text{yoc} \ast 365 - \left \lfloor \frac{\text{yoc}}{4} \right \rfloor + \left \lfloor \frac{\text{yoc}}{100} \right \rfloor$$ {#eq-doe2pid}

:::{.panel-tabset group="language"}
### Julia

```{julia}
function date(doe = 719468)
    coe = fld(doe, 146097)
    doc = doe - coe * 146097
    yoc = fld(
        doc -
        fld(doc, 1460) +
        fld(doc, 36524) -
        fld(doc, 146096),
        365
    )
    return (
        yoc + coe * 400,
        doc - (
            yoc * 365 +
            fld(yoc, 4) -
            fld(yoc, 100)
        )
    )
end
date()
```

### Observable JavaScript

```{ojs}
function date(doe = 719468) {
  const coe = Math.floor(doe / 146097),
    doc = doe - coe * 146097,
    yoc = Math.floor(
      (
        doc
        - Math.floor(doc / 1460)
        + Math.floor(doc / 36524)
        - Math.floor(doc / 146096)
      ) / 365
    );
  return [
    yoc + coe * 400,
    doc - (
      yoc * 365 +
      Math.floor(yoc / 4) -
      Math.floor(yoc / 100)
    )
  ];
}
date()
```

### Python

```{python}
def date(doe=719468):
    coe = doe // 146097
    doc = doe - coe * 146097
    yoc = (
        doc
        - doc // 1460
        + doc // 36524
        - doc // 146096
    ) // 365
    return (
        yoc + coe * 400,
        doc - (
            yoc * 365 +
            yoc // 4 -
            yoc // 100
        )
    )
date()
```

### R

```{r}
date <- function(doe = 719468) {
  coe <- doe %/% 146097
  doc <- doe - coe * 146097
  yoc <- (
    doc -
    doc %/% 1460 +
    doc %/% 36524 -
    doc %/% 146096
  ) %/% 365
  c(
    yoc + coe * 400,
    doc - (
      yoc * 365 +
      yoc %/% 4 -
      yoc %/% 100
    )
  )
}
date()
```

:::

Dates generated by Equations -@eq-doe2coe, -@eq-doe2doc, -@eq-doe2yoc, -@eq-yoe, and -@eq-doe2pid are guaranteed to be in the standard [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"}+[pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} format. Therefore, we can standardize Dec dates by converting them to [doe]{.tool data-bs-toggle="tooltip" data-bs-title="days of era"} and then back to dates again. A [round-trip](https://en.wikipedia.org/wiki/Round-trip_format_conversion#:~:text=converting%20from%20any%20data%20representation%20and%20back%20again) "date to [doe]{.tool data-bs-toggle="tooltip" data-bs-title="day of era"} to date" conversion ensures that the [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"} is an integer and the [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} is a positive integer less than the [dyl]{.tool data-bs-toggle="tooltip" data-bs-title="Decalendar year length"}: 0 &le; [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} &lt; [dyl]{.tool data-bs-toggle="tooltip" data-bs-title="Decalendar year length"}. 

# Day of week (dow) {#sec-dow}

Even though Decalendar functions best with [x]{.tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"}, Dec dates can display [dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"} by splitting a [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} into a "beginning of week" ([bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"}) and the POSIX zero-based [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}. To obtain the [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"}, we subtract the [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} from the [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"}: [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"} = [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} [-]{.mono} [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}. According to the current [z]{.tool data-bs-toggle="tooltip" data-bs-title="zone"}[0]{.color0} [[yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"}+[bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"}+[dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}]{.nowrap} date, [\${decYear}[\${dotw0sign}]{.mono}\${dotw0dotyPad}+\${dotw}]{.nowrap}, the most recent [Dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"} [0]{.color0} was on [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}\${dotw0doty} and today is [Dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"} \${dotw}.

:::{.overflowequation}
$$\text{yoe} + \frac{\text{pid}}{\text{dyl}} = \text{yoe} + \frac{\text{bow + dow}}{\text{dyl}}$$ {#eq-bow}
:::

A Dec [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"} date can have a countup or a countdown [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"}. The countdown equivalent of [\${decYear}[\${dotw0sign}]{.mono}\${dotw0dotyPad}+\${dotw}]{.nowrap} is [\${nextYear}[-]{.mono}\${dotw0dotyNegPad}+\${dotw}]{.nowrap}. Like [nid]{.tool data-bs-toggle="tooltip" data-bs-title="negative integer day of year"}, countdown [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"} can be useful. We can add up to 52 weeks to any countdown [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"} without having to take into account the length of the year. The sum of 52 weeks and the last [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"}+[dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"} of this year is 52 &times; 7 + ${-decYearLastBowNeg} + \${decYearLastDow} = \${decYearLastBowSum} + \${decYearLastDow}.

Based on the calculation above, the Dec [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"} date that is 52 weeks after [\${nextYear}[-]{.mono}\${decYearLastBowNegPad}[+]{.mono}\${decYearLastDow}]{.nowrap} is [\${nextYear}[+]{.mono}\${decYearLastBowSumPad}[+]{.mono}\${decYearLastDow}]{.nowrap}. When we see the same [dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"} in two dates, we know that difference between them is a multiple of 7. The [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"} can be used to refer to the current week in phrases like "the week of [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}\${dotw0doty}" or "the week that begins with [d]{.tool data-bs-toggle="tooltip" data-bs-title="day"}\${dotw0doty}" and thus can function like a [woy]{.tool data-bs-toggle="tooltip" data-bs-title="week of year"}.

# Week of year (woy) {#sec-woy}

We can convert between the [[bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"}+[dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}]{.nowrap} in Dec [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"} dates and the [7&times;[woy]{.tool data-bs-toggle="tooltip" data-bs-title="week of year"}+[dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}[-]{.mono}[boy]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"}[dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}]{.nowrap} in Dec [woy]{.tool data-bs-toggle="tooltip" data-bs-title="week of year"} dates. The [boy]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"}[dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} is the [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} of the first day of the Dec year. To obtain the current [woy]{.tool data-bs-toggle="tooltip" data-bs-title="week of year"}, we sum the [boy]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"}[dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} with the current [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"} and then divide by 7: \${week} = (\${doty0dotw} + \${dotw0doty}) &div; 7. Dec truncates [woy]{.tool data-bs-toggle="tooltip" data-bs-title="week of year"} dates so that they only display the [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"}, [woy]{.tool data-bs-toggle="tooltip" data-bs-title="week of year"}, and [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}: \${decYear}[+]{.mono}\${weekPad}[+]{.mono}\${dotw}.

:::{.overflowequation}
$$\text{bow} = 7\ast\text{woy}-\text{boydow}$$ {#eq-woy}
:::

If [dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"} were like [doy]{.tool data-bs-toggle="tooltip" data-bs-title="days of year"} and reset at the [boy]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"}, the [boy]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"}[dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} would always be zero and conversion between [woy]{.tool data-bs-toggle="tooltip" data-bs-title="week of year"} and [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"} dates would be straightforward but the reality is that we need the [boy]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"}[dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} to convert a [woy]{.tool data-bs-toggle="tooltip" data-bs-title="week of year"} date to a [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"} date. Dec pads the left side of the [woy]{.tool data-bs-toggle="tooltip" data-bs-title="week of year"} and [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"} in dates with zeros so that we can distinguish between two-digit [woy]{.tool data-bs-toggle="tooltip" data-bs-title="weeks of year"} and three-digit [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginnings of week"}. 

:::{.overflowequation}
$$\text{boydow} = (7 - \text{bow}\href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod}7)\href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod}7$$ {#eq-boydow}
:::

To find the [boy]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"}[dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}, we first divide the [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginnings of week"} by 7 and subtract the remainder from 7. Then, we divide the resulting difference by 7 and keep the remainder. We could also get the [boy]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of year"}[dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"} without a [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginnings of week"} by turning the [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"} into a [doe]{.tool data-bs-toggle="tooltip" data-bs-title="day of era"} and then the [doe]{.tool data-bs-toggle="tooltip" data-bs-title="day of era"} into a [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}. Dec [woy]{.tool data-bs-toggle="tooltip" data-bs-title="week of year"} dates obfuscate🫣[pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} much more than [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of week"} dates, but may be useful for [week-based accounting](https://en.wikipedia.org/wiki/Accounting_period#52%E2%80%9353-week_fiscal_year:~:text=used%20by%20companies%20that%20desire%20that%20their%20fiscal%20year%20always%20end%20on%20the%20same%20day%20of%20the%20week)🧾.

# Day of month (dom) {#sec-dom}

Dec year+day dates can be expanded to display the "beginning of month" ([bom]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of month"}) and [POSIX [dom]{.tool data-bs-toggle="tooltip" data-bs-title="day of month"}](https://pubs.opengroup.org/onlinepubs/007904875/utilities/date.html#:~:text=day%20of%20the%20month%20as%20a%20decimal%20number%20%5B01%2C31%5D). The [bom]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of month"} is the last [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} of the previous month because POSIX [dom]{.tool data-bs-toggle="tooltip" data-bs-title="days of month"} are one-based. We can think of the [bom]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of month"} as [Dom]{.tool data-bs-toggle="tooltip" data-bs-title="days of month"} 0 despite the fact that no such [dom]{.tool data-bs-toggle="tooltip" data-bs-title="days of month"} exists in POSIX or the Gregorian calendar. To obtain the [bom]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of month"}, we can subtract the [dom]{.tool data-bs-toggle="tooltip" data-bs-title="days of month"} from the [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"}: \${monthNumber} = \${decDoty} -- \${dotm}. 

:::{.column-margin .overflowequation}
$$\text{bom} = \text{pid} - \text{dom}$$ {#eq-bom}
:::

We can find every possible [bom]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of month"} using only a pair of hands🤲by counting index☝️and ring💍fingers as 30 days and other fingers as 31 days, as shown in the pair of images below. We start counting from -1, which is the [doy]{.tool data-bs-toggle="tooltip" data-bs-title="days of year"} that preceeds the first "month of year" ([moy]{.tool data-bs-toggle="tooltip" data-bs-title="month of year"}): [Moy]{.tool data-bs-toggle="tooltip" data-bs-title="month of year"} [0]{.color0}. To cover 12 months with only 10 fingers, the first and last finger each represent 2 months.

:::{.hand}
![](/asset/left.svg){#lefthand}
![](/asset/right.svg){#righthand}
:::
[[Wikimedia](https://commons.wikimedia.org/wiki/File:Typing-colour_for-finger-positions.svg)]{.handlabel}

Like the [knuckle](https://en.wikipedia.org/wiki/Knuckle_mnemonic#:~:text=a%20mnemonic%20device%20for%20remembering%20the%20number%20of%20days%20in%20the%20months%20of%20the%20Julian%20and%20Gregorian%20calendars)👊and [musical keyboard](https://en.wikipedia.org/wiki/Month#:~:text=this%20cyclical%20pattern%20of%20month%20lengths%20matches%20the%20musical%20keyboard%20alternation%20of%20wide%20white%20keys%20(31%20days)%20and%20narrow%20black%20keys%20(30%20days))🎹[mnemonics](https://en.wikipedia.org/wiki/Mnemonic#:~:text=any%20learning%20technique%20that%20aids%20information%20retention%20or%20retrieval%20in%20the%20human%20memory), the finger🖐counting technique described above is an attempt to make sense of the irregular pattern of [month lengths](https://en.wikipedia.org/wiki/Month#:~:text=Name-,Number,of%20days) in the Gregorian calendar️. We do not need mnemonics, [rhymes](https://en.wikipedia.org/wiki/Thirty_Days_Hath_September), tables, [dactylonomy](https://en.wikipedia.org/wiki/Finger-counting#:~:text=counting%20using%20the%20fingers), or mental calculations to use [h]{.tool data-bs-toggle="tooltip" data-bs-title="groups of one hundred days"} or [x]{.tool data-bs-toggle="tooltip" data-bs-title="groups of ten days"}, because all of the required information is plainly visible in the [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"}.

# Month of year (moy) {#sec-moy}

To convert a [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} to or from a [POSIX month](https://pubs.opengroup.org/onlinepubs/007904875/utilities/date.html#:~:text=Month%20as%20a%20decimal%20number%20%5B01%2C12%5D) and [dom]{.tool data-bs-toggle="tooltip" data-bs-title="day of month"}, we can use parts of the [`civil_from_days`](https://howardhinnant.github.io/date_algorithms.html#civil_from_days){.mono .under} and [`days_from_civil`](https://howardhinnant.github.io/date_algorithms.html#days_from_civil){.mono .under} algorithms [@hinnant2021date]. POSIX months are one-based and start at [Moy]{.tool data-bs-toggle="tooltip" data-bs-title="month of year"} [10]{.color306by365}, whereas [moy]{.tool data-bs-toggle="tooltip" data-bs-title="months of year"} are zero-based and thus begin from [Moy]{.tool data-bs-toggle="tooltip" data-bs-title="month of year"} [0]{.color0}. To obtain a [moy]{.tool data-bs-toggle="tooltip" data-bs-title="month of year"}, we can plug a [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} into @eq-pid2moy or a POSIX month into @eq-month2moy.

:::{.overflowequation}
$$\text{moy} = \left\lfloor\dfrac{\text{pid} \ast 5 + 2}{153}\right\rfloor$$ {#eq-pid2moy}

$$\text{month} = (\text{moy} + 3) \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 12$$ {#eq-moy2month}

$$\text{bom} = \left\lfloor\dfrac{\text{moy} \ast 153 + 2}{5}\right\rfloor - \href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{[}\text{UTC offset} \ge 0\href{https://en.wikipedia.org/wiki/Iverson_bracket#:~:text=is%20defined%20to%20take%20the%20value%201%20for%20the%20values%20of%20the%20variables%20for%20which%20the%20statement%20is%20true%2C%20and%20takes%20the%20value%200%20otherwise}{]}$$ {#eq-moy2bom}

$$\text{dom} = \text{pid} - \text{bom}$$ {#eq-dom}

$$\text{moy} = (\text{month} + 9) \href{https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder%20or%20signed%20remainder%20of%20a%20division}{\bmod} 12$$ {#eq-month2moy}

$$\text{pid} = \text{bom} + \text{dom}$$ {#eq-bomdomsum}
:::

POSIX months and [moy]{.tool data-bs-toggle="tooltip" data-bs-title="months of year"} are shifted in relation to each other because the Dec epoch, [0000]{.color0}+[000]{.color0}, is 2 months later than the Gregorian calendar epoch: -[0001]{.color99by100}+[306]{.color306by365}. To convert years, we add 1 to the [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"} or subtract 1 from the Gregorian calendar️ "common era year" ([cey]{.tool data-bs-toggle="tooltip" data-bs-title="common era year"}) if the [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} is greater than [305]{.color305by365}, the [moy]{.tool data-bs-toggle="tooltip" data-bs-title="month of year"} is greater than [9]{.color275by365}, or the POSIX month is less than [3]{.color0}.

:::{.overflowequation}
$$
\text{cey}=\text{yoe}+\begin{cases}
  1&{\begin{aligned}
    &\text{ if } \text{pid} \,\ \ \ \ \ \gt 305\\
    &\href{https://en.wikipedia.org/wiki/Logical_disjunction}{\lor}\text{moy}\ \ \ \ \gt 9\\
    &\href{https://en.wikipedia.org/wiki/Logical_disjunction}{\lor}\text{month}\lt 3\end{aligned}}\\\\
  0&{\text{ otherwise}}\end{cases}
$$ {#eq-cey}
:::

A similar adjustment in needed when dealing with negative UTC offsets. Dec does not permit "time zone offsets" ([tzo]{.tool data-bs-toggle="tooltip" data-bs-title="time zone offsets"}) to be negative and therefore adds one day to every negative [tzo]{.tool data-bs-toggle="tooltip" data-bs-title="time zone offset"}. @eq-moy2bom takes into account the possibility of a negative UTC offset and adjusts the [bom]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of month"} accordingly. Starting from zero, we can count every adjusted [bom]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of month"} on our fingers.

:::{.hand}
![](/asset/leftnegtzo.svg){#lefthand}
![](/asset/rightnegtzo.svg){#righthand}
:::
[[Wikimedia](https://commons.wikimedia.org/wiki/File:Typing-colour_for-finger-positions.svg)]{.handlabel}

The adjusted [bom]{.tool data-bs-toggle="tooltip" data-bs-title="beginnings of month"} in the images above are exactly the same as the values in the rightmost column of the first table under the heading "[Computing day-of-year from month and day-of-month](https://howardhinnant.github.io/date_algorithms.html#Computing%20day-of-year%20from%20month%20and%20day-of-month)" in [[`chrono`]{.mono .under}-Compatible Low-Level Date Algorithms](https://howardhinnant.github.io/date_algorithms.html) [@hinnant2021date]. The adjusted and unadjusted [bom]{.tool data-bs-toggle="tooltip" data-bs-title="beginnings of month"} can be generated using @eq-moy2bom whenever necessary.

Dec dates can also be explained in terms of [object oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming#:~:text=a%20programming%20paradigm%20based%20on%20objects). In this analogy, an [object](https://en.wikipedia.org/wiki/Object_(computer_science)#:~:text=a%20semantic%20entity%20that%20has%20state%2C%20behavior%2C%20and%20identity) is a blueprint for Dec dates and an [instance](https://en.wikipedia.org/wiki/Instance_(computer_science)#:~:text=a%20specific%20occurrence%20of%20a%20software%20element%20that%20is%20based%20on%20a%20type%20definition) represents a specific Dec date. When we create an instance, we can specify the date that it will represent by providing either a [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"} and [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} for it to store or a [cey]{.tool data-bs-toggle="tooltip" data-bs-title="common era year"}, month, and [dom]{.tool data-bs-toggle="tooltip" data-bs-title="day of month"} for it to convert into a [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"} and [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"}.

Regardless of the input, only a [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"} and [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} are stored as [instance attributes](https://en.wikipedia.org/wiki/Instance_variable#:~:text=each%20instantiated%20object%20of%20the%20class%20has%20a%20separate%20copy). Anything else has to be calculated from the [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"} and [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} by an instance [method](https://en.wikipedia.org/wiki/Method_(computer_programming)#:~:text=a%20procedure%20associated%20with%20an%20object). Therefore, our instance must contain one method for every potential output that is not a [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"} or [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"}. For example, a method based on Equations -@eq-pid2moy, -@eq-moy2month, -@eq-moy2bom, and -@eq-dom could generate a month and [dom]{.tool data-bs-toggle="tooltip" data-bs-title="day of month"}.

@fig-conv below visualizes how an instance that represents the UNIX epoch would convert its [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"} and [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} into a [cey]{.tool data-bs-toggle="tooltip" data-bs-title="common era year"}, month, [dom]{.tool data-bs-toggle="tooltip" data-bs-title="day of month"}, and [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}. For simplicity, @fig-conv omits the [coe]{.under .tool data-bs-toggle="tooltip" data-bs-title="cycle of era"}, [yoc]{.tool data-bs-toggle="tooltip" data-bs-title="year of cycle"}, and [doc]{.tool data-bs-toggle="tooltip" data-bs-title="day of cycle"} needed to convert a Dec date into a [doe]{.tool data-bs-toggle="tooltip" data-bs-title="day of era"}, the [moy]{.tool data-bs-toggle="tooltip" data-bs-title="months of year"} and [bom]{.tool data-bs-toggle="tooltip" data-bs-title="beginning of month"} required to split a [doy]{.tool data-bs-toggle="tooltip" data-bs-title="day of year"} into a month and a [dom]{.tool data-bs-toggle="tooltip" data-bs-title="day of month"}, and the negative UTC offset adjustment for [bom]{.tool data-bs-toggle="tooltip" data-bs-title="beginnings of month"} and [dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"}.

::: {#fig-conv}
```{mermaid}
%%{init: {'theme': 'default', 'themeVariables': { 'fontSize': '20px'}}}%%
flowchart LR
   L[  ]:::empty
   B[  ]:::empty
   A[  ]:::empty
   L---Y
   L---D
   L-->E
   D---A
   D---B
   A-->G
   Y---A
   B-->M
   B-->N
   E-->W
   subgraph decdate[Decalendar]
   Y[yoe<br>1969]
   D[pid<br>306]
   E[doe<br>719468]
   end
   subgraph gregdate[Gregorian calendar]
   W[dow<br>4]
   G[cey<br>1970]
   M[month<br>1]
   N[dom<br>1]
   end
   classDef empty width:0px;
   click E "#doe"
   click W "#dow"
   click Y "#yoe"
   click D "#doy"
   click G "#eya"
   click M "#moy"
   click N "#dom"
```
:::

# Request for comments (rfc) {#rfc}

Dec renders the Gregorian calendar [obsolete](https://en.wikipedia.org/wiki/Obsolescence#:~:text=antiquated%2C%20out%20of%20date%2C%20old%2Dfashioned%2C%20no%20longer%20in%20general%20use%2C%20no%20longer%20useful%2C%20or%20superseded) with time units that supersede both months and weeks, but is also better than the Gregorian calendar at displaying a [dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"} as a part of a date. Whereas Dec can expand [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"} into [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginnings of week"}+[dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"}, [\${dotw0doty}+\${dotw}]{.nowrap}, the only standardized way to combine a [dow]{.tool data-bs-toggle="tooltip" data-bs-title="day of week"}, [dom]{.tool data-bs-toggle="tooltip" data-bs-title="day of month"}, and month is to truncate an [RFC 7231](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.1:~:text=preferred%20format%20is-,Sun%2C%2006%20Nov,-1994%2008%3A49) date to 11 characters: \${loadStr}.

While [bow]{.tool data-bs-toggle="tooltip" data-bs-title="beginnings of week"}+[dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"} are math expressions that evaluate to [pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer days of year"}, RFC 7231 dates are character strings that include month and [dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"} names which are abbreviated to 3 letters. Unlike names, the math notation underlying Dec dates is universal. In contrast to the [plus sign](https://en.wikipedia.org/wiki/Plus_and_minus_signs#:~:text=represents%20the%20operation%20of%20addition) in a Dec date, \${decYear}+\${decDotyPad}, the delimiters in a [RFC 9557](https://www.rfc-editor.org/info/rfc9557/#name-optional-generation-and-ele:~:text=such%20as%3A%C2%B6-,2022%2D07%2D08T00,-%3A14%3A07%2B01) date are unrelated to math operators:  \${loadIso}.

# Summary {.unnumbered #tldr}

At its heart❤️, Decalendar is a simple system that measures time solely in integer years and days. A Dec [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"}+[pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"} date is essentially an abbreviation of [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"}+[pid]{.tool data-bs-toggle="tooltip" data-bs-title="positive integer day of year"}/[dyl]{.tool data-bs-toggle="tooltip" data-bs-title="Decalendar year length"}, which is a math expression that sums the [yoe]{.tool data-bs-toggle="tooltip" data-bs-title="year of era"} with the fraction of the year that has elapsed. The difference between the denominator and the numerator of this fraction is the number of days left in the year.

Dec can perform math operations on dates to expand them so that they display different kinds of information without changing the decimal year value that they represent. Dec expanded dates can show information relevant to the Gregorian calendar such as [dom]{.tool data-bs-toggle="tooltip" data-bs-title="days of month"} and [dow]{.tool data-bs-toggle="tooltip" data-bs-title="days of week"}. In this way, Dec date expansion bridges the gap between the Dec and Gregorian calendars.

# Next {.unnumbered #next}

After reading this article, you should be able to understand my motivation for customizing [Quarto](/quarto) and the examples in my [filter](/quarto/filter) and [include](/quarto/include) articles. If you want to see the full extent of the benefits that Dec provides, I recommend that you continue through the Dec section of my site to the [time](/dec/time)⏳, [snap](/dec/snap)🫰, and [span](/dec/span)🌈articles. Dec has a lot more to offer than just dates!

:::{.datenav #fig-btmdatenav}
{{< include /asset/_decquanav.qmd >}}
:::

In addition to the aforementioned articles, many other articles on my site discuss Dec. Notably, my [Jupyter](/jupyter) article compares the code underlying Dec in several programming languages, my [Reveal](/reveal) article features a presentation that introduces Dec, and my [Observable](/observable) article describes how I demonstrate Dec in action with interactive and animated visualizations.

Thank you for your interest in Dec. You will find citation information for this article below. Please note that the original source of the algorithms underlying the conversion of Dec year+day dates and [doe]{.tool data-bs-toggle="tooltip" data-bs-title="days of era"} is [Hinnant, Howard](https://howardhinnant.github.io). [2021+185]{.tool data-bs-toggle="tooltip" data-bs-title="2021-09-01"}. "`chrono`-Compatible Low-Level Date Algorithms." \${decYear}+\${decDotyPad}. <https://howardhinnant.github.io/date_algorithms.html>.

{{< include /asset/_cite.qmd >}}

{{< include /asset/_glossary.qmd >}}

{{< include /dec/date/_index.qmd >}}

© Copyright 2026, Martin Laptev

 
  • View source