Open rxaviers opened 9 years ago
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 notifications@github.com 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 shahrukhkhan201994@gmail.com 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 notifications@github.com 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 shahrukhkhan201994@gmail.com wrote:
working on issue #393
On Fri, Mar 6, 2015 at 1:15 AM, SHAHRUKH KHAN < shahrukhkhan201994@gmail.com> 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 notifications@github.com 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 < notifications@github.com> 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 ).
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 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.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.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).
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.
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).
Excellent compilation. Thanks for that.
About your assumptions:
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?
UTS#35 Dates has the specification for the Dates data. Although, some of your questions are indeed not answered.
A globalized date consists of 4 parts
Include weekday
in your list. http://www.unicode.org/reports/tr35/tr35-dates.html#Week_Data says nothing about it. But, it changes by changing calendars.
The time elements are assumed to be identical to Gregorian dates
Yes, it's assumed to be the same. At least, there's nothing explicitly mentioned at http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data.
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. 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.
Good question. UTS#35 Dates says nothing about it.
By looking at how ibm-js/ecma402 implements it:
era = 0
as default when an era is not found (see [1] and [2]) (era content at supplemental/calendarData.json
)."__starts": "645-6-19"
(as opposed to "_end": "645-6-19"
--- note that gregorian uses _end
for BC "_end": "0-12-31"
) according to supplemental/calendarData.json
.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".
http://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras says "The yeartype attribute for months is used to distinguish alternate month names that would be displayed for certain calendars during leap years. The practical example of this usage occurs in the Hebrew calendar, where the 7th month "Adar" occurs in non-leap years, with the 6th month being skipped, but in leap years there are two months named "Adar I" and "Adar II". There are currently only two defined year types, standard (the implied default) and leap.".
Does that help answering to your question?
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](
Correct. It's assumed to be 7-day weeks.
Wow, the french revolutionary calendar has 10 days per week. Interesting. I didn't know of. The article says it was used for about 12 years. Does any country/region use this calendar today? I guess not right. I'm pretty sure CLDR doesn't support it.
My suggestion is that we raise the open questions in the cldr mailing list cldr-users@unicode.org. More info at http://unicode.org/consortium/distlist.html
About your proposed API:
function Globalize( locale, calendar ) {
Calendar should be passed in the locale itself. For example, jp-u-ca-japanese
. Please, see http://www.unicode.org/reports/tr35/#Key_Type_Definitions, http://www.unicode.org/repos/cldr/trunk/common/bcp47/calendar.xml. Implementation should be quite trivial, analogous to https://github.com/jquery/globalize/blob/master/src/number/numbering-system.js#L11.
calendar = calendar || "gregorian"; // Or use http://www.unicode.org/reports/tr35/tr35-dates.html#Calendar_Preference_Data
Yes, we could use the locale-passed-calendar ||
Calendar_Preference_Data ||
"gregorian".
For the rest of your proposal I will make comments on your PR.
About your GDate proposal... Although I agree that an enhanced Date (i.e., GDate) that supports other calendars is useful, I think this class should live elsewhere (not in Globalize). Globalize could use it as a dependency if it turns out it's highly needed. Otherwise, I suggest we have Globalize formatting Date
into other-than-gregorian-calendars strings and parsing other-than-gregorian-calendars strings back into Date
. Potentially, developers may prefer using GDate to manipulate dates in their end-application code and using something like Globalize.formatDate(gdate.toDate(), <pattern>)
or gdate = new GDate( Globalize.parseDate(...) )
.
Having said that, feel free to include this class in your PR. We will make a better evaluation later.
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).
If you need help identifying where in src
your dist
changes are, let me know.
@rxaviers:
So calendars always have the format of "u-ca-calendarname"
? That does make it easier.
weekday
will always be the same as date.getDay()
because of the assumption of 7-day cycling weeks. What they are called changes in each calendar.
I'm not going to implement negative years (will parse
handle negative signs?), and just leave out-of-calendar dates as invalid.
The "yeartype"
attribute in the XML becomes part of the month identifier in the JSON data : "7-yeartype-leap"
. So months can't be numbers.
My plan would be to have Globalize.format
and Globalize.parse
only use Date
s. The Gdate
would be used internally, as something for the parser/formatter to store their parts. (So, yes, I agree with you). It would be useful to expose the interface to, say, datepicker, for the concept of "next month" and "last month". I'll leave the question of whether to keep it in Globalize or not for later.
No, no one uses a 10-day week or a calendar with days that aren't part of weeks right now. The latter comes up every few decades, as a way of "rationalizing" the calendar.
I have npm/bower/require/grunt running, and I'm stepping on bugs one at a time. Up to "764 assertions of 836 passed, 72 failed". The next week is going to be rough on me, but I'll get back on this.
So calendars always have the format of
"u-ca-calendarname"
? That does make it easier.
Yeap. u-ca-<calendarname>
should override the region default || "gregorian". Similarly how nu-<numberingSystem>
overrides the numbering sytem (for example, zh-u-nu-native
shown here).
I'm not going to implement negative years (will parse handle negative signs?), and just leave out-of-calendar dates as invalid.
Sounds good to me.
The "yeartype" attribute in the XML becomes part of the month identifier in the JSON data : "7-yeartype-leap". So months can't be numbers.
My plan would be to have Globalize.format and Globalize.parse only use Dates. The Gdate would be used internally, as something for the parser/formatter to store their parts. (So, yes, I agree with you). It would be useful to expose the interface to, say, datepicker, for the concept of "next month" and "last month". I'll leave the question of whether to keep it in Globalize or not for later.
No, no one uses a 10-day week or a calendar with days that aren't part of weeks right now. The latter comes up every few decades, as a way of "rationalizing" the calendar.
Ok
I have npm/bower/require/grunt running, and I'm stepping on bugs one at a time. Up to "764 assertions of 836 passed, 72 failed". The next week is going to be rough on me, but I'll get back on this.
All tests on master
should pass. Just let me know which ones you're hitting (please use gist to paste).
I created a PR for a proof of concept. It passes all the unit tests and almost all the functional tests. It's clearly not perfect; you are right that Gdate should not be part of Globalize itself, but why not part of this project? I will try to create a Hebrew calendar over the next few days to add to what I have so far.
I added Hebrew and Islamic calendars, though I have not written any tests. I just reviewed http://contribute.jquery.org/commits-and-pull-requests/ and changed the PR to be on a branch named 320-nongregorian, rather than on master. I'm getting errors from commitplease about "First line (subject) must indicate the component" but I don't know how to retroactively change commit messages.
I'm getting errors from commitplease about "First line (subject) must indicate the component" but I don't know how to retroactively change commit messages.
I see you have figured it out by now. A suggestion is to use git rebase
and reword them (if you're not doing that already) (more details https://coderwall.com/p/_thg9a/reword-a-git-commit-message and https://help.github.com/articles/using-git-rebase/). Then, you'll have to force push to your branch git push <your-remote> +<your-branch>
(your remote, e.g. origin
; your branch, e.g., 320-nongregorian
.
Yes, that's what I figured out.
Sent from my iPad
On May 11, 2015, at 9:42 AM, Rafael Xavier de Souza notifications@github.com wrote:
I'm getting errors from commitplease about "First line (subject) must indicate the component" but I don't know how to retroactively change commit messages.
I see you have figured it out by now. A suggestion is to use git rebase and reword them (if you're not doing that already) (more details https://coderwall.com/p/_thg9a/reword-a-git-commit-message and https://help.github.com/articles/using-git-rebase/). Then, you'll have to force push to your branch git push
+ (your remote, e.g. origin; your branch, e.g., 320-nongregorian. — Reply to this email directly or view it on GitHub.
Formal API for GDate: https://gist.github.com/dwachss/4f9a6c77c8feb8e2ad09
https://gist.github.com/dwachss/4f9a6c77c8feb8e2ad09
reflects the current state of the API.
We still have not resolved how to expose the GDate API to allow a date picker to get, e.g., the next month. I would simply add a method gdate( Date )
.
I also changed parse.js
to move all the default date values (undefined era, year, month, day) into the GDate constructor, since it needs to define those as well. This eliminates the needs for truncateAt
and all the associated algorithms.
I changed the meaning of an undefined hour, like .dateParser({ skeleton: "m" })( "5" )
, to use midnight local rather than the current hour. There is no documentation on the desired behavior, and there is no real use case (no one says, "meet me at 5 minutes" the way they would say "meet me at 3 PM"). This simplifies the code considerably.
Similarly, an undefined minute with a defined second is at the start of the hour, minute zero.
From my point of view, this is done. I will not be adding more code without further feedback.
Thanks for your help!
Hi Danny, reading your comment is in my TODO. Will reply as soon as I find time. Thanks.
@dwachss Bravo! It's a big implementation. Great work. Let's get that landed.
Final things:
./src/gdate
to ./gdate
. This will force necessary changes as if it was a separate module. Then, (b) I would move ./gdate
into another repo (https://github.com/jquery-support/gdate or on your own user) and fetch that as a version controlled module (via npm or bower). I can create the jquery-support/gdate and give you commit permissions if you prefer this choice. Note Date module should include gregorian support by default.I changed the meaning of an undefined hour, like .dateParser({ skeleton: "m" })( "5" ), to use midnight local rather than the current hour. There is no documentation on the desired behavior, and there is no real use case (no one says, "meet me at 5 minutes" the way they would say "meet me at 3 PM"). This simplifies the code considerably.
The preference obviously depends on the context. Currently, undefined is handled like that: lower precision fields use what's find in now
; higher precision fields are zeroed. This is, if we parse "June", we get a date (current year, "June", 1st day, 0h, 0m, ...)
, which makes sense in most cases instead of June of year 0. If we parse day "20", we get a date (current year, current month, 20th day, 0h, 0m, 0s, ...)
, which makes sense in most cases instead of day 20 of January of year 0. If we parse minute 30, we get a date (current year, current month, current day, current hour, 30m, 0s, ...)
, and so on.
I believe in two things here: (a) it's good to follow the same rule independently of the date field (the above rule is the same for year, month, minute, second); (b) it should allow other use cases easily in user land, i.e., if user wants to parse a minute only (isn't interested in other fields) it's easy to cherry-pick minute only, for example: parsedMinute.getMinutes()
. So, I vote not to change this behavior.
Please, just let me know if I misunderstood you.
I could put it back, but I think this approach is less bug-laden.
@rxaviers Can I ask what is the main source for calendarPreferenceData
object and is this the most comprehensive available calendar preference data?
Thanks
Info about it can be found at http://www.unicode.org/reports/tr35/tr35-dates.html#Calendar_Preference_Data, but as you can notice the info there isn't extensive. Is that what you were looking for? Any particular question?
@rxaviers Great! That answers my question. I need to port deductibility features of this repo to PHP as well. Can you advise please where can I find the structured data of deduced script and country according to language and deducing the language and script according to country please.
Cheers
Hello, is persian calendar supported ? i didn't find anything about it
@AlaaL it's not supported in 1.x according to the description of the issue. There's a WIP PR that stalled.
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).
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)
Tests