Public
Edited
Jul 29, 2024
Paused
Comments locked
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
fullYear = yearOfEra + era * 400 + (month <= 2)
Insert cell
month = mp + (mp < 10 ? 3 : -9) // map our internal month number to the civil month number
Insert cell
dayOfMonth = dayOfYear - div(offset * mp + 2, 5) + 1
Insert cell
diff = datediff(void 0, 0)
Insert cell
z === div(diff, 1000 * meanSolarDay) // expected output: true
Insert cell
z === daysFromCivil(fullYear, month, dayOfMonth) // expected output: true
Insert cell
civilFromDays(z)
Insert cell
Insert cell
mp = div(5 * dayOfYear + 2, offset) // mp === 0 is March, mp === 11 is February
Insert cell
/*!
* A value of:
* - 0 corresponds to March 1
* - 364 corresponds to February 28 of the following (civil) year
*/
dayOfYear = dayOfEra -
(365 * yearOfEra + div(yearOfEra, 4) - div(yearOfEra, 100))
Insert cell
yearOfEra = div(
dayOfEra -
div(dayOfEra, daysPer["4Y"]) +
div(dayOfEra, daysPer["100Y"]) -
div(dayOfEra, daysPer["400Y"]),
365
)
Insert cell
dayOfEra = Z - era * (daysPer["400Y"] + 1)
Insert cell
era = div(Z >= 0 ? Z : Z - daysPer["400Y"], (daysPer["400Y"] + 1))
Insert cell
Z = z + shift // shift the epoch from 1970-01-01 to 0000-03-01
Insert cell
Insert cell
z = div(+new Date(), 1000 * meanSolarDay) // today
Insert cell
Insert cell
Insert cell
origin = ((record) => (record && record["start date"]) || "0000-03-01")(
data.filter((d) => d.era === 0)[0]
)
Insert cell
shift = div(datediff(0, origin), 1000 * meanSolarDay)
Insert cell
Insert cell
Insert cell
Insert cell
/**
* Returns (year, month, day) triple in civil calendar
*
* @typedef {Object} Triple
* @property {number} year - full year
* @property {number} month - month [1, 12]
* @property {number} day - day of month
*
* @param {number} z - number of days since 1970-01-01
* @return {Triple} (year, month, day) triple
*/
function civilFromDays(z) {
/* thank you, Howard Hinnant! - mg */
z += shift;
const e = div(z >= 0 ? z : z - daysPer["400Y"], daysPer["400Y"] + 1);
const doe = z - e * (daysPer["400Y"] + 1); // [0, 146096]
const yoe = div(
doe -
div(doe, daysPer["4Y"]) +
div(doe, daysPer["100Y"]) -
div(doe, daysPer["400Y"]),
365
); // [0, 399]
const doy = doe - (365 * yoe + div(yoe, 4) - div(yoe, 100)); // [0, 365]
const mp = div(5 * doy + 2, offset); // [0, 11]
const day = doy - div(offset * mp + 2, 5) + 1; // [1, 31]
const month = mp < 10 ? mp + 3 : mp - 9; // [1, 12]
const year = yoe + e * 400 + (month <= 2);
return { year, month, day };
}
Insert cell
/**
* Returns the number of days since civil 1970-01-01.
* Negative values indicate days prior to 1970-01-01.
*
* (year, month, day) represents a date in the civil (Gregorian) calendar
*
* @param {number} year - full year
* @param {number} month - month [1, 12]
* @param {number} day - day of month
* @return {number} number of days since 1970-01-01
*/
function daysFromCivil(year, month, day) {
/* thank you, Howard Hinnant! - mg */
year -= month <= 2;
const e = div(year >= 0 ? year : year - 399, 400);
const yoe = year - e * 400; // [0, 399]
const doy =
div(offset * (month > 2 ? month - 3 : month + 9) + 2, 5) +
day -
1; // [0, 365]
const doe = yoe * 365 + div(yoe, 4) - div(yoe, 100) + doy; // [0, 146096]
return e * (daysPer["400Y"] + 1) + doe - shift;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
div = (a, n) => ((r) => (a - r) / n)(mod(a, n))
Insert cell
mod = (a, n) => (a % n) + (sign(a) !== sign(n) ? n : 0)
Insert cell
sign = Math.sign ||
((n) => {
if (n == 0 || isNaN(n)) {
return +n;
}
return n < 0 ? -1 : 1;
})
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more