Introduction

There are many different calendars used throughout the world. This plugin aims to make them accessible in JavaScript in a consistent manner.

The plugin is broken up into a number of modules to allow you to customise what functionality you need.

ModulePurposeDependencies
jquery.calendars.
js
Base calendar support, with full localisation, including custom Date object and Gregorian calendar. -
jquery.calendars.
taiwan.js
Taiwanese calendar support - also known as the Minguo calendar.
Since 1.1.0.
Base
jquery.calendars.
thai.js
Thai calendar support.
Since 1.1.0.
Base
jquery.calendars.
julian.js
Julian calendar support. Base
jquery.calendars.
persian.js
Persian calendar support - also known as Iranian or Jalali calendar. Base
jquery.calendars.
islamic.js
Islamic calendar support - the 'civil 16' version. Base
jquery.calendars.
ummalqura.js
Umm al-Qura calendar support - also known as the Saudi calendar. Written by Amro Osama.
Since 1.2.1.
Base
jquery.calendars.
hebrew.js
Hebrew (civil) calendar support. Base
jquery.calendars.
ethiopian.js
Ethiopian calendar support.
Since 1.1.0.
Base
jquery.calendars.
coptic.js
Coptic calendar support.
Since 1.1.0.
Base
jquery.calendars.
nepali.js
Nepali calendar support - also known as Vikram Samvat. Written by Artur Neumann.
Since 1.2.1.
Base
jquery.calendars.
nanakshahi.js
Nanakshahi calendar support.
Since 2.0.2.
Base
jquery.calendars.
mayan.js
Mayan (Long Count) calendar support. Base
jquery.calendars.
discworld.js
Discworld calendar support.
Since 2.0.2.
Base
jquery.calendars.
plus.js
Additional calendar functionality, such as parsing and formatting dates. Base
jquery.calendars.
picker.js
A datepicker with full calendar support and localisation. Base, Plus
jquery.calendars.
picker.ext.js
Extensions to the datepicker such as alternate renderers and additional functionality. Picker
jquery.calendars.
validation.js
Validation plugin support for the datepicker. Picker
jquery.calendars.
all.js
Combines the base, plus, and datepicker modules into one. -
Calendar Basics

Each calendar provides certain basic information about itself, such as the number of months in a year, the number of days in a month, today's date, etc. It also validates all dates that it uses and throws an error if there is a problem. You can check a date via the isValid function without raising an error.

You retrieve a calendar implementation via the $.calendars.instance() function by supplying the calendar name and localisation language. Both parameters are optional and default to 'gregorian' and 'en' respectively.

Sample date: (mm/dd/yyyy)

Is valid:

Leap year:

Months in the year:

Days in the year:

Days in the month:

Days in a week:

Week day:

Today:

Epoch:

Month of the year:

Day of the year:

Week of the year:

Day of the week:

To Julian Day Number:

To JavaScript Date:

$('#basicsButton').click(function() {
	try {
		$('#basics input:not(#basicsDate)').val('');
		var calendar = $.calendars.instance($('#basicsCalendar').val());
		var date = $('#basicsDate').val().split('/');
		var year = parseInt(date[2], 10);
		var month = parseInt(date[0], 10);
		var day = parseInt(date[1], 10);
		var isValid = calendar.isValid(year, month, day);
		$('#basicsToday').val(calendar.formatDate('mm/dd/yyyy', calendar.today()));
		$('#basicsValid').val(isValid ? 'Yes' : 'No');
		if (!isValid) return;
		$('#basicsLeap').val(calendar.leapYear(year) ? 'Yes' : 'No');
		$('#basicsEpoch').val(calendar.epoch(year));
		$('#basicsMiY').val(calendar.monthsInYear(year));
		$('#basicsMoY').val(calendar.monthOfYear(year, month));
		$('#basicsDiY').val(calendar.daysInYear(year));
		$('#basicsDoY').val(calendar.dayOfYear(year, month, day));
		$('#basicsWoY').val(calendar.weekOfYear(year, month, day));
		$('#basicsDiM').val(calendar.daysInMonth(year, month));
		$('#basicsDiW').val(calendar.daysInWeek());
		$('#basicsDoW').val(calendar.dayOfWeek(year, month, day));
		$('#basicsWD').val(calendar.weekDay(year, month, day) ? 'Yes' : 'No');
		$('#basicsJD').val(calendar.toJD(year, month, day));
		$('#basicsJSD').val(calendar.toJSDate(year, month, day));
	}
	catch (e) {
		alert(e);
	}
});
Date Conversion

