After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 624959 - initial support for calendar system other than gregorian
initial support for calendar system other than gregorian
Product: gnome-shell
Classification: Core
Component: calendar
Other Linux
: Normal normal
: ---
Assigned To: gnome-shell-maint
Depends on:
Reported: 2010-07-21 18:33 UTC by everplays
Modified: 2021-07-05 14:36 UTC
See Also:
GNOME target: ---
GNOME version: ---

main patch (format-patch) (27.47 KB, patch)
2010-07-21 18:35 UTC, everplays
needs-work Details | Review (686 bytes, patch)
2010-07-21 18:36 UTC, everplays
reviewed Details | Review
applied owen's comments (34.17 KB, patch)
2011-01-30 08:43 UTC, everplays
needs-work Details | Review

Description everplays 2010-07-21 18:33:56 UTC
this patch adds Jalali, Hebrew & Hijri to gnome-shell's calendar.

hebrew & hijri are based on (public domain)
Jalali is based on (GPL)

** also i should mention that it's not quite ready, for example label of Hebrew months needs to be updated.
Comment 1 everplays 2010-07-21 18:35:36 UTC
Created attachment 166318 [details] [review]
main patch (format-patch)
Comment 2 everplays 2010-07-21 18:36:09 UTC
Created attachment 166319 [details] [review]
Comment 3 André Klapper 2010-08-02 23:12:43 UTC
Also see bug 344005.
Comment 4 Owen Taylor 2010-08-19 21:42:28 UTC
Review of attachment 166318 [details] [review]:

In general this looks very reasonable. I obviously haven't checked the calendar system math. Do have some suggestions about coding style and structure here.

