Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 215 additions & 13 deletions calendarium@kami911/files/calendarium@kami911/desklet.js

Large diffs are not rendered by default.

102 changes: 101 additions & 1 deletion calendarium@kami911/files/calendarium@kami911/lib/calendars.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,20 @@
* • Hebrew calendar (Dershowitz-Reingold algorithmic method)
* • Islamic calendar (tabular/arithmetic method)
* • Persian calendar (Solar Hijri / Jalali, algorithmic)
* • French Republican calendar (equinox-based, historically accurate —
* see the toFrenchRepublican doc comment below)
*
* All conversion routines work through the Julian Day Number (JDN) as an
* intermediate representation so each calendar is independent of the others.
* intermediate representation so each calendar is independent of the others,
* except French Republican, which depends on lib/solstice.js for its real
* astronomical autumn-equinox timing (desklet.js pushes lib/ onto
* imports.searchPath before any lib module loads, so this resolves fine).
*
* This module exports a single `Calendars` object.
*/

const Solstice = imports.solstice.Solstice;

var Calendars = {

// ════════════════════════════════════════════════════════════════════
Expand Down Expand Up @@ -47,6 +54,21 @@ var Calendars = {
"Mehr", "Aban", "Azar", "Dey", "Bahman", "Esfand"
],

_FRENCH_REPUBLICAN_MONTHS: [
"Vendémiaire", "Brumaire", "Frimaire",
"Nivôse", "Pluviôse", "Ventôse",
"Germinal", "Floréal", "Prairial",
"Messidor", "Thermidor", "Fructidor"
],

// The 5 (or 6, in a sextile/leap year) intercalary days following
// Fructidor. Index 5 ("Jour de la Révolution") only applies in years
// whose cycle spans 366 days.
_FRENCH_REPUBLICAN_SANSCULOTTIDES: [
"Jour de la Vertu", "Jour du Génie", "Jour du Travail",
"Jour de l'Opinion", "Jour des Récompenses", "Jour de la Révolution"
],

// ════════════════════════════════════════════════════════════════════
// Gregorian → Julian Day Number
// ════════════════════════════════════════════════════════════════════
Expand Down Expand Up @@ -371,5 +393,83 @@ var Calendars = {
formatPersian: function(year, month, day) {
var p = this.toPersian(year, month, day);
return p.day + " " + this._PERSIAN_MONTHS[p.month - 1] + " " + p.year;
},

// ════════════════════════════════════════════════════════════════════
// French Republican calendar (equinox-based, historically accurate)
// ════════════════════════════════════════════════════════════════════
//
// Year 1 began at the true autumnal equinox of 1792 (22 September
// 1792), and each subsequent Republican year begins at the *next*
// true autumnal equinox — not a fixed arithmetic leap-year rule (the
// later "Romme method" some software uses). Whether a given Republican
// year has 5 or 6 intercalary Sansculottide days falls out naturally
// from the actual number of days between two real consecutive
// equinoxes (365 or 366), which is why this is built on
// Solstice.getForYear()'s real astronomical calculation.

/**
* Build a local-midnight Date for the calendar day a (possibly
* UTC-instant) Date falls on. Mirrors solstice.js's own getNext()
* technique of comparing local calendar days rather than raw UTC
* instants, to avoid timezone-driven off-by-one-day bugs.
* @param {Date} d
* @returns {Date}
*/
_localMidnight: function(d) {
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0);
},

/**
* Convert a Gregorian date to the French Republican calendar.
* @param {number} year Gregorian year
* @param {number} month 1–12
* @param {number} day 1–31
* @returns {Object} { year, month, day, sansculottide }
* month/day are 1-based and only meaningful when sansculottide === -1;
* sansculottide is 0-4 (or 0-5 in a sextile year) for one of the 5/6
* intercalary days, or -1 for a regular month day.
*/
toFrenchRepublican: function(year, month, day) {
var target = new Date(year, month - 1, day, 0, 0, 0, 0);

// Which autumn equinox is this date's applicable Republican New Year?
var newYearEvent = Solstice.getForYear(year).autumn;
var newYearMidnight = this._localMidnight(newYearEvent);
var republicanYear = year - 1791;

if (target.getTime() < newYearMidnight.getTime()) {
// Not yet reached this Gregorian year's autumn equinox —
// the applicable New Year is the previous one.
newYearEvent = Solstice.getForYear(year - 1).autumn;
newYearMidnight = this._localMidnight(newYearEvent);
republicanYear = year - 1792;
}

var msPerDay = 86400000;
var daysSinceNewYear = Math.round((target.getTime() - newYearMidnight.getTime()) / msPerDay);

if (daysSinceNewYear < 360) {
var rMonth = Math.floor(daysSinceNewYear / 30) + 1;
var rDay = (daysSinceNewYear % 30) + 1;
return { year: republicanYear, month: rMonth, day: rDay, sansculottide: -1 };
}

return { year: republicanYear, month: 0, day: 0, sansculottide: daysSinceNewYear - 360 };
},

/**
* Format a French Republican calendar date as a human-readable string.
* @param {number} year Gregorian year (will be converted internally)
* @param {number} month 1–12
* @param {number} day 1–31
* @returns {string} e.g. "3 Brumaire, an 234" or "Jour de la Vertu, an 3"
*/
formatFrenchRepublican: function(year, month, day) {
var r = this.toFrenchRepublican(year, month, day);
if (r.sansculottide >= 0) {
return this._FRENCH_REPUBLICAN_SANSCULOTTIDES[r.sansculottide] + ", an " + r.year;
}
return r.day + " " + this._FRENCH_REPUBLICAN_MONTHS[r.month - 1] + ", an " + r.year;
}
};
27 changes: 25 additions & 2 deletions calendarium@kami911/files/calendarium@kami911/lib/zodiac.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,28 @@
* This module exports a single `Zodiac` object.
*/