Since Julian Day Number (the number of days since 1 January 4713 BC - Julian Calendar) is used as a common reference point, it is easy to convert dates between the different calendars.

Also shown here are further details about a date: the day of the week, the day and week of the year, and whether it is in a common or leap year. Some calendars provide extra information about a date, such as is shown for the Hebrew and Mayan calendars.

Julian day number:

Gregorian calendar:

 

Taiwan calendar:

 

Thai calendar:

 

Julian calendar:

 

Persian calendar:

 

Islamic calendar:

 

Umm al-qura calendar:

 

Hebrew calendar:

 

 

Ethiopian calendar:

 

Coptic calendar:

 

Nepali calendar:

 

Nanakshahi calendar:

 

Mayan calendar:

 

 

Discworld calendar:

 

  Century:

function convertDates(name) {
	try {
		var jd = (name == 'jd' ? parseFloat($('#jDate').val(), 10) :
			$.calendars.instance(name).newDate(
				parseInt($('#' + name + 'Year').val(), 10),
				parseInt($('#' + name + 'Month').val(), 10),
				parseInt($('#' + name + 'Day').val(), 10)).toJD());
	}
	catch (e) {
		alert(e);
		return;
	}
	$('#jDate').val(jd);
	showDate('gregorian', jd);
	showDate('taiwan', jd);
	showDate('thai', jd);
	showDate('julian', jd);
	showDate('persian', jd);
	showDate('islamic', jd);
	showDate('ummalqura', jd);
	var extraInfo = showDate('hebrew', jd);
	$('#hebrewType').val(!extraInfo ? '' : extraInfo.yearType);
	showDate('ethiopian', jd);
	showDate('coptic', jd);
	showDate('nepali', jd);
	showDate('nanakshahi', jd);
	extraInfo = showDate('mayan', jd);
	$('#mayanTzolkin').val(!extraInfo ? '' :
		'Tzolkin: ' + extraInfo.tzolkinTrecena + ' ' + extraInfo.tzolkinDayName);
	$('#mayanHaab').val(!extraInfo ? '' :
		'Haab: ' + extraInfo.haabDay + ' ' + extraInfo.haabMonthName);
	extraInfo = showDate('discworld', jd);
	$('#discworldCentury').val(extraInfo.century);
}

function showDate(name, jd) {
	try {
		$('#convert *:input[id^=' + name + ']').val('');
		var date = $.calendars.instance(name).fromJD(jd);
		$('#' + name + 'Year').val(date.formatYear());
		$('#' + name + 'Month').val(date.month());
		$('#' + name + 'Day').val(date.day());
		$('#' + name + 'WeekDay').
			val(date.calendar().local.dayNames[date.dayOfWeek()]);
		$('#' + name + 'YearDay').val('Day ' + date.dayOfYear());
		$('#' + name + 'Week').val('Week ' + date.weekOfYear());
		$('#' + name + 'LeapYear').
			val(date.leapYear() ? 'Leap year' : 'Common year');
		return date.extraInfo();
	}
	catch (e) {
		alert(e);
		return null;
	}
}

$('#convert button').click(function() {
	convertDates($(this).attr('id').replace(/Convert/, ''));
});
Date Formats

