New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-Gregorian calendars inside moment.js #1454

Open
ebraminio opened this Issue Feb 1, 2014 · 15 comments

Comments

Projects
None yet
@ebraminio
Contributor

ebraminio commented Feb 1, 2014

MediaWiki's date formatter can easily generates non-Gregorian calendars output.

This is a copy of the related parts of the documentation:

Non-Gregorian calendars
Islamic
xmj Day of the month
xmF Full month name
xmn Month index
xmY Full year
Iranian (Jalaly)
xij Day of the month
xiF Full month name
xin Month index
xiY Full year
xiy 2-digit year
Hebrew
xjj Day of the month
xjF Full month name
xjt Number of days in month
xjx Genitive form of the month name
xjn Month number
xjY Full year
Thai solar
xkY Full year
Minguo/Juche year
xoY Full year
Japanese nengo
xtY Full year

With considering this and an example calendar algorithm from MediaWiki, this is my proposal:

  • Define a separate folder/script inside moment.js project for actual calendar algorithm implementation (xij, xiF, . . .) but don't include that on moment.js core
  • Original modules of extension calendars should just include the English translation and locales modules which handle the translation of needed calendars for a locale. A fallback to English (which provided by the algorithm itself) should be done also when translation is not available on a specific locale module
  • Locale module should define their default date format with their related calendars
  • Similar to MediaWiki date format convention, what available on above table (or same moment-jalaali?)

With this design, using Iranian calendar on English and Gregorian calendar on Persian for example [both use-cases are important] would be easy.

I think if we decide about a design, implementing the needed change will be easier.

globalize also has support of Persian calendar for example.

Thank you and sorry about spell/grammar/facts errors available

@ichernev

This comment has been minimized.

Contributor

ichernev commented Feb 1, 2014

OK, so you're suggesting

  • add support for plug-in-able calendar systems
  • add support for plug-in-able format tokens

I have a few questions:

  • don't we also need plug-in-able parsing tokens
  • do you expect to add special functions for those calendars (like getJapaneseYear) or we can just use an extensible get/set interface. The names can be the x-names from above, although I think there should be a longer, more readable version
  • what about local, utc and zoned version of those. Is there anything special to know?

extensible get/set

moment.registerUnit(name, getter, setter)
  • name is year (built-in), xmj (plug-in), etc
  • getter = function(moment, name) {} returning the value of the unit for a given moment object. name is given to allow reuse
  • setter = function(moment, value, name) {} setting the value of the unit for the given moment object. name is given to allow reuse

extensible parsing tokens

moment.registerParseToken(token_regex, string_regex[, loose_string_regex], handler)
  • token_regex is like xmj
  • string_regex is a regex used to match in strict parsing, for example\d{3}
  • loose_string_regex is a regex to use in non-strict parsing. Defaults to string_regex
  • handler = function(token, parsedInput, config) record a parsed token into config, for example (for all /xm./ tokens)
handler = function(token, parsedInput, config) {
  config._xm[token.charAt(2)] = parseInt(parsedInput, 10)
}

extensible converters (calendars)

moment.registerConverter(converter, inputFmt, outputFmt)
  • converter = function(config) {} converters the data stored in config from the handler to something understandable. Right now moment supports isoweek/isoWeekDay/isoWeekYear, week/weekDay/weekYear, year/dayOfYear, and day/month/year.
  • inputFmt -- the name of the format from which this is converting
  • outputFmt -- the name of the format to which this is converting

