globalize icon indicating copy to clipboard operation
globalize copied to clipboard

Support for non-gregorian calendars

Open rxaviers opened this issue 11 years ago • 50 comments

WIP PR #447


CLDR has data for a variety of different calendars (listed in the table below). Globalize 0.x supported some non-gregorian calendars. But, Globalize 1.x hasn't migrated them yet (it supports the gregorian calendar only).

Calendar Globalize 0.x Globalize 1.x ibm-js/ecma402 dojo
buddhist (Thai Buddhist calendar) x x x
chinese (Traditional Chinese calendar)
coptic (Coptic calendar)
dangi (Traditional Korean calendar)
ethioaa (Ethiopic calendar, Amete Alem (epoch approx. 5493 B.C.E))
ethiopic (Ethiopic calendar, Amete Mihret (epoch approx, 8 C.E.))
gregory (Gregorian calendar) x x x x
hebrew (Traditional Hebrew calendar) x x
indian (Indian calendar)
islamic (Islamic calendar) x x x
islamic-umalqura (Islamic calendar, Umm al-Qura) x x x
islamic-tbla (Islamic calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - astronomical epoch))
islamic-civil (Islamic calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - civil epoch)) x
islamic-rgsa (Islamic calendar, Saudi Arabia sighting)
iso8601 (ISO calendar (Gregorian calendar using the ISO 8601 calendar week rules))
japanese (Japanese Imperial calendar) x
persian (Persian calendar) x
roc (Republic of China calendar) x
islamicc (Civil (algorithmic) Arabic calendar)

We haven't been requested so far to support any non-gregorian calendar. Therefore, our priority is (1) first to support the previously supported calendars on 0.x, (2) then to support any other non-gregorian calendar.

References:

Unicode Technical Standard 35 describes three locale extension keys that are relevant to date and time formatting, "ca" for calendar, "tz" for time zone, and implicitly "nu" for the numbering system of the number format used for numbers within the date format. DateTimeFormat, however, requires that the time zone is specified through the timeZone property in the options objects.

Follow the calendar preference per territory: (use 001 as a default for countries not listed there)

"calendarPreferenceData": {
  "001": "gregorian",
  "AE": "gregorian islamic-umalqura islamic islamic-civil islamic-tbla",
  "AF": "persian gregorian islamic islamic-civil islamic-tbla",
  "BH": "gregorian islamic-umalqura islamic islamic-civil islamic-tbla",
  "CN": "gregorian chinese",
  "CX": "gregorian chinese",
  "DJ": "gregorian islamic islamic-civil islamic-tbla",
  "DZ": "gregorian islamic islamic-civil islamic-tbla",
  "EG": "gregorian coptic islamic islamic-civil islamic-tbla",
  "EH": "gregorian islamic islamic-civil islamic-tbla",
  "ER": "gregorian islamic islamic-civil islamic-tbla",
  "ET": "gregorian ethiopic",
  "HK": "gregorian chinese",
  "IL": "gregorian hebrew islamic islamic-civil islamic-tbla",
  "IN": "gregorian indian",
  "IQ": "gregorian islamic islamic-civil islamic-tbla",
  "IR": "persian gregorian islamic islamic-civil islamic-tbla",
  "JO": "gregorian islamic islamic-civil islamic-tbla",
  "JP": "gregorian japanese",
  "KM": "gregorian islamic islamic-civil islamic-tbla",
  "KR": "gregorian dangi",
  "KW": "gregorian islamic-umalqura islamic islamic-civil islamic-tbla",
  "LB": "gregorian islamic islamic-civil islamic-tbla",
  "LY": "gregorian islamic islamic-civil islamic-tbla",
  "MA": "gregorian islamic islamic-civil islamic-tbla",
  "MO": "gregorian chinese",
  "MR": "gregorian islamic islamic-civil islamic-tbla",
  "OM": "gregorian islamic islamic-civil islamic-tbla",
  "PS": "gregorian islamic islamic-civil islamic-tbla",
  "QA": "gregorian islamic-umalqura islamic islamic-civil islamic-tbla",
  "SA": "gregorian islamic-umalqura islamic islamic-rgsa",
  "SD": "gregorian islamic islamic-civil islamic-tbla",
  "SG": "gregorian chinese",
  "SY": "gregorian islamic islamic-civil islamic-tbla",
  "TD": "gregorian islamic islamic-civil islamic-tbla",
  "TH": "buddhist gregorian",
  "TN": "gregorian islamic islamic-civil islamic-tbla",
  "TW": "gregorian roc chinese",
  "YE": "gregorian islamic islamic-civil islamic-tbla"
}