The plus module adds date parsing and formatting to the calendars. Use combinations of the characters below, with the default depending on the calendar used. You must quote (using ') any text that matches these formats to avoid it being replaced.

Or you can use one of the predefined formats:

Parse from:

 

Format as:

 

var calendar = $.calendars.instance();
var formats = ['mm/dd/yyyy', 'M d, yyyy', 'MM d, yyyy',
	'mm/dd/yy', 'dd/mm/yyyy', 'mm/dd/yyyy (\'w\'w)',
	'\'Day\' d \'of\' MM, YYYY', calendar.ATOM, calendar.COOKIE,
	calendar.FULL, calendar.ISO_8601, calendar.JULIAN,
	calendar.RFC_822, calendar.RFC_850, calendar.RFC_1036,
	calendar.RFC_1123, calendar.RFC_2822, calendar.RSS,
	calendar.TICKS, calendar.TIMESTAMP, calendar.W3C];

$('#dateFormat').click(function() {
	try {
		var calendar = $.calendars.instance($('#parseCalendar').val());
		var date = calendar.parseDate(formats[$('#parseFormat').val()],
			$('#parseDate').val());
		calendar = $.calendars.instance($('#formatCalendar').val());
		date = calendar.fromJD(date.toJD());
		$('#formatDate').val(
			calendar.formatDate(formats[$('#formatFormat').val()], date));
	}
	catch (e) {
		alert(e);
	}
});
Updating Dates

Dates may be updated directly by setting the day, month, and/or year. They can also be updated by adding a number of periods to an existing date. Use 'd' for days, 'w' for weeks, 'm' for months, or 'y' for years. The number of periods may be negative.

If adding months or years and the resulting month has fewer days than the original, the date is set to the last day of the new month.

The updated date is returned by the add function, allowing you to chain several additions together.

Starting date:

Add:

 

$('#addButton').click(function() {
	try {
		var calendar = $.calendars.instance($('#addCalendar').val());
		var date = calendar.parseDate('mm/dd/yyyy', $('#addDate').val());
		var amount = parseInt($('#addAmount').val(), 10);
		var period = $('#addPeriod').val();
		date.add(amount, period);
		$('#addResult').val(calendar.formatDate('mm/dd/yyyy', date));
	}
	catch (e) {
		alert(e);
	}
});
Calendar Localisations

You can localise the calendars for other languages. Select a language to change the text and settings. Right-to-left languages are also supported.

Select localisation

Days and months

Format and first day   

$('#l10nCal').change(function() {
	$('#l10nLanguage').html(formatLanguages($(this).val())).change();
});

$('#l10nLanguage').change(function() {
	var name = $('#l10nCal').val();
	var loadName = (name == 'julian' ? '' : name);
	var lang = $(this).val();
	if (lang) {
		$.localise('js/jquery.calendars' + (loadName ? '.' : '') + loadName, lang);
	}
	var calendar = $.calendars.instance(name, lang);
	$('#l10n ul').toggleClass('l10nRTL', calendar.local.isRTL);
	var list = '';
	for (var i = 0; i < calendar.local.dayNames.length; i++) {
		list += '<li>' + calendar.local.dayNames[i] + '</li>';
	}
	$('#l10nDays').empty().html(list);
	list = '';
	for (var i = 0; i < calendar.local.monthNames.length; i++) {
		list += '<li>' + calendar.local.monthNames[i] + '</li>';
	}
	$('#l10nMonths').empty().html(list);
	$('#l10nFormat').val(calendar.local.dateFormat);
	$('#l10nFirstDay').val(calendar.local.dayNames[calendar.local.firstDay]);
});

You need to load the appropriate language package (see list below), which adds a language set ($.calendars.calendars.<type>.regionalOptions[langCode]) to a particular calendar implementation.

<script type="text/javascript" src="jquery.calendars-fr.js"></script>

or

<script type="text/javascript" src="jquery.calendars.persian-fa.js"></script>

Then, when you instantiate a calendar, you can specify which localisation to use:

$.calendars.instance('gregorian'); // Gregorian in English (default)

or

$.calendars.instance('persian', 'fa'); // Persian in Farsi
Date Picker

A datepicker based on a calendar can easily be added to a text field or division with appropriate default settings when using the picker module.

See the datepicker page for more details and examples.

Datepicker calendar: Month: Year:

 

$('#defaultPicker').calendarsPicker(
	{monthsToShow: [2, 3], showOtherMonths: true,
	onSelect: function(date) { alert('You picked ' + date[0].formatDate()); }});

$('#pickerButton').click(function() {
	try {
		var calendar = $.calendars.instance($('#pickerCal').val());
		$('#defaultPicker').calendarsPicker('option', {calendar: calendar}).
			calendarsPicker('showMonth', parseInt($('#pickerYear').val(), 10),
				parseInt($('#pickerMonth').val(), 10));
	}
	catch (e) {
		alert(e);
	}
});
AIR Application

The calendars and datepicker are available as a standalone AIR application. It displays a number of months and lets you configure which calendar to use, its localisation, its styling, and a few other items. You can also convert between dates in the various calendars.

World Calendars - AIR World Calendars - Convert
World Calendars - Setup

In the Wild

This tab highlights examples of this plugin in use "in the wild".

To add another example, please contact me (wood.keith{at}optusnet.com.au) and provide the plugin name, the URL of your site, its title, and a short description of its purpose and where/how the plugin is used.

Quick Reference

A list of available fields and functions. For more detail see the documentation reference page.

$.calendars.instance(name, language) // Retrieve calendar
$.calendars.newDate(year, month, day, calendar, language) // Create a date

calendar.name // The calendar name
calendar.jdEpoch // Julian date of start of epoch
calendar.hasYearZero // True if has a year zero, false if not
calendar.minMonth // The minimum month number
calendar.firstMonth // The first month in the year
calendar.minDay // The minimum day number
calendar.regionalOptions // Localisations
calendar.newDate(year, month, day) // Create a date
calendar.today()
calendar.leapYear(year) // Is a leap year?
calendar.epoch(year) // BCE/CE
calendar.formatYear(year) // Formatted year
calendar.monthsInYear(year)
calendar.monthOfYear(year, month) // To ordinal month
calendar.fromMonthOfYear(year, ord) // From ordinal month
calendar.weekOfYear(year, month, day)
calendar.daysInYear(year)
calendar.dayOfYear(year, month, day)
calendar.daysInMonth(year, month)
calendar.daysInWeek()
calendar.dayOfWeek(year, month, day) // 0 = Sunday, ...
calendar.weekDay(year, month, day) // Is a week day?
calendar.extraInfo(year, month, day)
calendar.add(date, offset, period) // Update a period
calendar.set(date, value, period) // Set a period
calendar.isValid(year, month, day)
calendar.toJD(year, month, day) // To Julian Day Number
calendar.fromJD(jd) // From Julian Day Number
calendar.toJSDate(year, month, day) // To JavaScript Date
calendar.fromJSDate(jsd) // From JavaScript Date

date.newDate() // Clone date
date.newDate(year, month, day) // Create a date
date.year(year) // Set year
date.year() // Get year
date.month(month) // Set month
date.month() // Get month
date.day(day) // Set day
date.day() // Get day
date.date(year, month, day) // Set date
date.leapYear() // Is a leap year?
date.epoch() // BCE/CE
date.formatYear() // Get formatted year
date.monthOfYear() // Get ordinal month
date.weekOfYear()
date.dayOfYear()
date.daysInMonth()
date.dayOfWeek() // 0 = Sunday, ...
date.weekDay() // Is a week day?
date.extraInfo()
date.add(offset, period) // Update a period
date.set(value, period) // Set a period
date.compareTo(date) // Compare to another date
date.calendar() // Underlying calendar
date.toJD() // To Julian Day Number
date.fromJD(jd) // From Julian Day Number
date.toJSDate() // To JavaScript Date
date.fromJSDate(jsd) // From JavaScript Date

// From the plus module
calendar.formatDate(format, date, settings)
calendar.parseDate(format, value, settings)
calendar.determineDate(dateSpec, defaultDate, currentDate, dateFormat, settings)
calendar.ATOM // Date formats
calendar.COOKIE
calendar.FULL
calendar.ISO_8601
calendar.JULIAN
calendar.RFC_822
calendar.RFC_850
calendar.RFC_1036
calendar.RFC_1123
calendar.RFC_2822
calendar.RSS
calendar.TICKS
calendar.TIMESTAMP
calendar.W3C
date.formatDate(format)