From aa6892b05d73b5c0879635831a81611cefe354db Mon Sep 17 00:00:00 2001 From: Prabin Dahal Date: Fri, 22 Nov 2024 11:32:52 +0100 Subject: [PATCH] Initial commit --- calendar.js | 325 +++++++++++++++++++++++++++++++++++++++++++++++++ extension.js | 76 ++++++++++++ metadata.json | 10 ++ stylesheet.css | 3 + 4 files changed, 414 insertions(+) create mode 100644 calendar.js create mode 100644 extension.js create mode 100644 metadata.json create mode 100644 stylesheet.css diff --git a/calendar.js b/calendar.js new file mode 100644 index 0000000..85a5548 --- /dev/null +++ b/calendar.js @@ -0,0 +1,325 @@ +/* calendar.js + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-2.0-or-later + *//* +Converts a Gregorian date to Nepali. +*/ +function toNepali(gy, gm, gd) { + if (Object.prototype.toString.call(gy) === '[object Date]') { + gd = gy.getDate() + gm = gy.getMonth() + 1 + gy = gy.getFullYear() + } + return d2n(g2d(gy, gm, gd)) +} + +/* + Converts a Nepali date to Gregorian. +*/ +function toGregorian(ny, nm, nd) { + return d2g(n2d(ny, nm, nd)) +} + +/* + Checks whether a Nepali date is valid or not. +*/ +function isValidNepaliDate(ny, nm, nd) { + return ny >= 2000 && ny <= 2099 && + nm >= 1 && nm <= 12 && + nd >= 1 && nd <= nepaliMonthLength(ny, nm) +} + +/* + Is this a leap year or not? +*/ +function isLeapNepaliYear(ny) { + return (nepaliCalendarData.leapYears.indexOf(ny) != -1); +} + +/* + Number of days in a given month in a Nepali year. +*/ +function nepaliMonthLength(ny, nm) { + return nepaliCalendarData[ny][nm - 1]; +} + +/* + Converts a date of the Nepali calendar to the Julian Day number. + + @param ny Nepali year (1 to 3100) + @param nm Nepali month (1 to 12) + @param nd Nepali day (1 to 29/31) + @return Julian Day number +*/ +function n2d(ny, nm, nd) { + i = ly = nepaliCalendarData.startYear; + d = nepaliCalendarData.startJulianDay - 1; + ly = nepaliCalendarData.leapYears[0]; + for (j = 1; j < nepaliCalendarData.leapYears.length; j++) { + if (ly > ny) break; + d += (ly - i) * 365; + d += 366; + i = ly + 1; + ly = nepaliCalendarData.leapYears[j] + } + if (ny - i > 1) d += (ny - i) * 365; + for (i = 1; i < nm; i++) { + d += nepaliCalendarData[ny][i - 1]; + } + d += nd; + return d; +} +/* + Converts the Julian Day number to a date in the Nepali calendar. + + @param jdn Julian Day number + @return + ny: Nepali year (1 to 3100) + nm: Nepali month (1 to 12) + nd: Nepali day (1 to 29/32) +*/ +function d2n(jdn) { + jdn = jdn - nepaliCalendarData.startJulianDay - 1 + 2; + ny = ly = nepaliCalendarData.startYear; + d = td = jdn; + try { + for (i = 0; i < nepaliCalendarData.leapYears.length; i++) { + td -= (nepaliCalendarData.leapYears[i] - ny) * 365; + td -= 366; + if (td < 0) break; + d = td; + ny = nepaliCalendarData.leapYears[i] + 1; + } + while (d > 365) { + d -= 365; + ny++; + } + for (nm = 1; nm < 12; nm++) { + if (d > nepaliCalendarData[ny][nm - 1]) + d -= nepaliCalendarData[ny][nm - 1]; + else + break; + } + nd = d; + + return { + ny: ny + , nm: nm + , nd: nd + } + } + catch (exception) { + return null; + } +} +/* + Calculates the Julian Day number from Gregorian or Julian + calendar dates. This integer number corresponds to the noon of + the date (i.e. 12 hours of Universal Time). + The procedure was tested to be good since 1 March, -100100 (of both + calendars) up to a few million years into the future. + + @param gy Calendar year (years BC numbered 0, -1, -2, ...) + @param gm Calendar month (1 to 12) + @param gd Calendar day of the month (1 to 28/29/30/31) + @return Julian Day number +*/ +function g2d(gy, gm, gd) { + var d = div((gy + div(gm - 8, 6) + 100100) * 1461, 4) + + div(153 * mod(gm + 9, 12) + 2, 5) + + gd - 34840408 + d = d - div(div(gy + 100100 + div(gm - 8, 6), 100) * 3, 4) + 752 + return d; +} + +/* + Calculates Gregorian and Julian calendar dates from the Julian Day number + (jdn) for the period since jdn=-34839655 (i.e. the year -100100 of both + calendars) to some millions years ahead of the present. + + @param jdn Julian Day number + @return + gy: Calendar year (years BC numbered 0, -1, -2, ...) + gm: Calendar month (1 to 12) + gd: Calendar day of the month M (1 to 28/29/30/31) +*/ +function d2g(jdn) { + var j + , i + , gd + , gm + , gy + j = 4 * jdn + 139361631 + j = j + div(div(4 * jdn + 183187720, 146097) * 3, 4) * 4 - 3908 + i = div(mod(j, 1461), 4) * 5 + 308 + gd = div(mod(i, 153), 5) + 1 + gm = mod(div(i, 153), 12) + 1 + gy = div(j, 1461) - 100100 + div(8 - gm, 6) + return { + gy: gy + , gm: gm + , gd: gd + } +} + +/* + Utility helper functions. +*/ + +function div(a, b) { + return ~~(a / b) +} + +function mod(a, b) { + return a - ~~(a / b) * b +} + +/* + Nepali Calendar Data +*/ +var nepaliCalendarData = { + "2000": [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31], + "2001": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2002": [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30], + "2003": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2004": [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31], + "2005": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2006": [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30], + "2007": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2008": [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31], + "2009": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2010": [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30], + "2011": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2012": [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30], + "2013": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2014": [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30], + "2015": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2016": [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30], + "2017": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2018": [31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30], + "2019": [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31], + "2020": [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30], + "2021": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2022": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30], + "2023": [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31], + "2024": [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30], + "2025": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2026": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2027": [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31], + "2028": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2029": [31, 31, 32, 31, 32, 30, 30, 29, 30, 29, 30, 30], + "2030": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2031": [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31], + "2032": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2033": [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30], + "2034": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2035": [30, 32, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31], + "2036": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2037": [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30], + "2038": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2039": [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30], + "2040": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2041": [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30], + "2042": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2043": [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30], + "2044": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2045": [31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30], + "2046": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2047": [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30], + "2048": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2049": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30], + "2050": [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31], + "2051": [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30], + "2052": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2053": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30], + "2054": [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31], + "2055": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2056": [31, 31, 32, 31, 32, 30, 30, 29, 30, 29, 30, 30], + "2057": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2058": [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31], + "2059": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2060": [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30], + "2061": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2062": [30, 32, 31, 32, 31, 31, 29, 30, 29, 30, 29, 31], + "2063": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2064": [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30], + "2065": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2066": [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31], + "2067": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2068": [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30], + "2069": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2070": [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30], + "2071": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2072": [31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30], + "2073": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31], + "2074": [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30], + "2075": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2076": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30], + "2077": [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31], + "2078": [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30], + "2079": [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30], + "2080": [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30], + "2081": [31, 31, 32, 32, 31, 30, 30, 30, 29, 30, 30, 30], + "2082": [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30], + "2083": [31, 31, 32, 31, 31, 30, 30, 30, 29, 30, 30, 30], + "2084": [31, 31, 32, 31, 31, 30, 30, 30, 29, 30, 30, 30], + "2085": [31, 32, 31, 32, 30, 31, 30, 30, 29, 30, 30, 30], + "2086": [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30], + "2087": [31, 31, 32, 31, 31, 31, 30, 30, 29, 30, 30, 30], + "2088": [30, 31, 32, 32, 30, 31, 30, 30, 29, 30, 30, 30], + "2089": [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30], + "2090": [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30], + "leapYears": [2003, 2007, 2011, 2015, 2019, 2023, 2026, 2030, 2034, 2038, 2042, 2046, 2050, 2054, 2057, 2061, 2065, 2069, 2073, 2077, 2081, 2085, 2087], + "startYear": 2000, + "endYear": 2090, + "startJulianDay": 2430829 +} + +function convertNumbers(string) { + const chars = { + '0': '०', + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + } + + return string.replace(/[0-9]/g, m => chars[m]); +} + +function convertMonths(string) { + const chars = { + '1': 'बैशाख', + '2': 'जेष्ठ', + '3': 'आषाढ', + '4': 'श्रावण', + '5': 'भाद्र', + '6': 'आश्विन', + '7': 'कार्तिक', + '8': 'मंसिर', + '9': 'पौष', + '10': 'माघ', + '11': 'फाल्गुन', + '12': 'चैत्र', + } + + return string.replace(/[0-9]/g, m => chars[m]); +} diff --git a/extension.js b/extension.js new file mode 100644 index 0000000..b2492f0 --- /dev/null +++ b/extension.js @@ -0,0 +1,76 @@ +/* extension.js + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +/* exported init */ + +const GETTEXT_DOMAIN = 'nepalidate'; + +const { Clutter, GObject, St } = imports.gi; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const Calendar = Me.imports.calendar; +const Main = imports.ui.main; +const PanelMenu = imports.ui.panelMenu; +const PopupMenu = imports.ui.popupMenu; + +const _ = ExtensionUtils.gettext; + +const Indicator = GObject.registerClass( + class Indicator extends PanelMenu.Button { + _init() { + super._init(0.0, _('Nepali Date')); + + var nepaliDate = Calendar.toNepali(new Date()); + console.log(nepaliDate); + + var label = new St.Label({ + style_class: 'nepalidate-label', + y_align: Clutter.ActorAlign.CENTER + }); + label.text = ( + Calendar.convertMonths(nepaliDate.nm.toString()) + " " + + Calendar.convertNumbers(nepaliDate.nd.toString()) + ", " + + Calendar.convertNumbers(nepaliDate.ny.toString()) + ); + + this.add_child(label); + } + }); + +class Extension { + constructor(uuid) { + this._uuid = uuid; + + ExtensionUtils.initTranslations(GETTEXT_DOMAIN); + } + + enable() { + this._indicator = new Indicator(); + Main.panel.addToStatusArea(this._uuid, this._indicator); + } + + disable() { + this._indicator.destroy(); + this._indicator = null; + } +} + +function init(meta) { + return new Extension(meta.uuid); +} diff --git a/metadata.json b/metadata.json new file mode 100644 index 0000000..8f1711a --- /dev/null +++ b/metadata.json @@ -0,0 +1,10 @@ +{ + "uuid": "nepalidate@prabin-dahal.com.np", + "name": "Nepali Date", + "description": "Show Bikram Sambat on the top panel", + "version": 1, + "shell-version": [ + "43" + ], + "url": "https://projects.prabin-dahal.com.np/pdahal/nepalidate" +} \ No newline at end of file diff --git a/stylesheet.css b/stylesheet.css new file mode 100644 index 0000000..b8d99c5 --- /dev/null +++ b/stylesheet.css @@ -0,0 +1,3 @@ +/* Add your custom extension styling here */ +.nepalidate-label { +} \ No newline at end of file