Tests

  • Eras #87

rxaviers avatar Sep 29 '14 11:09 rxaviers

See also the non-gregorian label (applied here as well) for related issues.

jzaefferer avatar Dec 12 '14 12:12 jzaefferer

Hi!

I was just going through the ideas page of jQuery for GSoC and found this issue quite interesting and would like to work on it. The cross mentioned above means they have been completed ,right? Please provide more information regarding what all will we be developing and how I can start contributing. :)

manrajgrover avatar Mar 04 '15 15:03 manrajgrover

was just going through the ideas page of jQuery for GSoC and found ur project quite interesting and would like to work on it.The idea is good and i would like to work on it.

khansrk avatar Mar 04 '15 15:03 khansrk

Hi @ManrajGrover and @srk12345. For the GSoC application, please make sure you read https://github.com/jquery/gsoc/wiki/Getting-started-for-students. Get yourself familiarized with the contributing workflow by fixing simpler issues, e.g., #393. Then, get familiarized with our source code. If you have any questions, don't hesitate to ask, we're available at IRC (see http://irc.jquery.org/).

@ManrajGrover, yes the cross means support (implemented). Note it refers to other projects as well, Globalize 1.x only supports the gregorian calendar.

rxaviers avatar Mar 05 '15 18:03 rxaviers

Hi @rxaviers sir. Great! So first we need to support 0.x calendars on 1.x and then code the rest of the calendars for both versions. I hope I am getting it right. Sir, I went through the #393 but couldn't locate any issue there other than links pointing to other projects and this issue page. Am I missing anything? I would like to work on some small bugs first. Please suggest me some good first bugs.

manrajgrover avatar Mar 05 '15 18:03 manrajgrover

So first we need to support 0.x calendars on 1.x

Correct.

and then code the rest of the calendars for both versions