For example {inputFmt: 'xm', outputFmt: 'dayOfYear'} (but I really don't like the name xm).

input/output formats would be used to define in which orders should the converters run, and would enable sharing of code in the converter. We might need to also record which converters need to run based on the format tokens used, so that we don't run 100 unused converters. We can also get rid of them and depend on the registration order (run last registered first).

extensible formatting tokens

moment.registerFormatToken(token, formatter)
  • token is like MM
  • formatter = function(moment, token) {} returns the string to be displayed

@icambron any thoughts? I think this is a good candidate for the 3.0 release. It would need moderate refactoring throughout the code, but it shouldn't be too hard.

@ebraminio

This comment has been minimized.

Contributor

ebraminio commented Feb 1, 2014

Excellent!

  • Yes, I guess
  • I don't think
  • No. I don't remember anything like this on MediaWiki at least

I like a transparent solution where a small project won't need to care about local calendars but would automatically get a good localized UI but also a more advance project can have options for doing different things. On libicu every locale has a default calendar, Persian (Iranian) calendar for fa and this. Instead complete transparency, another solution could be providing some tokens for locale preferred calendars (alias to their real token but independent from exact calendar).

@ghost

This comment has been minimized.

ghost commented Sep 8, 2014

+1

1 similar comment
@robink-teleopti

This comment has been minimized.

robink-teleopti commented Oct 9, 2014

+1

@Nate-Wilkins

This comment has been minimized.

Nate-Wilkins commented Jan 9, 2015

@ichernev How far along is this feature? This seems like it could be tied into extensibility with #1241

@glittle

This comment has been minimized.

glittle commented Jun 20, 2016

What is the status of pluggable calendar systems? Is it possible today? Is there documentation somewhere? Or does it still require plugins to implement?

@mj1856

This comment has been minimized.

Member

mj1856 commented Jun 21, 2016

Still requires plugins. A few are mentioned in the docs.

@mhf-ir

This comment has been minimized.

mhf-ir commented Jul 5, 2016

For better algorithm of special calendars reference is here: with C,C++ and Java codes :
http://userguide.icu-project.org/datetime/calendar

  • Japanese
  • Buddhist
  • Chinese
  • Persian
  • Indian
  • Islamic
  • Hebrew
  • Indian
  • Coptic
  • Ethiopic

This will help for better i18n and l10n apps

@sandstrom

This comment has been minimized.

sandstrom commented Jul 27, 2016

How common are the other calendars?

I know they are useful for traditional festivities and religious events. But to what extent are they really used in these countries in day-to-day activities? (like scheduling an appointment with a dentist) I'm just curious!

@glittle

This comment has been minimized.

glittle commented Jul 28, 2016

I don't know about others, but my interest is in the Wondrous calendar (Badí'). So far, it is a religious calendar used by the Baha'i Faith to schedule religious events, etc. However, at its core, it is a very practical solar calendar that will likely become better known in the years to come.

@ebraminio

This comment has been minimized.

Contributor

ebraminio commented Feb 19, 2017

https://github.com/catull/calendariale is a complete and wonderful calendar converter implementation, I hope it could be used directly by this project someday.

@ebraminio

This comment has been minimized.

Contributor

ebraminio commented Feb 19, 2017

Also in the meanwhile, browser makers have made an implementation of local dates accesible throughout i18n API. For example, new Date().toLocaleString('fa') now returns a fully localized formatted string with native Persian calendar, but it is not very flexible and customizable.

@behrang

This comment has been minimized.

behrang commented Feb 23, 2017

Hello. I'm author of moment-jalaali and some other Persian calendar implementations in Jalaali.

While developing moment-jalaali, my problem was moment's lack of support for calendar systems. Since I needed to use both calendars (Gregorian and Jalaali) in my applications, I introduced new formatting/parsing tokens (like jYY, jM, jD). However, when people wanted to use moment-jalaali for date pickers, it was a very difficult task, since date pickers' codebase needed substantial changes and everywhere .month(), .year(), etc. were used needed to change. We tried a few times to fix this problem, but we failed and it is still an open issue.

I think if moment supports the concept of calendar systems and offloads the responsibility of calendar conversion to plugins, the problem will be fixed. For this, I don't think there is any need for new formatting/parsing tokens (at least for Persian calendar). However, everywhere calendar date is changed, should be refactored to support pluggable calendars.

So for example, constructing new moment with a different calendar (moment({calendar: 'Persian'})), getting date part (.year(), .dayOfYear(), .isLeapYear(), .daysInMonth()), setting it (.month(4)), adding or subtracting (.add(1, 'year'), .startOf('month')), and formatting or parsing should be handled by plugins.

(@sandstrom Persian calendar is the official calendar in Iran and it is used everywhere, including scheduling appointments, banking, new year ceremony, ...).

@mj1856

This comment has been minimized.

Member

mj1856 commented Apr 12, 2017

Relevent to this discussion also: tc39/proposal-temporal#5

@tomerm

This comment has been minimized.

tomerm commented Jun 26, 2017

Support for non Gregorian calendars also assumes support for different types of numbering systems. For example:

Is there any plan to leverage http://numeraljs.com/ library for that purpose or moment.js envision development of local module / component for that purpose ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment