Support for non-gregorian calendars
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
See also the non-gregorian label (applied here as well) for related issues.
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. :)
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.
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.
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.
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.
Okay sir. Following #393. Thank you.
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.
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.
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.
@srk12345 please, ping me on IRC for chatting. Your comment has no relation with this issue.
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.
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!
For GSoC, please read the above comments. Also, consider checking out https://github.com/jquery/gsoc/issues/1.
Hi I would like to know where should I submit the proposal??
@johnatm, please read the above comments.
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!
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 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 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!).
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 I just updated my comment as you were responding. Sorry.
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. :)
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.
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?
can we legally import excerpts of an MIT 3rd-party lib?
yes
@scottgonzalez thanks
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.
-
era: indexed by number from0, 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. -
year: a non-negative integer. It's not clear that there are any calendars that have a year0. 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. -
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". -
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.
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.
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).