// Local identity function so xgettext can extract these strings.
// Actual translation is done by the caller (desklet.js) via its own _().
function _(s) { return s; }

// Return the globe emoji for the Earth element based on the system locale.
// 🌍 U+1F30D — Europe / Africa (default)
// 🌎 U+1F30E — Americas
// 🌏 U+1F30F — Asia / Pacific
function _getGlobeEmoji() {
let lang = "";
try {
let langs = imports.gi.GLib.get_language_names();
if (langs && langs.length > 0) lang = langs[0].toLowerCase();
} catch(e) {}

if (/^(en_us|en_ca|es_mx|es_us|es_co|es_ar|es_cl|es_pe|es_ve|pt_br|fr_ca)/.test(lang))
return "\uD83C\uDF0E"; // 🌎 Americas
if (/^(zh|ja|ko|hi|th|vi|id|ms|fil|bn|ta|te|mr|ur|fa|my|km|lo|si)/.test(lang))
return "\uD83C\uDF0F"; // 🌏 Asia-Pacific
return "\uD83C\uDF0D"; // 🌍 Europe-Africa (default)
}

var Zodiac = {

// ── Western zodiac ──────────────────────────────────────────────────
Expand Down Expand Up @@ -85,11 +107,12 @@ var Zodiac = {

// One emoji per element (index matches ELEMENTS above).
// BMP chars use \uXXXX; SMP chars use surrogate pairs.
// Earth globe is locale-aware: Europe-Africa / Americas / Asia-Pacific.
ELEMENT_SYMBOLS: [
"\uD83C\uDF33", // 🌳 Wood U+1F333 deciduous tree
"\uD83D\uDD25", // 🔥 Fire U+1F525
"\u26F0", // ⛰ Earth U+26F0 mountain
"\u2699", // Metal U+2699 gear
_getGlobeEmoji(),// 🌍/🌎/🌏 Earth — locale-dependent
"\uD83D\uDEE1", // 🛡 Metal U+1F6E1 shield
"\uD83D\uDCA7" // 💧 Water U+1F4A7 droplet
],

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"uuid": "calendarium@kami911",
"name": "Calendarium",
"description": "A rich calendar desklet with moon phase, sunrise/sunset, zodiac, name days, traditional month names, and optional Wikipedia features.",
"version": "1.0",
"version": "1.1",
"max-instances": "5",
"author": "kami911",
"website": "https://github.com/kami911"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ msgstr ""
msgid "Persian date"
msgstr ""

#. desklet.js:1295
msgid "French Republican date"
msgstr ""

#. metadata.json->name
msgid "Calendarium"
msgstr ""
Expand Down Expand Up @@ -394,6 +398,7 @@ msgstr ""
msgid "Wikipedia (Internet Required)"
msgstr ""

#. settings-schema.json->page-appearance->title
#. settings-schema.json->section-appearance->title
msgid "Appearance"
msgstr ""
Expand Down Expand Up @@ -648,7 +653,13 @@ msgid "Show equinox and solstice"
msgstr ""

#. settings-schema.json->use-manual-location->description
msgid "Use manual location (default: Budapest, Hungary)"
msgid "Use manual location"
msgstr ""

#. settings-schema.json->use-manual-location->tooltip
msgid ""
"When off, the location is detected automatically from the computer's system "
"timezone (falling back to Budapest, Hungary if it cannot be determined)."
msgstr ""

#. settings-schema.json->location-search->description
Expand Down Expand Up @@ -679,6 +690,28 @@ msgstr ""
msgid "Longitude (positive = East)"
msgstr ""

#. settings-schema.json->primary-tz->description
msgid "Primary location timezone (IANA, e.g. Europe/Budapest)"
msgstr ""

#. settings-schema.json->primary-tz->tooltip
msgid ""
"Timezone used for the primary location's sunrise/sunset and moonrise/moonset "
"times. Filled automatically when using city search. Leave empty to use the "
"computer's system timezone."
msgstr ""

#. settings-schema.json->use-primary-tz-for-clock->description
msgid "Show the clock and date in the primary location's timezone"
msgstr ""

#. settings-schema.json->use-primary-tz-for-clock->tooltip
msgid ""
"When off, the clock, date and calendar follow the computer's own time. When "
"on, they use the primary location's timezone (from the field above, or the "
"auto-detected system timezone)."
msgstr ""

#. settings-schema.json->city1-name->description
msgid "City 1 name (leave empty to disable)"
msgstr ""
Expand Down Expand Up @@ -911,6 +944,26 @@ msgid ""
"0 = fully transparent (wallpaper shows through), 1 = solid black background"
msgstr ""

#. settings-schema.json->show-border->description
msgid "Draw a border around the desklet"
msgstr ""

#. settings-schema.json->border-width->description
msgid "Border width"
msgstr ""

#. settings-schema.json->border-color->description
msgid "Border color"
msgstr ""

#. settings-schema.json->border-radius->description
msgid "Corner radius"
msgstr ""

#. settings-schema.json->border-radius->tooltip
msgid "0 = square corners"
msgstr ""

#. settings-schema.json->show-julian->description
msgid "Show Julian calendar date"
msgstr ""
Expand All @@ -926,3 +979,11 @@ msgstr ""
#. settings-schema.json->show-persian->description
msgid "Show Persian calendar date"
msgstr ""

#. settings-schema.json->show-french-republican->description
msgid "Show French Republican calendar date"
msgstr ""

#. settings-schema.json->show-french-republican->tooltip
msgid "Equinox-based (the historically accurate rule): each Republican year begins at the true autumnal equinox, so 5 or 6 intercalary days fall out naturally rather than from a fixed leap-year formula."
msgstr ""
12 changes: 12 additions & 0 deletions calendarium@kami911/files/calendarium@kami911/po/de.po
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,10 @@ msgstr "Islamisches Datum"
msgid "Persian date"
msgstr "Persisches Datum"

#. desklet.js:1295
msgid "French Republican date"
msgstr "Französisch-republikanisches Datum"

#. metadata.json->name
msgid "Calendarium"
msgstr "Calendarium"
Expand Down Expand Up @@ -935,3 +939,11 @@ msgstr "Datum im islamischen Kalender anzeigen"
#. settings-schema.json->show-persian->description
msgid "Show Persian calendar date"
msgstr "Datum im persischen Kalender anzeigen"

#. settings-schema.json->show-french-republican->description
msgid "Show French Republican calendar date"
msgstr "Datum im französisch-republikanischen Kalender anzeigen"

#. settings-schema.json->show-french-republican->tooltip
msgid "Equinox-based (the historically accurate rule): each Republican year begins at the true autumnal equinox, so 5 or 6 intercalary days fall out naturally rather than from a fixed leap-year formula."
msgstr "Äquinoktium-basiert (die historisch korrekte Regel): Jedes Republikjahr beginnt mit der wahren Herbst-Tagundnachtgleiche, sodass sich die 5 oder 6 Zusatztage natürlich ergeben, statt aus einer festen Schaltjahrformel."
12 changes: 12 additions & 0 deletions calendarium@kami911/files/calendarium@kami911/po/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,10 @@ msgstr "Fecha islámica"
msgid "Persian date"
msgstr "Fecha persa"

#. desklet.js:1295
msgid "French Republican date"
msgstr "Fecha republicana francesa"

#. metadata.json->name
msgid "Calendarium"
msgstr "Calendarium"
Expand Down Expand Up @@ -903,3 +907,11 @@ msgstr "Mostrar fecha del calendario islámico"
#. settings-schema.json->show-persian->description
msgid "Show Persian calendar date"
msgstr "Mostrar fecha del calendario persa"

#. settings-schema.json->show-french-republican->description
msgid "Show French Republican calendar date"
msgstr "Mostrar fecha del calendario republicano francés"

#. settings-schema.json->show-french-republican->tooltip
msgid "Equinox-based (the historically accurate rule): each Republican year begins at the true autumnal equinox, so 5 or 6 intercalary days fall out naturally rather than from a fixed leap-year formula."
msgstr "Basado en el equinoccio (la regla históricamente precisa): cada año republicano comienza en el equinoccio de otoño real, por lo que los 5 o 6 días adicionales surgen de forma natural, no de una fórmula fija de año bisiesto."
12 changes: 12 additions & 0 deletions calendarium@kami911/files/calendarium@kami911/po/fr.po
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,10 @@ msgstr "Date islamique"
msgid "Persian date"
msgstr "Date persane"

#. desklet.js:1295
msgid "French Republican date"
msgstr "Date du calendrier républicain"

#. metadata.json->name
msgid "Calendarium"
msgstr "Calendarium"
Expand Down Expand Up @@ -955,3 +959,11 @@ msgstr "Afficher la date du calendrier islamique"
#. settings-schema.json->show-persian->description
msgid "Show Persian calendar date"
msgstr "Afficher la date du calendrier persan"

#. settings-schema.json->show-french-republican->description
msgid "Show French Republican calendar date"
msgstr "Afficher la date du calendrier républicain français"

#. settings-schema.json->show-french-republican->tooltip
msgid "Equinox-based (the historically accurate rule): each Republican year begins at the true autumnal equinox, so 5 or 6 intercalary days fall out naturally rather than from a fixed leap-year formula."
msgstr "Basé sur l'équinoxe (la règle historiquement exacte) : chaque année républicaine commence au véritable équinoxe d'automne, de sorte que les 5 ou 6 jours complémentaires en découlent naturellement, plutôt que d'une formule fixe d'année bissextile."
Loading
Loading