[Development] Calendar Systems proposal

Edward Welbourne edward.welbourne at qt.io
Wed Feb 8 16:42:47 CET 2017


Soroush Rabiei (30 January 2017 11:04) wrote:
> Speaking of the API, I wish to share an idea about not to put calendar
> implementations in a plugin subsystem.

I should clarify: when I spoke of calendar systems in plugins, I wasn't
suggesting we should do that as the normal mode for commonly-used
calendars.  I prefer an instance-based system (over an enum-based one)
because it allows third parties to define a mechanism to support
calendar customisation, which might for example use a plugin.  However,
the usual way of using the API would indeed be to instantiate a calendar
system provided either by Qt or by the application built on Qt.

> There are differences between those concepts that are implemented as
> plugins and calendars. A calendar system is not an image format nor a
> database implementation.

It is, however, something that each user typically only wants one or a
few of, despite there being many more for which they have no use.  That,
to me, is the decisive place where a plugin architecture is a win; spare
users the bloat of the ones they don't need, while supporting those most
users do need and making it easy to have others as needed.

> There will be no new calendar (at least, it's unlikely to have a brand
> new calendar) and there will be no newer versions of existing
> calendars. What is the point of having calendars as plugins?

There are, however, existing calendars with more variations than we
shall be happy to support: for example, the Islamic calendar, when
implemented strictly by astronomic observation, has a different variant
for each location, albeit with only minor variations.  We can *allow*
for those who want (for whatever reason) to follow this for their
location, without having to actually support them ourselves.  They can
subclass our Islamic calendar class (which shall provide the relevant
locale-specific details and generic structure), apply their tweaks and
have the calendar they want.

This does also mean that we can initially support a small sub-set of
calendar systems and wait for contributors to supply the rest, rather
than feeling obliged to implement a dozen or more different calendar
systems ourselves at the outset - for each of which we'd need to do
significant research (and we'd probably get some of them wrong).

> And we have to keep QGregorianCalendar everywhere after
> all... And we will have the problem of instantiation. While plugins
> have no public header, then how we are supposed to use them in code?
> Like this:
> 
>     QDate d;
>     d.setDate(y,m,d,QCalendar::fromName("jalali"));
> 
> Or maybe:
> 
>     d.setDate(y,m,d,"jalali");
>
> Let's add all calendar systems that do have locale information in
> CLDR,

That's probably more work than we want to do - how familiar are you with
the algorithms for computation of the different calendar systems ?  I'm
sure we can look each up on Wikipedia - and *most* of them shall have
sufficiently well-established algorithms for mapping to and from Julian
day number that we can implement them; but, even so, it's going to take
a pile of work to do that; and lack of someone familiar with a calendar
is apt to leave us innocently making embarrassing mistakes.  Better to
make it easy for others to contribute the ones they care about, while
we implement the ones we know.

> and make all of them configurable as to be built or not, except
> QGregorianCalendar. Then decide on a default subset of calendars to be
> compiled into qtbase. That will be something like:
> 
> +----+-----------------+--------------------+------------+--------+
> |No. |Name             |Variant             |Configurable|Default |
> +----+-----------------+--------------------+------------+--------+
> |1   |Gregorian        |                    |No          |Yes     |
> +----+-----------------+--------------------+------------+--------+
> |2   |Islamic          |Astronomical        |Yes         |No      |
> +----+-----------------+--------------------+------------+--------+
> |3   |Islamic          |Civil (Algorithmic) |Yes         |Yes     |
> +----+-----------------+--------------------+------------+--------+
> |4   |Persian          |                    |Yes         |Yes     |
> +----+-----------------+--------------------+------------+--------+
> |5   |Hebrew           |                    |Yes         |Yes     |
> +----+-----------------+--------------------+------------+--------+
> |6   |Chinese          |                    |Yes         |Yes     |
> +----+-----------------+--------------------+------------+--------+
> |7   |Japanese         |                    |Yes         |No      |
> +----+-----------------+--------------------+------------+--------+
> |8   |Buddhist         |                    |Yes         |No      |
> +----+-----------------+--------------------+------------+--------+
> |9   |Republic of China|                    |Yes         |No      |
> +----+-----------------+--------------------+------------+--------+
> |10  |Coptic           |                    |Yes         |No      |
> +----+-----------------+--------------------+------------+--------+
> |11  |Ethiopic         |Amete Alem          |Yes         |No      |
> +----+-----------------+--------------------+------------+--------+
> |12  |Ethiopic         |Amete Mihret        |Yes         |No      |
> +----+-----------------+--------------------+------------+--------+
> |13  |Indian           |                    |Yes         |No      |
> +----+-----------------+--------------------+------------+--------+

For reference, the Mozilla documentation Robin helpfully linked lists
these fourteen calendars:

  "buddhist", "chinese", "coptic", "ethioaa", "ethiopic", "gregory",
  "hebrew", "indian", "islamic", "islamicc", "iso8601", "japanese",
  "persian", "roc".

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString

Once you've got five added, it's within a factor of three more to get
all of those listed; if adding five is affordable, adding all probably
is, too.  I'd be inclined to make Gregorian-only the default, but we
should definitely make it easy to select, at configure-time, any subset
of those available, including "all".  As Gregorian is needed for basic
QDate, it's not optional or configurable.

> For historical calendars, Qt users are unlikely to add marginal
> calendar systems -> A reason to avoid plugin system. Though having
> current schema, they can subclass QAbstractCalendar and add their
> calendar (not as a loadable plugin) in their own code.

The thing about "unlikely" is that *each* user being unlikely to need a
marginal calendar doesn't get us away from there being many users, hence
*some* who do that unlikely thing - or who *wish they could* but, since
none of the software at their disposal lets them, suffer without.
Historians, for example, may find it very useful to be able to view a
calendar that faithfully represents what the era and folk they study
used; there shall be few such users of each obsolete calendar, to be
sure, but the thing about long tails is that, when you sum up the tiny
group-sizes of many small constituencies with eccentric needs, you may
be surprised by how many they come to in total.

The other issue with a long tail is making the call about where to make
the cut - do we really want to include all three Ethiopian calendars
(Coptic being also from Ethiopia) when we probably don't have large
numbers of Ethiopian users ?  I note that you leave out the Julian
calendar: yet Eastern Orthodox Christians still use it - shouldn't we
include it ?  If we support a few while making it easy for applications
to support more, and easy for users to contribute ones we lack, we don't
impose our culturally-biased decisions about "who matters more" on our
users.  We just support the calendars for which we have active
contributors willing to serve as maintainers, while leaving the door
open to the rest.

So, to reiterate: we don't need to invent a plugin architecture; we just
need to use an instance-based model - then a third party who *wants to*
has the option of (defining their own plugin API and) accepting plugins;
while applications that want to build in a calendar we don't support can
do so; and *we* only need to support as many as we actually have a
maintainer familiar with.

	Eddy.



More information about the Development mailing list