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 Dec dates will help you to understand the articles on filter, script, and include files in the Quarto section of my site.
Among its many features, Quarto offers support for the Observable data analysis and visualization system. In the Observable calendar🗓️plots below, Gregorian calendar months are identified by color and each day of the year has its own cell. Despite these similarities, the two plots illustrate how the Dec (top) and Gregorian (bottom) calendars differ.
In the Gregorian calendar, a month and a day-of-month (dom) identify a specific day in a given year like a pair of coordinates, such as longitude and latitude in the geographic🌐coordinate system or x and y in the Cartesian coordinate system. Instead of months and doms, the Dec calendar (Decalendar) uses a single number: the day-of-year (doy).
Day of year (doy)
The doy chosen by the Observablerange🎚️inputs below to be highlighted with a red🟥background in the calendar🗓️plots, , functions like a pair of coordinates in the top calendar🗓️plot by selecting a group of 10 days called a dek on the x-axis↔︎️via the dek equation, = ⌊ ÷ 10⌋, and a day-of-dek (dod) on the y-axis↕with its last digit, .
The Play▶️button beneath the range🎚️inputs cycles🔄through the year so that every doy gets its turn to have a red🟥background. All Dec years start on the first day, Day 0, of the first dek of the year, Dek 0. Common years end on Day 364, the midpoint of Dek 36, whereas leap years end on Day 365, the Dec and Gregorian calendar leap day.
The toggle✅input labelled “Leap year” to the right of the Play▶️button adds or removes Day 365, and thus shifts 306 dates, Day 0 to Day 305, in the bottom calendar🗓️plot by one day, but does not change the order of any dates in the top calendar🗓️plot, because Day 365 is the last day of Dec leap years and the doy resets to zero at the start of every year.
The radio🔘input beneath the calendar🗓️plots picks the dow for Day 306, the first day of the Gregorian calendar year. Changing the Day 306dow does not affect the top calendar🗓️plot, but shifts every date in the bottom calendar🗓️plot by one to six days depending on the number of days that Week 0, the first week of the year, contributes to the year.
There are two range🎚️inputs labeled as “day of year” because every doy can be expressed as both a positive and a negative number. The typical range for doys is 0 to n-1, but negative doys typically range from -n to -1, where n is the number of days in the year. A doy outside these bounds represents a day in a previous or subsequent year.
Unlike weeks in the Gregorian calendar, doys and deks do not need to continue in an infinite unbroken sequence. The last day of the year, Day -1, is always followed by Day 0, regardless of the last 4 or 5 days of Dek 36 that extend past the end of the year. If we want to track days seamlessly across years, we can use a continuous count of days called the day-of-era (doe).
Day of era (doe)
A doe is essentially a Julian day with a different epoch. We can convert a Julian day in a doe by subtracting 1721119.5 days to shift the epoch from -4713+268.5 to 0000+000.0. To turn a UNIX timestamp into a doe, we divide by 86400 to convert seconds to days and then add 719468.0 to account for the fact that the UNIX epoch is 1969+306.0.
Dec uses does for calculations, such as finding the POSIXSunday-based dow of a given date. This year, the dow of Christmas🎄is , according to the Dec dow equation: ( + 3) mod 7 = . In contrast to the dow, finding the dod of a given Dec date does not require any calculations because the dod is simply the last digit of the integer part of the doy.
Christmas🎄is a fixed holiday because it occurs on the same doy, Day 299, every year. Unlike fixed holidays, Gregorian calendar floating holidays happen on a different doy every year so that their dow can remain constant. Dec uses the dowdelta equation, wΔ = (wM - wS + 7) mod 7, to determine which of the seven possible floating holiday dates corresponds to the given year.
In the dowdelta equation, wM is the minuenddow at which we want to arrive and wS is subtrahenddow from which we start. To get the doy of Thanksgiving🦃in the United States and Brazil, we plug 4 as wM and , the dow of Day 266 this year, as wS into the dowdelta equation, = (4 - + 7) mod 7, and then add the resulting wΔ to 266: = + 266.
Apart from the dow and dowdelta equations, the Thanksgiving🦃calculation above relies on the Dec doe equation, which is based on the days_from_civil algorithm created by Howard Hinnant and described in his manuscript entitled chrono-Compatible Low-Level Date Algorithms, to convert the cycle-of-era (coe), year-of-cycle (yoc), and doy of Day 266 into its doe:
The Dec date equations, the inverse🔁of the Dec doe equation above, are based on Howard Hinnant’s days_from_civil algorithm and is useful for obtaining Dec dates from does and doe analogs like Unix timestamps and Julian days. Apart from coe and yoc, the Dec date equations use the day-of-cycle (doc) of a doe to produce the doe’s corresponding year and doy:
Dates generated by the Dec date equations are guaranteed to be in the standard year+day format. Therefore, we can standardize Dec dates by performing a round-trip date-to-doe-to-date conversion using the Dec doe and date equations consecutively. This allows Dec to handle Dec dates with a non-integer year and a day outside the typical range of 0 ≤ day ≤ 365.
Year of era (yoe)
A doe is essentially a Dec date with a year that is always equal to 0 and a day that is unbounded. Similarly, a Dec year-of-era (yoe) is basically a Dec with a non-integer year and a day permanently set to 0. Both does and yoes allow us to represent a date as a single number and obtain the difference between two dates, either in days (dM - dS) or years (yM - yS).
Compared to does, yoes are easier to turn into Dec dates. We can convert dates to yoes and vice versa with the Dec yoe equation: y = ⌊y⌋ + d ÷ n. In the Dec yoe equation, y is the yoe, ⌊y⌋ + d is the Dec date, ⌊y⌋ is the year, d is the doy, and n is the number of days in Year ⌊y⌋. The current yoe equation values are = + ÷ .
Dec dates do not include n, because it is not needed to specify a date, remains constant for 366, 1095, or 2920 days, has only 2 possible values: 366 if ⌊y⌋+1 is a Gregorian calendar leap year and 365 if ⌊y⌋+1 is a Gregorian calendar common year, and can be determined by applying the Gregorian calendar leap year rule to ⌊y⌋+1, as shown in the Dec year length equation:
\[\text{n}=\begin{cases}
366&{\begin{align}\text{if } (\lfloor \text{y}\rfloor+1)\text{ mod }\ \ \ \ 4=0\\
\href{https://en.wikipedia.org/wiki/Logical_conjunction}{\land}(\lfloor \text{y}\rfloor+1)\text{ mod }100\neq0\\
\href{https://en.wikipedia.org/wiki/Logical_disjunction}{\lor}(\lfloor \text{y}\rfloor+1)\text{ mod }400=0\end{align}}\\\\
365&{\text{otherwise.}}\end{cases}\]
Apart from its role in the Dec date and doy equations, n is needed to convert between year+day and year-day Dec dates. The year-day version of the Dec yoe equation is ⌊y⌋+1+(d-n)÷n=y. In essence, d-n is the number of days until the start of Year ⌊y⌋+1. The current year-day date, -, tells us that Year will begin in days.
The distinction between d and d-n can also be explained in terms of computer programming. If we think of years as arrays, d and d-n are like array indexes that can be used to identify array elements or combine them into groups via slicing. In this analogy, n is the number of elements in the array, d is a positive index, and d-n is a negative index.
The yoe equation can be rearranged into the Dec doy equation, d = ⌊ymod 1 × n⌋, where ymod 1 is the decimal part of y. The current doy equation values are = ⌊ × ⌋. We can refer to a doy without a year as a floating date and a year+day date as a fixed date. Unlike other types of dates, floating dates do not specify the year and thus can apply to any year.
Fixed dates are essentially unsimplified math expressions. Instead of simplifying a fixed date into a yoe, we can do the opposite and expand it to display additional information, such as the number of days in between it and another date. For example, +299 is an expanded version of the current date which tells us that days Day 299🎄of this year.
In the example above, the minuend has been expanded into the subtrahend 299 and the difference according to the minuend equation: minuend = subtrahend + difference. If we were preparing for a rocket🚀launch, the minuend would be the current time, the subtrahend would be the planned launch time, and the difference would be the “T-minus” countdown.
To see its minuend, subtrahend, and difference at the same time, we could rewrite the expanded date above as a Dec span🌈: +=+299. Unlike expanded dates, Dec spans🌈represent time intervals instead of individual dates and are structured like the minuend equation as opposed to a math expression that can be simplified to a yoe.
Expanded dates display a subtrahend Dec spans🌈can omit their subtrahend, 2025+320=+21, or their difference, 2025+320=2025+299. Spans that omit the difference can also omit the year on either their left, 320=2025+299, or right side, 2025+320=299.
All it takes is a little bit of arithmetic! This incredible versatility is possible thanks to the mathematical basis of Dec date notation.
Day of week (dow)
Even though Dec uses deks instead of weeks, Dec dates can be modified to include POSIX Sunday-based dows. Instead of the current Dec date, +, the navigation bar (navbar) of my site displays the current Dec dow date, +, by splitting the current doy, , into the doy of the first day of the current week (Dow 0doy), , and the current POSIX dow: .
Instead of the doyd, Dec dow dates display d-w+w, where d-w is the Dow 0doy and w is the dow associated with d. We evaluate the subtraction, d-w, to obtain the Dow 0doy, but leave the addition unsimplified so we can see w. Dec dow dates supply all of the information needed to identify specific dates and coordinate schedules based on deks or weeks.
Dec dates can be further modified to include POSIX week numbers: +7×+. The current week number, , is the sum of the Dow 0doy, , and the first dow of the year (Day 0dow), , divided by 7: = ( + ) ÷ 7. The current Dec floating week date, 7×+, is therefore equal to the sum of the current doy and the Day 0dow: 7 × + = + .
Dec week dates turn d-w into 7×W-w0, where W is the week number and w0 is the Day 0dow. In this case, the subtraction is omitted, because w0 is not necessary to identify a date and can be calculated from a given y by flooring it, turning it into a doe, and passing it into the dow equation. POSIX week numbers may be useful for week-based accounting🧾.
Following the Dec week date pattern described above, we can base Dec dates on any fixed-length calendar unit, including the 20-day dudek, 30-day tridek, 40-day kvardek, 73-day sepdektri, or 90-day naŭdek. No other calendar unit can be as convenient as the 10-day dek, because our decimal numeral system allows us to naturally combine a dek, , and a dod, , into a doy: .
While weeks are not evenly divisible by two, a dek can be cut✂️into two equal halves. Each half of a dek is called a pent and can be used to schedule work and rest days. If we designate the first 3 days of each pent as work days and the remaining 2 days as a group of rest days called the pentend, we would work on Dods 0, 1, 2, 5, 6, and 7, and rest on Dods 3, 4, 8, and 9.
Day of month (dom)
Dec dates can also be modified to display Dec month and POSIX dom numbers. The current Dec dom date is ++. Dec dom dates represent each month with the last doy of the previous month because POSIX doms start from one instead of zero. For zero-baseddoms, we represent each month with its first doy: ++.
Dec dom dates replace the doyd from Dec dates with d-m+m. We evaluate the subtraction to get d-m, the Dec month number, but not the addition, so we can see m, the dom. If we combine the dom and dow patterns above, we can create hybrid Dec dates: +++, where is d-m-w, the doy of the last Dow 0 before the beginning of the month.
We can obtain Dec month numbers using only a pair of hands🤲by counting index☝️and ring💍fingers as 30 days and other fingers as 31 days. For zero-based doms, we start counting from 0. For one-based doms, we start counting from -1, as shown in the image below. To spread 12 months across 10 fingers, the first and last fingers each represent 2 months.
The finger🖐mnemonic described above is similar to the knuckle👊and musical keyboard🎹mnemonics. These mnemonics attempt to make sense of the irregular pattern of month lengths in the Gregorian calendar. As opposed to months, we do not need mnemonics, tables, or mental calculations to use deks, because all of the required information is plainly visible in the doy.
Time of day (tod)
In addition to the dek and dod, doys can also provide the time-of-day (tod). The dek, dod, and tod are all just different parts of the doy. If we floor a doy, ⌊d⌋, we get its integer part, which is a floating date that provides the dek and dod, and if we obtain the remainder after dividing a doy or a doe by 1, dmod 1, we get its decimal part, which is a tod.
The combination of a tod and a Dec time zone z is called a Dec time: .tod-z. Dec times can be appended to Dec dates to form Dec snaps🫰: year+day.tod-z. The Dec snap on the left side of the navbar of my site, +🗓️🕓, multiplies the tod by 10, × 10 = , so it is in the same deciday units as the time zone.
Next
After reading this article, you should be able to understand the examples in the filter, script, and include articles in the Quarto section of my site. To see the full extent of the benefits that Decalendar can provide, I recommend that you continue on through the Dec section of my site to the time🕰️, ISO 8601🌐, snap🫰, and span🌈articles.
flowchart LR
B[date]-->C[time]-->D[iso]-->E[snap]-->F[span]
click B "/dec/date"
click C "/dec/time"
click D "/dec/iso"
click E "/dec/snap"
click F "/dec/span"
style B stroke:#99f,stroke-width:5px
Cite
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 does is Hinnant, Howard. 2021+184. “chrono-Compatible Low-Level Date Algorithms.” +. https://howardhinnant.github.io/date_algorithms.html.
---title: Dec Dateimage: /asset/cal16.svgdescription: > Introducing the Dec calendar (Decalendar), which displays dates in years and days using math notation without the need for months or weeks.citation: url: https://maptv.github.io/dec/datealiases: - /dec/date - /datelicense: CC BY-SAlightbox: falsetoc: truetoc-depth: 4format: html: shift-heading-level-by: 3 include-after-body: - ../../asset/cite.html - ../../asset/style.html - ../../asset/stamp.html - ../../asset/tooltip.html commonmark: defaultfilters: - ../../asset/date.lua - include-code-files---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]{.yellow}+[day]{.cyan} format. Knowing the basics of Dec dates will help you to understand the articles on [filter](https://quarto.org/docs/extensions/filters.html), [script](https://quarto.org/docs/projects/scripts.html), and [include](https://quarto.org/docs/output-formats/html-basics.html#includes) files in the [Quarto section](/quarto) of my site.Among its many features, Quarto offers support for the [Observable](https://observablehq.com/) data analysis and visualization system. In the Observable [calendar🗓️plots](https://observablehq.com/@observablehq/plot-calendar) below, [Gregorian calendar](https://en.wikipedia.org/wiki/Gregorian_calendar#:~:text=the%20calendar%20used%20in%20most%20parts%20of%20the%20world) months are identified by [color](https://observablehq.com/@d3/color-schemes) and each day of the year has its own [cell](https://observablehq.com/plot/marks/cell). Despite these similarities, the two plots illustrate how the Dec (top) and Gregorian (bottom) calendars differ.In the Gregorian calendar, a month and a day-of-month ([dom]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-month"}) identify a specific day in a given year like a pair of coordinates, such as longitude and latitude in the [geographic🌐coordinate system](https://en.wikipedia.org/wiki/Geographic_coordinate_system#:~:text=a%20spherical%20or%20geodetic%20coordinate%20system%20for%20measuring%20and%20communicating%20positions%20directly%20on%20Earth%20as%20latitude%20and%20longitude) or x and y in the [Cartesian coordinate system](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#:~:text=a%20coordinate%20system%20that%20specifies%20each%20point%20uniquely%20by%20a%20pair%20of%20real%20numbers%20called%20coordinates). Instead of months and [doms]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-month"}, the Dec calendar (Decalendar) uses a single number: the day-of-year ([doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}).# Day of year (doy){id="doy"}The [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} chosen by the [Observable](https://observablehq.com/)[range](https://observablehq.com/@observablehq/input-range)🎚️inputs below to be highlighted with a red🟥background in the calendar🗓️plots, [\${dotyInput}]{.cyan}, functions like a pair of coordinates in the top calendar🗓️plot by selecting a group of 10 days called a dek on the x-axis↔️via the dek equation, [\${dekInput}]{.cyan} = ⌊[\${dotyInput}]{.cyan} ÷ 10⌋, and a day-of-dek ([dod]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-dek"}) on the y-axis↕with its last digit, [\${dodInput}]{.cyan}.The Play▶️button beneath the [range](https://observablehq.com/@observablehq/input-range)🎚️inputs cycles🔄through the year so that every [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} gets its turn to have a red🟥background. All Dec years start on the first day, [Day 0]{.underline .tool data-bs-toggle="tooltip" data-bs-title="March 1"}, of the first dek of the year, Dek 0. [Common years](https://en.wikipedia.org/wiki/Common_year#:~:text=a%20calendar%20year%20with%20365%20days) end on [Day 364]{.underline .tool data-bs-toggle="tooltip" data-bs-title="February 28"}, the midpoint of Dek 36, whereas [leap years](https://en.wikipedia.org/wiki/Leap_year#:~:text=a%20calendar%20year%20that%20contains%20an%20additional%20day) end on [Day 365]{.underline .tool data-bs-toggle="tooltip" data-bs-title="February 29"}, the Dec and Gregorian calendar [leap day](https://en.wikipedia.org/wiki/February_29#:~:text=intercalary%20date%20added%20periodically).The toggle✅input labelled "Leap year" to the right of the Play▶️button adds or removes [Day 365]{.underline .tool data-bs-toggle="tooltip" data-bs-title="February 29"}, and thus shifts 306 dates, [Day 0]{.underline .tool data-bs-toggle="tooltip" data-bs-title="March 1"} to [Day 305]{.underline .tool data-bs-toggle="tooltip" data-bs-title="December 31"}, in the bottom calendar🗓️plot by one day, but does not change the order of any dates in the top calendar🗓️plot, because [Day 365]{.underline .tool data-bs-toggle="tooltip" data-bs-title="February 29"} is the last day of Dec leap years and the [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} resets to zero at the start of every year.```{ojs}//| echo: falseviewof dotyInput = Inputs.range([0, 364 + leapInput], {value: 306, step: 1, label: "Day of year"});viewof monthInput = transformInput( Inputs.range([1, 12], {step: 1, label: "Month"}), {bind: viewof dotyInput, transform: doty2month, invert: month2doty});viewof dotyInput1 = transformInput( Inputs.range([-365 - leapInput, -1], {step: 1, label: "Day of year"}), {bind: viewof dotyInput, transform: subN, invert: addN});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))});viewof leapscrub = Inputs.form([ Scrubber(numbers, {autoplay: false, alternate: true, delay: 86.4, loopDelay: 864, format: y => "", inputStyle: "display:none;"}), Inputs.toggle({label: "Leap year", value: false}),])```::: {.column-page-right}```{ojs}//| echo: falsedecPlot = Plot.plot({ padding: 0, width: 1080, height: 240, className: "calplot", marginTop: -3, marginLeft: 31, marginBottom: 35, y: {tickSize: 0, label: "Day of dek ", domain: [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], ticks: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], tickPadding: -12, labelOffset: 22, }, x: {interval: 1, ticks: 18, label: "Dek", type: "band", tickSize: 0, tickPadding: -2, labelOffset: 32}, //fx: {tickFormat: ""}, style: { fontSize: "21px" }, color: { range: d3.schemePastel1.concat(d3.schemePastel2.slice(4, 7)).concat(d3.schemeSet1[0]), domain: months.concat("selected"), className: "cal", }, marks: [ Plot.cell(dates, { x: (d, i) => Math.floor(i / 10), y: (d, i) => i % 10, //fx: d => d.getUTCFullYear(), fill: d => Math.floor(unix2doty(d.getTime())) === dotyInput ? "selected" : months[d.getUTCMonth()], stroke: d => Math.floor(unix2doty(d.getTime())) === dotyInput ? "darkorange" : "none", strokeWidth: 3, inset: 0.5, }), Plot.text(dates, { x: (d, i) => Math.floor(i / 10), y: (d, i) => i % 10, //fx: d => d.getUTCFullYear(), text: d => d.getUTCDate() === 7 ? months[d.getUTCMonth()].slice(0, 3) : "", y: -1, frameAnchor: "left", dy: -1, monospace: true, fontSize: "18px"}), Plot.text(dates, { x: (d, i) => Math.floor(i / 10), y: (d, i) => i % 10, //fx: d => d.getUTCFullYear(), fill: d => Math.floor(unix2doty(d.getTime())) === dotyInput ? "white" : "black", //stroke: "white", text: (d, i) => String(i),//.padStart(3, "0").slice(1), monospace: true, fontSize: "13px"}) ]})``````{ojs}//| echo: falsecalPlot = Plot.plot({ padding: 0, width: 1000, height: 200, className: "calplot", marginTop: 0, marginBottom: 40, marginLeft: 42, y: {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: 2, }, x: {interval: 1, ticks: 26, label: "Week", type: "band", tickSize: 0, tickPadding: 2, labelOffset: 36}, //fx: {tickFormat: ""}, style: { fontSize: "20px" }, color: { range: d3.schemePastel1.concat(d3.schemePastel2.slice(4, 7)).concat(d3.schemeSet1[0]), domain: months.concat("selected"), className: "cal", }, marks: [ Plot.cell(datesCal, { x: d => d3.utcWeek.count(d3.utcYear(d), d), y: d => d.getUTCDay(), //fx: d => d.getUTCFullYear(), fill: d => Math.floor(unix2doty(d.getTime())) === dotyInput ? "selected" : months[d.getUTCMonth()], stroke: d => Math.floor(unix2doty(d.getTime())) === dotyInput ? "darkorange" : "none", strokeWidth: 3, inset: .5, }), Plot.text(datesCal, { x: d => d3.utcWeek.count(d3.utcYear(d), d), y: d => d.getUTCDay(), //fx: d => d.getUTCFullYear(), text: d => d.getUTCDate() === 7 ? months[d.getUTCMonth()].slice(0, 3) : "", y: -1, frameAnchor: "left", dy: -1, monospace: true, fontSize: "18px"}), Plot.text(datesCal, { x: d => d3.utcWeek.count(d3.utcYear(d), d), y: d => d.getUTCDay(), //fx: d => d.getUTCFullYear(), fill: d => Math.floor(unix2doty(d.getTime())) === dotyInput ? "white" : "black", //stroke: "white", text: d => d.getUTCDate(), //Math.floor(unix2doty(d.getTime())).toString().padStart(3, "0"), monospace: true, fontSize: "13px"}) ]})```:::[First day of the Gregorian calendar year]{.radiotitle}```{ojs}//| echo: false//| id: radiobuttonsviewof dotwInput = Inputs.radio([ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", ], {value: "Sunday"})```The radio🔘input beneath the calendar🗓️plots picks the [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} for [Day 306]{.under .tool data-bs-toggle="tooltip" data-bs-title="January 1"}, the first day of the Gregorian calendar year. Changing the [Day 306]{.under .tool data-bs-toggle="tooltip" data-bs-title="January 1"} [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} does not affect the top calendar🗓️plot, but shifts every date in the bottom calendar🗓️plot by one to six days depending on the number of days that Week 0, the first week of the year, contributes to the year.There are two range🎚️inputs labeled as "day of year" because every [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} can be expressed as both a positive and a negative number. The typical range for [doys]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-year"} is 0 to [n]{.orange}-1, but negative [doys]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-year"} typically range from -[n]{.orange} to -1, where [n]{.orange} is the number of days in the year. A [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} outside these [bounds](https://en.wikipedia.org/wiki/Upper_and_lower_bounds#:~:text=an%20upper%20bound%20or%20majorant%5B1%5D%20of%20a%20subset%20S%20of%20some%20preordered%20set%20(K%2C%20%E2%89%A4)%20is%20an%20element%20of%20K%20that%20is%20greater%20than%20or%20equal%20to%20every%20element%20of%20S.%5B2%5D%5B3%5D%20Dually%2C%20a%20lower%20bound%20or%20minorant%20of%20S%20is%20defined%20to%20be%20an%20element%20of%20K%20that%20is%20less%20than%20or%20equal%20to%20every%20element%20of%20S) represents a day in a previous or subsequent year.Unlike weeks in the Gregorian calendar, [doys]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-year"} and deks do not need to continue in an infinite unbroken sequence. The last day of the year, Day -1, is always followed by [Day 0]{.underline .tool data-bs-toggle="tooltip" data-bs-title="March 1"}, regardless of the last 4 or 5 days of Dek 36 that extend past the end of the year. If we want to track days seamlessly across years, we can use a continuous count of days called the day-of-[era](https://en.wikipedia.org/wiki/Calendar_era#:~:text=the%20period%20of%20time%20elapsed%20since%20one%20epoch%20of%20a%20calendar) ([doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"}).# Day of era (doe){id="doe"}A [doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"} is essentially a [Julian day](https://en.wikipedia.org/wiki/Julian_day#:~:text=a%20continuous%20count%20of%20days%20from%20the%20beginning%20of%20the%20Julian%20period) with a different [epoch](https://en.wikipedia.org/wiki/Epoch#:~:text=an%20instant%20in%20time%20chosen%20as%20the%20origin%20of%20a%20particular%20calendar%20era). We can convert a Julian day in a [doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"} by subtracting [1721119.5]{.cyan} days to shift the epoch from [-4713]{.under .yellow data-bs-toggle="tooltip" data-bs-title="4714 BC"}+[268]{.under .cyan data-bs-toggle="tooltip" data-bs-title="November 24"}.[5]{.under .cyan data-bs-toggle="tooltip" data-bs-title="noon"} to [0000]{.under .yellow data-bs-toggle="tooltip" data-bs-title="1 BC"}+[000]{.under .cyan data-bs-toggle="tooltip" data-bs-title="March 1"}.[0]{.under .cyan data-bs-toggle="tooltip" data-bs-title="midnight"}. To turn a [UNIX timestamp](https://en.wikipedia.org/wiki/Unix_time#:~:text=the%20number%20of%20non%2Dleap%20seconds%20that%20have%20elapsed%20since%2000%3A00%3A00%20UTC%20on%201%C2%A0January%201970) into a [doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"}, we divide by [86400](https://en.wikipedia.org/wiki/Day#:~:text=average%2C%20this%20is-,24%20hours%20(86%2C400%20seconds),-.%20As%20a%20day) to convert seconds to days and then add [719468.0]{.cyan} to account for the fact that the [UNIX epoch](https://en.wikipedia.org/wiki/Unix_time#:~:text=00%3A00%3A00%20UTC%20on%201%C2%A0January%201970) is [1969]{.under .yellow data-bs-toggle="tooltip" data-bs-title="1970"}+[306]{.under .cyan data-bs-toggle="tooltip" data-bs-title="January 1"}.[0]{.under .cyan data-bs-toggle="tooltip" data-bs-title="midnight"}.Dec uses [does]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-era"} for calculations, 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)[Sunday-based [dow]{.under .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]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} of [Christmas](https://en.wikipedia.org/wiki/Christmas#:~:text=annual%20festival%20commemorating%20the%20birth%20of%20Jesus%20Christ)🎄is [\${xmasDotw}]{.wine}, according to the Dec [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} equation: ([\${xmasDote}]{.cyan} + 3) [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 7 = [\${xmasDotw}]{.wine}. In contrast to the [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"}, finding the [dod]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-dek"} of a given Dec date does not require any calculations because the [dod]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-dek"} is simply the last digit of the [integer part](https://en.wikipedia.org/wiki/Decimal#:~:text=the%20integer%20written%20to%20the%20left%20of%20the%20decimal) of the [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}.::: {.callout-warning}# Bad Pun Alert[Dek the halls](https://en.wikipedia.org/wiki/Deck_the_Halls#:~:text=a%20traditional%20Christmas%20carol.) with [dows]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-week"} of holly! Fa + la × 8!:::Christmas🎄is a fixed holiday because it occurs on the same [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}, [Day 299]{.underline .tool data-bs-toggle="tooltip" data-bs-title="December 25"}, every year. Unlike fixed holidays, Gregorian calendar floating holidays happen on a different [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} every year so that their [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} can remain constant. Dec uses the [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} [delta](https://en.wikipedia.org/wiki/Delta_(letter)#:~:text=the%20difference%20operator) equation, [w~Δ~]{.wine} = ([w~M~]{.wine} - [w~S~]{.wine} + 7) [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 7, to determine which of the seven possible floating holiday dates corresponds to the given year.In the [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} [delta](https://en.wikipedia.org/wiki/Delta_(letter)#:~:text=the%20difference%20operator) equation, [w~M~]{.wine} is the [minuend](https://en.wiktionary.org/wiki/minuend#:~:text=A%20number%20or%20quantity%20from%20which%20another%20is%20to%20be%20subtracted)[dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} at which we want to arrive and [w~S~]{.wine} is [subtrahend](https://en.wikipedia.org/wiki/Subtraction#:~:text=number%20being%20subtracted)[dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} from which we start. To get the [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} of [Thanksgiving](https://en.wikipedia.org/wiki/Thanksgiving#:~:text=Thanksgiving%20is-,a%20national%20holiday,-celebrated%20on%20various)🦃in the United States and Brazil, we plug [4]{.wine} as [w~M~]{.wine} and [\${day266dotw}]{.wine}, the [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} of [Day 266]{.underline .tool data-bs-toggle="tooltip" data-bs-title="November 22"} this year, as [w~S~]{.wine} into the [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} [delta](https://en.wikipedia.org/wiki/Delta_(letter)#:~:text=the%20difference%20operator) equation, [\${day266dotwDiff}]{.wine} = ([4]{.wine} - [\${day266dotw}]{.wine} + 7) [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 7, and then add the resulting [w~Δ~]{.wine} to [266]{.cyan}: [\${day266dotwDiff + 266}]{.cyan} = [\${day266dotwDiff}]{.wine} + [266]{.cyan}.Apart from the [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} and [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} [delta](https://en.wikipedia.org/wiki/Delta_(letter)#:~:text=the%20difference%20operator) equations, the Thanksgiving🦃calculation above relies on the Dec [doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"} equation, which is 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), to convert 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]{.under .tool data-bs-toggle="tooltip" data-bs-title="cycle-of-era"}), year-of-cycle ([yoc]{.under .tool data-bs-toggle="tooltip" data-bs-title="year-of-cycle"}), and [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} of [Day 266]{.underline .tool data-bs-toggle="tooltip" data-bs-title="November 22"} into its [doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"}:$$\text{coe} = \Biggl \lfloor \frac{\begin{cases}\text{year}&{\text{if } \text{year} \geq 0;}\\\text{year}-399&{\text{otherwise.}}\end{cases}}{400} \Biggr \rfloor$$$$\text{yoc} = \text{year} - \text{coe} \times 400$$:::{style="overflow-x:auto;overflow-y:hidden;"}$$\text{doe} = \text{coe}\times146097 + \text{yoc}\times365 + \lfloor\frac{\text{yoc}}{4}\rfloor - \lfloor\frac{\text{yoc}}{100}\rfloor + \text{doy}$$:::The Dec date equations, the [inverse](https://en.wikipedia.org/wiki/Inverse#:~:text=Inverse%20function%2C-,a%20function%20that%20%22reverses%22%20another%20function,-Generalized%20inverse%2C%20a)🔁of the Dec [doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"} equation above, are based on Howard Hinnant's [`days_from_civil`](https://howardhinnant.github.io/date_algorithms.html#days_from_civil){.mono} algorithm and is useful for obtaining Dec dates from [does]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-era"} and [doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"} analogs like [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 [Julian days](https://en.wikipedia.org/wiki/Julian_day#:~:text=a%20continuous%20count%20of%20days%20from%20the%20beginning%20of%20the%20Julian%20period). Apart from [coe]{.under .tool data-bs-toggle="tooltip" data-bs-title="cycle-of-era"} and [yoc]{.under .tool data-bs-toggle="tooltip" data-bs-title="year-of-cycle"}, the Dec date equations use the day-of-cycle ([doc]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-cycle"}) of a [doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"} to produce the [doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"}'s corresponding year and [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}:$$\text{coe} = \Biggl \lfloor \frac{\begin{cases}\text{doe}&{\text{if } \text{doe} \geq 0;}\\\text{doe}-146096&{\text{otherwise.}}\end{cases}}{146097} \Biggr \rfloor$$$$\text{doc} = \text{doe} - \text{coe} \times 146097$$$$\text{yoc} = \biggl \lfloor \frac{\text{doc} - \lfloor \frac{\text{doc}}{1460} \rfloor + \lfloor \frac{\text{doc}}{36524} \rfloor - \lfloor \frac{\text{doc}}{146096} \rfloor}{365} \biggr \rfloor$$$$\text{year} = \text{yoc} + \text{coe} \times 400$$$$\text{doy} = \text{doc} - \text{yoc} \times 365 - \lfloor \frac{\text{yoc}}{4} \rfloor + \lfloor \frac{\text{yoc}}{100} \rfloor$$Dates generated by the Dec date equations are guaranteed to be in the standard [year]{.yellow}+[day]{.cyan} format. Therefore, we can standardize Dec dates by performing a [round-trip](https://en.wikipedia.org/wiki/Round-trip_format_conversion#:~:text=converting%20from%20any%20data%20representation%20and%20back%20again) date-to-[doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"}-to-date conversion using the Dec [doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"} and date equations consecutively. This allows Dec to handle Dec dates with a non-integer [year]{.yellow} and a [day]{.cyan} outside the typical range of [0]{.cyan} ≤[day]{.cyan} ≤[365]{.cyan}.# Year of era (yoe){#yoe}A [doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"} is essentially a Dec date with a [year]{.yellow} that is always equal to [0]{.yellow} and a [day]{.cyan} that is [unbounded](https://en.wikipedia.org/wiki/Bounded_set#:~:text=a%20set%20which%20is%20not%20bounded). Similarly, a Dec year-of-era ([yoe]{.under .tool data-bs-toggle="tooltip" data-bs-title="year-of-era"}) is basically a Dec with a non-integer [year]{.yellow} and a [day]{.cyan} permanently set to [0]{.cyan}. Both [does]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-era"} and [yoes]{.under .tool data-bs-toggle="tooltip" data-bs-title="years-of-era"} allow us to represent a date as a single number and obtain the difference between two dates, either in days ([d~M~]{.cyan} - [d~S~]{.cyan}) or years ([y~M~]{.yellow} - [y~S~]{.yellow}).Compared to [does]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-era"}, [yoes]{.under .tool data-bs-toggle="tooltip" data-bs-title="years-of-era"} are easier to turn into Dec dates. We can convert dates to [yoes]{.under .tool data-bs-toggle="tooltip" data-bs-title="years-of-era"} and vice versa with the Dec [yoe]{.under .tool data-bs-toggle="tooltip" data-bs-title="year-of-era"} equation: [y]{.yellow} = ⌊[y]{.yellow}⌋ + [d]{.cyan} ÷[n]{.orange}. In the Dec [yoe]{.under .tool data-bs-toggle="tooltip" data-bs-title="year-of-era"} equation, [y]{.yellow} is the [yoe]{.under .tool data-bs-toggle="tooltip" data-bs-title="year-of-era"}, ⌊[y]{.yellow}⌋ + [d]{.cyan} is the Dec date, ⌊[y]{.yellow}⌋ is the year, [d]{.cyan} is the [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}, and [n]{.orange} is the number of days in Year ⌊[y]{.yellow}⌋. The current [yoe]{.under .tool data-bs-toggle="tooltip" data-bs-title="year-of-era"} equation values are [\${fullfracYear}]{.yellow} = [\${decoYear}]{.yellow} + [\${decoDoty}]{.cyan} ÷[\${nDaysInYear}]{.orange}.Dec dates do not include [n]{.orange}, because it is not needed to specify a date, remains constant for 366, 1095, or 2920 days, has only 2 possible values: 366 if ⌊[y]{.yellow}⌋+1 is a Gregorian calendar leap year and 365 if ⌊[y]{.yellow}⌋+1 is a Gregorian calendar common year, and can be determined by applying the Gregorian calendar [leap year rule](https://en.wikipedia.org/wiki/Leap_year#:~:text=Every%20year%20that%20is%20exactly%20divisible%20by%20four%20is%20a%20leap%20year%2C%20except%20for%20years%20that%20are%20exactly%20divisible%20by%20100%2C%20but%20these%20centurial%20years%20are%20leap%20years%20if%20they%20are%20exactly%20divisible%20by%20400) to ⌊[y]{.yellow}⌋+1, as shown in the Dec year length equation:$$\text{n}=\begin{cases} 366&{\begin{align}\text{if } (\lfloor \text{y}\rfloor+1)\text{ mod }\ \ \ \ 4=0\\ \href{https://en.wikipedia.org/wiki/Logical_conjunction}{\land}(\lfloor \text{y}\rfloor+1)\text{ mod }100\neq0\\ \href{https://en.wikipedia.org/wiki/Logical_disjunction}{\lor}(\lfloor \text{y}\rfloor+1)\text{ mod }400=0\end{align}}\\\\ 365&{\text{otherwise.}}\end{cases}$$Apart from its role in the Dec date and [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} equations, [n]{.orange} is needed to convert between [year]{.yellow}+[day]{.cyan} and [year]{.yellow}-[day]{.pink} Dec dates. The [year]{.yellow}-[day]{.pink} version of the Dec [yoe]{.under .tool data-bs-toggle="tooltip" data-bs-title="year-of-era"} equation is ⌊[y]{.yellow}⌋+1+([d]{.cyan}-[n]{.orange})÷[n]{.orange}=[y]{.yellow}. In essence, [d]{.cyan}-[n]{.orange} is the number of days until the start of Year ⌊[y]{.yellow}⌋+1. The current [year]{.yellow}-[day]{.pink} date, [\${nextYear}]{.yellow}-[\${TminusPadded}]{.pink}, tells us that Year [\${nextYear}]{.yellow} will begin in [\${Tminus}]{.pink} days.The distinction between [d]{.cyan} and [d]{.cyan}-[n]{.orange} can also be explained in terms of computer programming. If we think of years as [arrays](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), [d]{.cyan} and [d]{.cyan}-[n]{.orange} are like array [indexes](https://en.wikipedia.org/wiki/Array_(data_structure)#Element_identifier_and_addressing_formulas:~:text=individual%20objects%20are%20selected%20by%20an%20index) that can be used to identify array elements or combine them into groups via [slicing](https://en.wikipedia.org/wiki/Array_slicing#:~:text=an%20operation%20that%20extracts%20a%20subset%20of%20elements%20from%20an%20array). In this analogy, [n]{.orange} is the number of elements in the array, [d]{.cyan} is a [positive index](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), and [d]{.cyan}-[n]{.orange} is a [negative index](https://en.wikipedia.org/wiki/Array_slicing#:~:text=specify%20an%20offset%20from%20the%20end%20of%20the%20array).The [yoe]{.under .tool data-bs-toggle="tooltip" data-bs-title="year-of-era"} equation can be rearranged into the Dec [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} equation, [d]{.cyan} = ⌊[y]{.yellow} [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 1 ×[n]{.orange}⌋, where [y]{.yellow} [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 1 is the [decimal part](https://en.wikipedia.org/wiki/Fractional_part#:~:text=the%20excess%20beyond%20that%20number%27s%20integer%20part) of [y]{.yellow}. The current [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} equation values are [\${decoDoty}]{.cyan} = ⌊[\${mod1FracYear}]{.yellow} ×[\${nDaysInYear}]{.orange}⌋. We can refer to a [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} without a year as a floating date and a [year]{.yellow}+[day]{.cyan} date as a fixed date. Unlike other types of dates, floating dates do not specify the year and thus can apply to any year.Fixed dates are essentially [unsimplified](https://en.wikipedia.org/wiki/Simplification#:~:text=the%20process%20of%20replacing%20a%20mathematical%20expression%20by%20an%20equivalent%20one%2C%20that%20is%20simpler) math expressions. Instead of simplifying a fixed date into a [yoe]{.under .tool data-bs-toggle="tooltip" data-bs-title="year-of-era"}, we can do the opposite and expand it to display additional information, such as the number of days in between it and another date. For example, [\${decoYear}]{.yellow}+[299]{.cyan}\${xmasDiffSign}[\${Math.abs(xmasDiff)}]{.denim} is an expanded version of the current date which tells us that [\${Math.abs(xmasDiff)}]{.denim} days \${xmasDiffSince} [Day 299]{.underline .tool data-bs-toggle="tooltip" data-bs-title="December 25"}🎄of this year.In the example above, the minuend [\${decoDoty}]{.cyan} has been expanded into the subtrahend [299]{.cyan} and the difference [\${xmasDiff}]{.denim} according to the minuend equation: minuend = subtrahend + difference. If we were preparing for a rocket🚀launch, the minuend would be the current time, the subtrahend would be the planned launch time, and the difference would be the ["T-minus" countdown](https://en.wikipedia.org/wiki/Countdown#:~:text=backward%20counting%20to%20indicate%20the%20time%20remaining%20before%20an%20event).To see its minuend, subtrahend, and difference at the same time, we could rewrite the expanded date above as a Dec span🌈: [\${decoYear}]{.yellow}+[\${decoDoty}]{.cyan}=[\${decoYear}]{.yellow}+[299]{.cyan}\${xmasDiffSign}[\${Math.abs(xmasDiff)}]{.denim}. Unlike expanded dates, Dec spans🌈represent time intervals instead of individual dates and are structured like the minuend equation as opposed to a math expression that can be simplified to a [yoe]{.under .tool data-bs-toggle="tooltip" data-bs-title="year-of-era"}.Expanded dates display a subtrahend Dec spans🌈can omit their subtrahend, 2025+320=+21, or their difference, 2025+320=2025+299. Spans that omit the difference can also omit the year on either their left, 320=2025+299, or right side, 2025+320=299.All it takes is a little bit of arithmetic! This incredible versatility is possible thanks to the mathematical basis of Dec date notation.# Day of week (dow){#dow}Even though Dec uses deks instead of weeks, Dec dates can be modified to include POSIX Sunday-based [dows]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-week"}. Instead of the current Dec date, [\${decoYear}]{.yellow}+[\${decoDoty}]{.cyan}, the [navigation bar](https://en.wikipedia.org/wiki/Navigation_bar#:~:text=a%20section%20of%20a%20graphical%20user%20interface%20intended%20to%20aid%20visitors%20in%20accessing%20information) (navbar) of my site displays the current Dec [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} date, [\${decoYear}]{.yellow}\${dotw0sign}[\${dotw0doty}]{.cyan}+[\${dotw}]{.wine}, by splitting the current [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}, [\${decoDoty}]{.cyan}, into the [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} of the first day of the current week ([Dow 0]{.under .tool data-bs-toggle="tooltip" data-bs-title="Sunday"} [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}), [\${dotw0doty}]{.cyan}, and the current POSIX [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"}: [\${dotw}]{.wine}.Instead of the [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} [d]{.cyan}, Dec [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} dates display [d]{.cyan}-[w]{.wine}+[w]{.wine}, where [d]{.cyan}-[w]{.wine} is the [Dow 0]{.under .tool data-bs-toggle="tooltip" data-bs-title="Sunday"} [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} and [w]{.wine} is the [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} associated with [d]{.cyan}. We evaluate the subtraction, [d]{.cyan}-[w]{.wine}, to obtain the [Dow 0]{.under .tool data-bs-toggle="tooltip" data-bs-title="Sunday"} [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}, but leave the addition unsimplified so we can see [w]{.wine}. Dec [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} dates supply all of the information needed to identify specific dates and coordinate schedules based on deks or weeks.Dec dates can be further modified to include [POSIX week numbers](https://pubs.opengroup.org/onlinepubs/007904875/utilities/date.html#:~:text=week%20of%20the%20year%20(sunday%20as%20the%20first%20day%20of%20the%20week)%20as%20a%20decimal%20number%20%5B00%2C53%5D.%20all%20days%20in%20a%20new%20year%20preceding%20the%20first%20sunday%20shall%20be%20considered%20to%20be%20in%20week%200.): [\${decoYear}]{.yellow}+7×[\${week}]{.wheat}+[\${dotw}]{.wine}. The current week number, [\${week}]{.wheat}, is the sum of the [Dow 0]{.under .tool data-bs-toggle="tooltip" data-bs-title="Sunday"} [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}, [\${dotw0doty}]{.cyan}, and the first [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} of the year ([Day 0]{.underline .tool data-bs-toggle="tooltip" data-bs-title="March 1"} [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"}), [\${doty0dotw}]{.wine}, divided by 7: [\${week}]{.wheat} = ([\${dotw0doty}]{.cyan} + [\${doty0dotw}]{.wine}) ÷ 7. The current Dec floating week date, 7×[\${week}]{.wheat}+[\${dotw}]{.wine}, is therefore equal to the sum of the current [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} and the [Day 0]{.underline .tool data-bs-toggle="tooltip" data-bs-title="March 1"} [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"}: 7 ×[\${week}]{.wheat} + [\${dotw}]{.wine} = [\${decoDoty}]{.cyan} + [\${doty0dotw}]{.wine}.Dec week dates turn [d]{.cyan}-[w]{.wine} into 7×[W]{.wheat}-[w~0~]{.wine}, where [W]{.wheat} is the week number and [w~0~]{.wine} is the [Day 0]{.underline .tool data-bs-toggle="tooltip" data-bs-title="March 1"} [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"}. In this case, the subtraction is omitted, because [w~0~]{.wine} is not necessary to identify a date and can be calculated from a given [y]{.yellow} by flooring it, turning it into a [doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"}, and passing it into the [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} equation. POSIX week numbers 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)🧾.Following the Dec week date pattern described above, we can base Dec dates on any fixed-length calendar unit, including the 20-day [dudek](https://en.wiktionary.org/wiki/dudek#Esperanto:~:text=dudek-,twenty,-Polish%5Bedit), 30-day [tridek](https://en.wiktionary.org/wiki/tridek#Esperanto:~:text=tridek-,thirty,-Categories%3A), 40-day [kvardek](https://en.wiktionary.org/wiki/kvardek#Esperanto:~:text=kvardek-,forty,-Categories%3A), 73-day [sepdektri](https://en.wiktionary.org/wiki/sepdek_tri#Esperanto:~:text=sepdek%20tri-,seventy%2Dthree,-Categories%3A), or 90-day [naŭdek](https://en.wiktionary.org/wiki/na%C5%ADdek). No other calendar unit can be as convenient as the 10-day [dek](https://en.wiktionary.org/wiki/dek#Esperanto:~:text=dek-,ten%20(10),-Derived%20terms%5B), because our [decimal numeral system](https://en.wikipedia.org/wiki/Decimal#:~:text=system%20for%20denoting%20integer%20and%20non%2Dinteger%20numbers) allows us to naturally combine a dek, [\${decoDoty.slice(0, 2)}]{.cyan}, and a [dod]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-dek"}, [\${decoDoty[2]}]{.cyan}, into a [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}: [\${decoDoty}]{.cyan}.While weeks are not evenly divisible by two, a dek can be cut✂️into two equal halves. Each half of a dek is called a pent and can be used to schedule work and rest days. If we designate the first 3 days of each pent as work days and the remaining 2 days as a group of rest days called the pentend, we would work on [Dods]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-dek"} 0, 1, 2, 5, 6, and 7, and rest on [Dods]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-dek"} 3, 4, 8, and 9.```{mermaid}%%{ init : { "theme" : "default", "flowchart" : { "curve" : "linear" }}}%%flowchart LR A[0]-->B[1]-->C[2]-->D[3]-->E[4] F[5]-->G[6]-->H[7]-->I[8]-->J[9] subgraph pentstart[work days] A B C F G H end subgraph pentend[rest days] D E I J end```# Day of month (dom){#dom}Dec dates can also be modified to display Dec month and [POSIX [dom]{.under .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) numbers. The current Dec [dom]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-month"} date is [\${decoYear}]{.yellow}+[\${monthNumber}]{.cyan}+[\${dotm}]{.magenta}. Dec [dom]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-month"} dates represent each month with the last [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} of the previous month because POSIX [doms]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-month"} start from one instead of zero. For [zero-based](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)[doms]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-month"}, we represent each month with its first [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}: [\${decoYear}]{.yellow}+[\${monthNumber0}]{.cyan}+[\${dotm0}]{.magenta}.Dec [dom]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-month"} dates replace the [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} [d]{.cyan} from Dec dates with [d]{.cyan}-[m]{.magenta}+[m]{.magenta}. We evaluate the subtraction to get [d]{.cyan}-[m]{.magenta}, the Dec month number, but not the addition, so we can see [m]{.magenta}, the [dom]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-month"}. If we combine the [dom]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-month"} and [dow]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-week"} patterns above, we can create hybrid Dec dates: [\${decoYear}]{.yellow}+[\${monthNumber - dotw}]{.cyan}+[\${dotm}]{.magenta}+[\${dotw}]{.wine}, where [\${monthNumber - dotw}]{.cyan} is [d]{.cyan}-[m]{.magenta}-[w]{.wine}, the [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} of the last [Dow 0]{.under .tool data-bs-toggle="tooltip" data-bs-title="Sunday"} before the beginning of the month.We can obtain Dec month numbers using only a pair of hands🤲by counting index☝️and ring💍fingers as 30 days and other fingers as 31 days. For zero-based [doms]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-month"}, we start counting from 0. For one-based [doms]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-month"}, we start counting from -1, as shown in the image below. To spread 12 months across 10 fingers, the first and last fingers each represent 2 months.{{< include _finger.qmd >}}The finger🖐[mnemonic](https://en.wikipedia.org/wiki/Mnemonic#:~:text=any%20learning%20technique%20that%20aids%20information%20retention%20or%20retrieval%20in%20the%20human%20memory) described above is similar to 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. These mnemonics 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.As opposed to months, we do not need mnemonics, tables, or mental calculations to use deks, because all of the required information is plainly visible in the [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}.# Time of day (tod){#tod}In addition to the dek and [dod]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-dek"}, [doys]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-year"} can also provide the time-of-day ([tod]{.under .tool data-bs-toggle="tooltip" data-bs-title="time-of-day"}). The dek, [dod]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-dek"}, and [tod]{.under .tool data-bs-toggle="tooltip" data-bs-title="time-of-day"} are all just different parts of the [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}. If we floor a [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"}, ⌊[d]{.cyan}⌋, we get its integer part, which is a floating date that provides the dek and [dod]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-dek"}, and if we obtain the remainder after dividing a [doy]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-year"} or a [doe]{.under .tool data-bs-toggle="tooltip" data-bs-title="day-of-era"} by 1, [d]{.cyan} [mod](https://en.wikipedia.org/wiki/Modulo#:~:text=returns%20the%20remainder) 1, we get its decimal part, which is a [tod]{.under .tool data-bs-toggle="tooltip" data-bs-title="time-of-day"}.The combination of a [tod]{.under .tool data-bs-toggle="tooltip" data-bs-title="time-of-day"} and a Dec time zone [z]{.lime} is called a Dec time: .[tod]{.cyan}-[z]{.lime}. Dec times can be appended to Dec dates to form Dec snaps🫰: [year]{.yellow}+[day]{.cyan}.[tod]{.cyan}-[z]{.lime}. The Dec snap on the left side of the navbar of my site, [\${decoYear}]{.yellow}\${dotw0sign}[\${dotw0doty}]{.cyan}+[\${dotw}]{.wine}🗓️[\${decidayTime}]{.cyan}\${zoneSign}[\${Math.abs(zone)}]{.lime}🕓, multiplies the [tod]{.under .tool data-bs-toggle="tooltip" data-bs-title="time-of-day"} by 10, [\${dayTime.toFixed(5)}]{.cyan} × 10 = [\${decidayTime}]{.cyan}, so it is in the same [deciday](https://en.wiktionary.org/wiki/deciday#:~:text=One%20tenth%20of%20one%20day) units as the time zone.# NextAfter reading this article, you should be able to understand the examples in the [filter](/quarto/filter), [script](/quarto/script), and [include](/quarto/include) articles in the [Quarto section](/quarto) of my site. To see the full extent of the benefits that Decalendar can provide, I recommend that you continue on through the [Dec section](/dec) of my site to the [time](/dec/time)🕰️, [ISO 8601](/dec/iso)🌐, [snap](/dec/snap)🫰, and [span](/dec/span)🌈articles.```{mermaid}%%| label: navchartflowchart LR B[date]-->C[time]-->D[iso]-->E[snap]-->F[span] click B "/dec/date" click C "/dec/time" click D "/dec/iso" click E "/dec/snap" click F "/dec/span" style B stroke:#99f,stroke-width:5px```# CiteThank 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]{.yellow}+[day]{.cyan} dates and [does]{.under .tool data-bs-toggle="tooltip" data-bs-title="days-of-era"} is [Hinnant, Howard](https://howardhinnant.github.io). [[2021]{.yellow}+[184]{.cyan}]{.underline .tool data-bs-toggle="tooltip" data-bs-title="2021-09-01"}. “`chrono`-Compatible Low-Level Date Algorithms.” [\${decoYear}]{.yellow}+[\${decoDoty}]{.cyan}. <https://howardhinnant.github.io/date_algorithms.html>.```{ojs}//| echo: false//| output: falseunix = { while(true) { yield Date.now(); }}// http://howardhinnant.github.io/date_algorithms.html#civil_from_daysfunction 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 doty2deco0(year = 1969, doty = 306, zone = 0) { return `${year.toString().padStart(4, "0")}+${Math.floor(doty).toString().padStart(3, "0")}${String(doty % 1 * 10).slice(0, 6)}-${zone}`}function dotw2diff(x, y) { return (x - y + 7) % 7;}dz = unix2dote(unix)ydz = dote2date(...dz)deco = doty2deco0(...ydz)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}decoYear = deco.slice(0, 4)nextYear = parseInt(decoYear) + 1decoDoty = deco.slice(5, 8)xmasDiff = decoDoty - 299xmasDiffSign = xmasDiff < 0 ? "-" : "+"xmasDiffSince = xmasDiff < 0 ? "are left until" : "have passed since"dotyInputStr = String(dotyInput).padStart(3, "0")dekInput = parseInt(dotyInputStr.slice(0, 2))dodInput = dotyInputStr[2]xmasDote = date2dote(ydz[0], 299)[0]xmasDotw = dote2dotw(xmasDote)dotw = Math.floor(dote2dotw(dz[0]))day266dotw = dote2dotw(date2dote(ydz[0], 266)[0])day266dotwDiff = dotw2diff(4, day266dotw)week = Math.floor((ydz[1] + doty0dotw) / 7)dotm = doty2dotm(Math.floor(ydz[1]))dotm0 = String(dotm - 1).padStart(2, "0")dotm1 = dotm.toString().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]) - dotwdoty0dote = date2dote(ydz[0], 0, ydz[2])doty0dotw = dote2dotw(...doty0dote)dotw0sign = dotw0doty < 0 ? "-" : "+"dayTime = dz[0] % 1decidayTime = (dayTime * 10).toFixed(4)zone = dz[1]zoneSign = zone < 0 ? "+" : "-"nDaysInYear = 365 + year2leap(ydz[0] + 1)Tminus = nDaysInYear - decoDotyTminusPadded = Tminus.toString().padStart(3, "0")fracYear = ydz[0] + ydz[1] / nDaysInYearfullfracYear = (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"];today = new Date()monthName = today.toLocaleString('default', { month: 'long' });monthNumJS = today.getMonth();currMonth = monthNums[monthNumJS]nextMonth = monthNums[(monthNumJS + 1) % 12]dekStart = Math.floor(decoDoty / 10) * 10diff = parseInt(currMonth || 0) - parseInt(nextMonth || nDaysInYear) //currMonth === "" ? 0 : parseInt(currMonth) - nextMonth === "" ? nDaysInYear : parseInt(nextMonth)// https://observablehq.com/@juang1744/transform-input/1transformInput = 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;}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;}function doty2month(doty = 0) { const m = Math.floor((5 * doty + 2) / 153); return Math.floor(m < 10 ? m + 3 : m - 9);}function month2doty(month = 1) { return Math.floor( (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5)}function doty2dotm(doty = 0) { const m = Math.floor((5 * doty + 2) / 153); return doty - Math.floor((153 * m + 2) / 5) + 1;}numbers = Array.from({length: 366}, (_, i) => i)set(viewof dotyInput, leapscrub[0])// https://observablehq.com/@observablehq/synchronized-inputsfunction set(input, value) { input.value = value; input.dispatchEvent(new Event("input", {bubbles: true}));}// https://observablehq.com/@mbostock/scrubberfunction 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;}calYear = !leapInput && dotwInput == "Monday" ? 6 : !leapInput && dotwInput == "Tuesday" ? 7 : !leapInput && dotwInput == "Wednesday" ? 2 : !leapInput && dotwInput == "Thursday" ? 3 : !leapInput && dotwInput == "Friday" ? 9 : !leapInput && dotwInput == "Saturday" ? 10 : !leapInput && dotwInput == "Sunday" ? 11 : leapInput && dotwInput == "Monday" ? 12 : leapInput && dotwInput == "Tuesday" ? 24 : leapInput && dotwInput == "Wednesday" ? 8 : leapInput && dotwInput == "Thursday" ? 20 : leapInput && dotwInput == "Friday" ? 4 : leapInput && dotwInput == "Saturday" ? 16 : leapInput && dotwInput == "Sunday" ? 28 : 0;datesCal = d3.utcDays(new Date(calYear, 0, 0), new Date(calYear, 12, 0));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 doty2deco(yearDoty = [1969, 306], zone = 0) { const yd = dote2date(...date2dote(yearDoty[0], Math.floor(yearDoty[1]), zone)); return `${yd[0].toString().padStart(4, "0")}+${yd[1].toString().padStart(3, "0")}${ yearDoty[1].toString().includes(".") ? "." + ( (yearDoty[1] > 0) ? (yearDoty[1] - zone).toString().split(".").pop() : [...(yearDoty[1] - zone).toString().split(".").pop()].map( (e, i, a) => (i + 1 === a.length) ? 10 - e : 9 - e ).join("") ) : "" }`}function deco2doty(timestamp = "1969+306.00000Z") { const arr = timestamp.toString().split(/(?=[+-]|[a-zA-Z])/, 3); switch (arr.length) { case 1: return [unix2doty(Date.now())[0], parseFloat(arr[0]), 0]; case 2: return (/^[a-zA-Z]+$/.test(arr[1])) ? [unix2doty(Date.now())[0], parseFloat(arr[0]), zone2hour(arr[1]) / 24] : [parseFloat(arr[0]), parseFloat(arr[1]), 0]; }; return [parseFloat(arr[0]), parseFloat(arr[1]), /^[a-zA-Z]+$/.test(arr[2]) ? zone2hour(arr[2]) / 24 : parseFloat(arr[2].replace(/([+-])/, "$1\."))];}function zone2hour(zone = "Z") { return (zone = zone.toUpperCase()) == "Z" ? 0 : zone > "@" && zone < "J" ? zone.charCodeAt() - 64 : zone > "J" && zone < "N" ? zone.charCodeAt() - 65 : zone < "Z" && zone > "M" ? -(zone.charCodeAt() - 77) : zone;}function doty2unix(year = 1969, doty = 306, zone = 0) { return (date2dote(year, doty, zone) - 719468) * 86400000;}function doty2isoc(yd) { return new Date(doty2unix(...yd))}function doty2greg(doty = 306) { const m = Math.floor((5 * doty + 2) / 153); return [ Math.floor(m < 10 ? m + 3 : m - 9), Math.floor(doty - (153 * m + 2) / 5 + 2) ];}function greg2doty(month = 1, day = 1) { return Math.floor( (153 * (month > 2 ? month - 3 : month + 9) + 2) / 5 + day - 1)}function greg2year(year = 1970, month = 1) { return year - (month < 3) }function isoc2doty(isoc) { return [greg2year(isoc.getFullYear(), isoc.getUTCMonth() + 1), greg2doty(isoc.getUTCMonth() + 1, isoc.getUTCDate())];}leapInput = leapscrub[1]function addN(d) { return d + 365 + leapInput }function subN(d) { return d - 365 - leapInput }dates = d3.utcDays(new Date(1999, 2, 0), new Date(2000, 1, 28 + leapInput));``````{=html}<style>h6.relative.anchored { margin-top: -25px; margin-bottom: -2px;}<!-- .calplot { --><!-- margin-top: -15px; --><!-- margin-bottom: -15px; --><!-- } -->#decalendar > g.cluster-label { transform: translate(305px, 50px) !important;}span.cal-swatch { font-size: 14px !important;}form.oi-3a86ea-checkbox { max-width: 700px;}div.cell:has(form.oi-3a86ea-toggle) { display: flex; flex-wrap: wrap; align-items: center;}div.observablehq > div:has(form.oi-3a86ea-toggle) { display: flex; flex-wrap: wrap; align-items: center;}form.oi-3a86ea-toggle { max-width: 100% !important; --label-width: 100px; display: flex; flex-wrap: wrap; align-items: center;}form.oi-3a86ea { --input-width: 200px; padding-right: 9px;}form.oi-3a86ea-toggle > label { width: 75px;}input.oi-3a86ea-input[type="checkbox"] { margin: 4px 0px 0px 0px;}div > form > label { --label-width: 140px;}input[type="radio"] { margin: 1px 0px 0px 0px;}p:has(.radiotitle) { margin-top: -3px; margin-bottom: -3px;}#radiobuttons { margin-bottom: -12px;}svg#finger { max-width: 760px;}h4.anchored { margin: 8px 0px 8px 0px;}</style>```