Partially correct. We should support other calendars on 1.x, not on 0.x (we're not maintaining 0.x anymore).

I went through the #393 but couldn't locate any issue there

I'm going to add comments there.

rxaviers avatar Mar 05 '15 18:03 rxaviers

Okay sir. Following #393. Thank you.

manrajgrover avatar Mar 05 '15 18:03 manrajgrover

after going through the problem i understood that u are not using 0.x anymore and need to support other calendars on 1.x so we have to code rest of the calendars for 1.x

On Fri, Mar 6, 2015 at 12:26 AM, Manraj Singh [email protected] wrote:

Okay sir. Following #393 https://github.com/jquery/globalize/issues/393. Thank you.

— Reply to this email directly or view it on GitHub https://github.com/jquery/globalize/issues/320#issuecomment-77426305.

khansrk avatar Mar 05 '15 19:03 khansrk

working on issue #393

On Fri, Mar 6, 2015 at 1:15 AM, SHAHRUKH KHAN [email protected] wrote:

after going through the problem i understood that u are not using 0.x anymore and need to support other calendars on 1.x so we have to code rest of the calendars for 1.x

On Fri, Mar 6, 2015 at 12:26 AM, Manraj Singh [email protected] wrote:

Okay sir. Following #393 https://github.com/jquery/globalize/issues/393. Thank you.

— Reply to this email directly or view it on GitHub https://github.com/jquery/globalize/issues/320#issuecomment-77426305.

khansrk avatar Mar 05 '15 19:03 khansrk

after going thru ur migration guide i understood that 0.x came with a bundled locale for US english while 1.x uses CLDR. Do we have to parse date in order to migrate

On Fri, Mar 6, 2015 at 1:16 AM, SHAHRUKH KHAN [email protected] wrote:

working on issue #393

On Fri, Mar 6, 2015 at 1:15 AM, SHAHRUKH KHAN < [email protected]> wrote:

after going through the problem i understood that u are not using 0.x anymore and need to support other calendars on 1.x so we have to code rest of the calendars for 1.x

On Fri, Mar 6, 2015 at 12:26 AM, Manraj Singh [email protected] wrote:

Okay sir. Following #393 https://github.com/jquery/globalize/issues/393. Thank you.

— Reply to this email directly or view it on GitHub https://github.com/jquery/globalize/issues/320#issuecomment-77426305.

khansrk avatar Mar 05 '15 19:03 khansrk

@srk12345 please, ping me on IRC for chatting. Your comment has no relation with this issue.

rxaviers avatar Mar 05 '15 20:03 rxaviers

1.x only supports gregorian calendar

On Fri, Mar 6, 2015 at 1:33 AM, Rafael Xavier de Souza < [email protected]> wrote:

@srk12345 https://github.com/srk12345 please, ping me on IRC for chatting. Your comment has no relation with this issue.

— Reply to this email directly or view it on GitHub https://github.com/jquery/globalize/issues/320#issuecomment-77440481.

khansrk avatar Mar 05 '15 20:03 khansrk

I am a Chinese students. After going through ideas page of jQuery for GSoC, I found I'm very interested in this project. I have some experience using some calendar components in my web pages, eg. the calendar.js, and I found that there's no one supporting Traditional Chinese calendar, which is listed in the table. So, I think I can start from scratch by doing some work about Chinese calendar and then turn to others. I hope to get some suggestions on what I should know and how I can get started. Yours sincerely!

MelodyCuida avatar Mar 14 '15 14:03 MelodyCuida

For GSoC, please read the above comments. Also, consider checking out https://github.com/jquery/gsoc/issues/1.

rxaviers avatar Mar 18 '15 20:03 rxaviers

Hi I would like to know where should I submit the proposal??

johnatm avatar Mar 26 '15 04:03 johnatm

@johnatm, please read the above comments.

rxaviers avatar Mar 26 '15 13:03 rxaviers

I am a Nigerian student. I went through the ideas page of jQuery for GSoC, I found them very interested. I possess some few experiences using some calendar components in web pages, I hope to get some suggestions on what I should know and how I can get started. Yours sincerely!

didagu avatar Mar 27 '15 08:03 didagu

I'd like to help get non-Gregorian calendars working. I've skimmed through the source, and it looks like it ought to be straightforward.

CLDR only includes nomenclature, not algorithms, so cldr.js should be fine as is.

Any reason we can't use Keith Wood's calendars ( https://github.com/kbwood/calendars ) for the algorithms? His code is under the jQuery MIT license. I should be able to duck-punch his CDate to look like a native Date, then make sure to use that in date.js.

As long as all the date calculations go through date.js, the rest of globalize should be fine.

I will have to go through it and through datepicker to watch for incorrect assumptions (like fixed names of months, leap year calculations, etc.)

I would not use calendarPreferenceData. Default to gregorian unless otherwise specified.

But the big question is adding a dependency on kbwood/calendars.

Danny

dwachss avatar May 04 '15 16:05 dwachss

@dwachss your help is very welcome.

I assume you're talking about the calendar algebras only and not the widgets themselves. In this case, you would have to extract code excerpts from it, not use it as a dependency (it's a jQuery widget library). Also, this library doesn't seem very active.

I suggest that you evaluate it along with all the other references I put in the description above and come up with an implementation for Globalize.

Feel free to show me the code of what you have in mind by submitting a work in progress PR.

rxaviers avatar May 04 '15 17:05 rxaviers

@rxaviers Yes, I'm talking about the calendar algorithms, not the datepicker widget. Are you saying that I should not use the calendar as a dependency, or the widgets?

When you say "this library doesn't seem very active", are you talking about kbwood/calendars? That isn't necessarily a bad thing, since the underlying math is stable (the algorithms for the Hebrew calendar that form the basis of the code were published by Maimonides in 1180!).

dwachss avatar May 04 '15 17:05 dwachss

When you say "this library doesn't seem very active",

I was referring to kbwood/calendars being year olds updated.

I'll see what I can put together and submit a pull request.

Great. Just let me know if you have any Globalize questions that I can help you with.

rxaviers avatar May 04 '15 17:05 rxaviers

@rxaviers I just updated my comment as you were responding. Sorry.

dwachss avatar May 04 '15 17:05 dwachss

Are you saying that I should not use the calendar as a dependency, or the widgets?

Given the calendar (algebra) is tight coupled with the widget, I'm curious to see how you can depend on it without including the widgets. But, feel free to show me what you have in mind.

About the algorithm stability/quality of kbwood/calendars, you can definitely start with it. But, you'll make me comfortable by also evaluating the other implementations. :)

rxaviers avatar May 04 '15 18:05 rxaviers

I now see what you mean about having to extract the code. Even though kbwood/calendars doesn't inherently use jQuery, it's structured as a jQuery plugin. And Globalize isn't meant to depend on jQuery. So I will have to copy the code.

dwachss avatar May 04 '15 18:05 dwachss

I now see what you mean about having to extract the code. Even though kbwood/calendars doesn't inherently use jQuery, it's structured as a jQuery plugin. And Globalize isn't meant to depend on jQuery. So I will have to copy the code.

Yeap. @kborchers, can we legally import excerpts of an MIT 3rd-party lib?

rxaviers avatar May 04 '15 19:05 rxaviers

can we legally import excerpts of an MIT 3rd-party lib?

yes

scottgonzalez avatar May 04 '15 19:05 scottgonzalez

@scottgonzalez thanks

rxaviers avatar May 04 '15 19:05 rxaviers

Thinking about implementing non-Gregorian calendars:

It's very hard to find anything on the CLDR website. Is there a consistent place to find the specifications about what the data means rather than just its format? The most recent information I can find is from 2012 ( http://cldr.unicode.org/development/development-process/design-proposals/chinese-calendar-support ).

Assumptions

From what I can tell:

A globalized date consists of 4 parts. The time elements are assumed to be identical to Gregorian dates, though the day periods and time formats are members of the dates.calendar object.

  1. era: indexed by number from 0, in chronological order. What to do with a date that does not belong in an era is undefined (a date before the start of the calendar). For Hebrew, Islamic and Japanese calendars at least, there is no "negative" era equivalent to BCE.
  2. year: a non-negative integer. It's not clear that there are any calendars that have a year 0. The years do not necessarily go in order; for example, BCE years go backwards (the year after 10 BCE is 9 BCE). The calendar algorithm has to take care of this.
  3. month: this is the worst part from my point of view. Months are named by strings, not necessarily numbers. For instance, "7-yeartype-leap" for Adar II in the Hebrew calendar. Since we technically can't rely on the order of members of objects, the calendar algorithm has to implement "next month" and "last month", and even "first month of the year".
  4. date: a positive integer. This is assumed to go from 1 continuously to the end of the month.

Days of the week are assumed to be identical to the Gregorian calendar; 7-day weeks, cycling continuously, with no dates that do not have a day of the week (no French Revolutionary calendar or rationalized calendar).

Proposal

New definition for Globalize:

/**
 * [new] Globalize( locale|cldr [, calendar] )
 * @locale [String]
 * @cldr [Cldr instance]
 * @calendar [String]
 *
 * Create a Globalize instance.
 */
function Globalize( locale, calendar ) {
    ...
    this.cldr = alwaysCldr( locale );

    calendar = calendar || "gregorian"; // Or use http://www.unicode.org/reports/tr35/tr35-dates.html#Calendar_Preference_Data
    validateTypeString ( calendar, "calendar" );
    validateType ( calendar, "calendar", calendar in Globalize.calendars, "a defined calendar system" );
    cldr.attributes.calendar = calendar;

    validateLikelySubtags( this.cldr );
}

Where Globalize.calendars is the object that contains the calendar algorithm functions:

Globalize.calendars = {
  gregorian: GregorianDate; // constructor for a generalized "date-like" object to be used in date.js
};

And, in date.js, replace "gregorian" with "{calendar}", as in "dates/calendars/gregorian/months" to be replaced by "dates/calendars/{calendar}/months".

This will allow use of the calendar-specific nomenclature.

date.js will still need to be modified to use the generalized date rather than Date.

dwachss avatar May 06 '15 13:05 dwachss

Proposal: Globalized Date

Immutable representation of a date, localized to a specific calendar system (not a locale).

new Gdate (d);

returns the equivalent Gdate for a given javascript Date. If d cannot be represented (as noted above, some calendars do not have eras that cover all possible dates), the Gdate is marked invalid.

new Gdate (g);

clone an existing Gdate.

new Gdate(era [Number], year [Number], month [String], date [number]);

construct a new Gdate with the given parameters. If any are undefined, use today's date's value. Coerce era, year and date to be in range (e.g., if date is less than 1, set to 1. If greater than the number of days in the month, set to the last day of the month). If month is not a valid month for the year, make a best guess (calendar-defined) or mark the Gdate invalid.

Gdate.prototype.getEra = function(){}

return the era number, or NaN if invalid. Similarly getYear and getDate.

Gdate.prototype.getMonth = function(){}

return the month identifier string, or undefined if invalid.

Gdate.prototype.nextYear = function (n [Number]){}

returns a new Gdate that is n years in the future (or past for negative numbers). n defaults to 1. Similarly nextMonth and nextDate. I don't think nextEra would be meaningful.

Gdate.prototype.toDate = function() {}

returns a javascript Date that corresponds to this Gdate, or new Date(NaN) if invalid.

dwachss avatar May 06 '15 13:05 dwachss

I have a proof-of-concept with the Gregorian calendar of all this working, and I will put together a pull request as soon as I can get grunt to build all this (I'm old-fashioned and am editing the distribution files directly).

dwachss avatar May 06 '15 13:05 dwachss