General style issues:

 * Code should have 4 space idents. If tabs characters are used, your editor must be set to 8-space tabs. (It appears that the code might have been created with a 4-space ta width.)
 * Operators (==, +, etc.) should have spaces around them
 * The calendar source files need to credit the sources you adapted from them. (This is not a legal requirement for public domain code, in the US. It is a legal requirement for GPL code. And it's the polite thing to do in any case.)

::: js/misc/calsys/gregorian.js
@@ +4,3 @@
+// & controls it's behaviour
+function controller(){

* Missing space between () and {

* constructors for objects should be named with an upper case initial letter
But looking at this, I think it would be be better to get rid of the controller() object and make the module itself the "object". So just have getDate(), setDate(), etc, functions directly in the module namespace. I don't think the stateless "controller" object adds anything.

So in calendar.js you'd replace

 this.controller = new CalSystems[this._calSys].controller();

With this:

 this._calendarSystem = CalendarSystems[calendarSystem];

@@ +10,3 @@
+controller.prototype = {
+	/**
+	 * sets date based on passed date object

sets "day of month"

::: js/misc/calsys/hebrew.js
@@ +223,3 @@
+		let h = dateToHebrew(d);
+		h[2] = 1;
+		// next year occures on 6th month (why?)

'occurs' (and again below)

@@ +225,3 @@
+		// next year occures on 6th month (why?)
+		if(h[1]==6){
+			++h[0]; // increase year

Use post-increment when it doesn't matter (and when it does matter, you probably should break the statement up)

@@ +276,3 @@
+	 */
+	getMonth : function(d){
+		return --dateToHebrew(d)[1];

Only use '--' when you want to modify a value. Here write '- 1'. (the above wouldn't even be legal in C!)

::: js/misc/calsys/hijri.js
@@ +175,3 @@
+	 */
+	getMonth : function(d){
+		return --dateToIslamic(d)[1];

Same comment

::: js/misc/calsys/jalali.js
@@ +247,3 @@
+		let gy = d.getFullYear();
+		let j = JalaliDate.gregorianToJalali(gy, gm+1, gd);
+		return format.replace(/%B/g, JalaliDate.j_month_names[j[1]-1]).replace(/%Y/g, this._english2persian(''+j[0]));

If you are going to chain like this, it's better to beak lines to show the structure

 return format.replace(/%B/g, JalaliDate.j_month_names[j[1]-1])
              .replace(/%Y/g, this._english2persian(''+j[0]));

With the '.replace' lined up

::: js/ui/calendar.js
@@ +8,3 @@
 const Shell =;
 const Gettext_gtk20 = imports.gettext.domain('gtk20');
+const CalSystems = [

You have CalSstems here, and CalSys and CALENDAR_SYSTEM_KEY. Rather than have inconsistent abbreviations, it's better to just always put the full thing.

@@ +67,3 @@
+        this._calSys = 0;
+        try {
+			this._calSys = this._settings.get_int(CALENDAR_SYSTEM_KEY);

- You have get_int() here and get_integer() below.

- It would be better to identify calendar systems by strings rather than by arbitrary integers indices into an array.)

@@ +71,3 @@
+			this._settings.set_int(CALENDAR_SYSTEM_KEY, 0);
+		}
+		this.controller = new CalSystems[this._calSys].controller();

- Like other private fields, this should be _controller.
- I think this object is the "calendar system", and the _calSys field you have maybe shouldn't even be stored in the object at all. Controller is a very generic and unclear name to me.
Comment 5 Owen Taylor 2010-08-19 21:48:32 UTC
Review of attachment 166319 [details] [review]:

No issues. Obviously shouldn't be separate in a final patch.
Comment 6 everplays 2011-01-30 08:43:39 UTC
Created attachment 179624 [details] [review]
applied owen's comments

now it uses string instead of integer for setting.

i've tied to respect coding style of GJS but there maybe some mistakes :)
Comment 7 everplays 2011-01-30 13:30:43 UTC
i should add 2 comments:

const Shell =;
const Gettext_gtk20 = imports.gettext.domain('gtk20');

is not necessary & none of them has been used in code

2. we don't need try/catch block. because in any case that fetching setting fails (for example setting doesn't exist) GIO won't throw error or at least it's not catchable in JS
Comment 8 Nguyen Thai Ngoc Duy 2011-02-20 14:52:34 UTC
I would like to add a switch to change calendar at runtime (if I read the patch correctly, calendar system is autodetected).

We Vietnamese use Western calendar most of the time of the year. But when our lunar new year comes, we turn to lunar calendar instead. I suppose Chinese share the same tradition. Japanese also use dual calendar system if I remember correctly.

Another way of displaying, used by paper calendars, is show both calendar at the same time. Lunar date is shown as a small number at the bottom right corner. When lunar month changes, show both month and date. We don't have to show every lunar date, just some important ones (customized by locales?). For Vietnamese, they are the first, 15th and the last day of each month, and first three days of January.
Comment 9 André Klapper 2012-01-12 15:14:40 UTC
Owen: Can the patch in comment 6 get a review, please?
Comment 10 Arash Mousavi 2012-03-16 13:29:19 UTC
Is this feature going to be added on gnome 3.4? This is a cool feature for gnome-shell, while there's no built-in support for these calendars on Glib.
Comment 11 André Klapper 2012-03-16 13:36:23 UTC
No, as we are past feature freeze. Maybe this get some reviews for 3.5.x but I highly recommend to ping again as people tend to forget...
Comment 12 Jasper St. Pierre (not reading bugmail) 2012-03-16 22:07:19 UTC
Review of attachment 179624 [details] [review]:

I only reviewed Hebrew and Gregorian, but most of my comments apply to both. I don't understand the complex date code, so I didn't review it, but there's lots of formatting/code style issues.

I'm not sure I like the module-based API, though. It's an interesting idea, but I think I'm more comfortable with a class-based duck-typing API.

I will also say that the "Date" type in JS is just a wrapper around a timestamp that provides a basic Gregorian-style calendaring API based around that timestamp, which is a notoriously bad API for calendering. It probably makes sense not to use the JS Date object. There is a current Harmony Strawman to introduce a "globalization API", making note of date/time formatting and other things, and it looks like it has a calendaring API going forward:

An implementation of DateTimeFormat might include the language tag "th" in its [[availableLocales]]
internal property, and must (according to 13.2.3) include the key "ca" in its [[relevantExtensionKeys]] internal property. For
Thai, the "buddhist" calendar is usually the default, but an implementation might also support the calendars "gregory",
"chinese", and "islamicc" for the locale "th". The [[localeData]] internal property would therefore at least include {"th": {ca:
["buddhist", "gregory", "chinese", "islamicc"]}}.


::: data/
@@ +63,3 @@
+      <default>'gregorian'</default>
+      <summary>calendar system of calendar widget</summary>
+      <description>can be gregorian, jalali, hebrew, hijri</description>

That's not how you do an enum.

::: js/
@@ +11,3 @@
 	misc/telepathy.js	\
 	misc/util.js		\
+	misc/CalendarSystems/gregorian.js \

No. "calendarSystems" if anything.

::: js/misc/CalendarSystems/gregorian.js
@@ +15,3 @@
+ * 
+ * @author behrooz shabani <>
+ * @copyright 2010-2011 behrooz shabani

We do not add GPL headers.

::: js/misc/CalendarSystems/hebrew.js
@@ +15,3 @@
+ * 
+ * @author behrooz shabani <>
+ * @copyright 2010-2011 behrooz shabani

We do not add GPL headers.

@@ +18,3 @@
+ */
+// based on

// Based on Fourmilab JavaScript Converter by John Walker:

@@ +20,3 @@
+// based on
+let HEBREW_EPOCH = 347995.5;


@@ +21,3 @@
+let HEBREW_EPOCH = 347995.5;
+let hebrew_month_names = [


@@ +37,3 @@
+function hebrew_leap(year) {

We use camelCase, so hebrewLeap.

@@ +47,3 @@
+ * converts an integer to letter form of it
+ */

Remove the useless docstrings.

@@ +51,3 @@
+    let length = 0;
+    let h_number = "" ;
+    let digits = [

const HEBREW_DIGITS, and put at the top of the module.

@@ +53,3 @@
+    let digits = [
+        " \u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8",
+        "\u05d8\u05d9\u05db\u05dc\u05de\u05e0\u05e1\u05e2\u05e4\u05e6",

Is the lack of space here intentional?

@@ +58,3 @@
+    /* sanity checks */
+    if (n < 1 || n > 10000)

No sanity checks.

@@ +219,3 @@
+                               (leap_gregorian(year) ? -1 : -2)
+           ) +
+           day);

This is a mess.

@@ +263,3 @@
+    let jd = hebrew_to_jd(year, month, day);
+    let gd = jd_to_gregorian(jd);
+    return new Date(gd[0], gd[1] - 1, gd[2], 0, 0, 0);

Please use destructuring assignment.

::: js/misc/CalendarSystems/jalali.js
@@ +18,3 @@
+ */
+// based on 

This is GPLv3. We cannot import GPLv3 into the Shell.

@@ +24,3 @@
+let JalaliDate = {};
+JalaliDate = {

Don't do this. Just define everything in module scope.

::: js/ui/calendar.js
@@ +71,3 @@
+            _calendarSystem = this._settings.get_string(CALENDAR_SYSTEM_KEY);
+        } catch(e) {
+            this._settings.set_string(CALENDAR_SYSTEM_KEY, _calendarSystem);

get_string should never throw an error.

@@ +74,3 @@
+        }
+        if ( !CalendarSystems[_calendarSystem] )
+            _calendarSystem = 'gregorian' ;

If you use a gsettings enum properly, this should never happen.

@@ +75,3 @@
+        if ( !CalendarSystems[_calendarSystem] )
+            _calendarSystem = 'gregorian' ;
+        this._calendarSystem = CalendarSystems[_calendarSystem] ;

No space after semi.

@@ +76,3 @@
+            _calendarSystem = 'gregorian' ;
+        this._calendarSystem = CalendarSystems[_calendarSystem] ;
+        this._settings.connect('changed::'+CALENDAR_SYSTEM_KEY, Lang.bind(this, this._calendarSystemChanged));


@@ +119,3 @@
+    // trigger for changing calendar system

Useless docstring.

@@ +123,3 @@
+        let _calendarSystem = this._settings.get_string(CALENDAR_SYSTEM_KEY);
+        if(CalendarSystems[_calendarSystem]){
+            this._calendarSystem = CalendarSystems[_calendarSystem] ;

Don't you need to update the UI or something here?

And just call this on first init instead of having the same logic in two places.
Comment 13 Mathieu Bridon 2015-12-22 16:56:03 UTC
(In reply to Nguyen Thai Ngoc Duy from comment #8)
> I would like to add a switch to change calendar at runtime (if I read the
> patch correctly, calendar system is autodetected).
> We Vietnamese use Western calendar most of the time of the year. But when
> our lunar new year comes, we turn to lunar calendar instead. I suppose
> Chinese share the same tradition.

I can't speak for all Chinese people, but I can hopefully describe how (some? most?) Chinese people in Hong Kong use these things.

Hong Kong people will look at both calendars all year long, depending on what they are looking for.

There, the Western calendar is the default for business, school, official matters, i.e almost everything. It should be the default, and probably should always be displayed.

However, for traditional things (like Chinese New Year which you mention), people will often look at the Lunar calendar.

People won't simply switch to the Lunar calendar temporarily as you describe though, they'll want to see either, or both at the same time.

Another example is birthdays. Some (generally older) people only known their birthday in the Lunar calendar. Their relative will want to look at the Lunar calendar to find what day (in the Western calendar) their birthday is this year.

So that's more of a « conversion » use case, which requires seeing both calendars at the same time.

> Another way of displaying, used by paper calendars, is show both calendar at
> the same time. Lunar date is shown as a small number at the bottom right
> corner. When lunar month changes, show both month and date.

This is what some other systems/applications do, and would be very useful, at least to Hong Kong Chinese people.
Comment 14 GNOME Infrastructure Team 2021-07-05 14:36:22 UTC
GNOME is going to shut down in favor of
As part of that, we are mass-closing older open tickets in
which have not seen updates for a longer time (resources are unfortunately
quite limited so not every ticket can get handled).

If you can still reproduce the situation described in this ticket in a recent
and supported software version, then please follow
and create a new ticket at

Thank you for your understanding and your help.