Skip to main content

Globalization Step-by-Step

Calendar Differences

Sorting & String Comparison Date Formatting


Overview and Description

The Gregorian calendar is used in most English speaking countries, but world-ready products should also take into consideration other calendaring systems in use worldwide. For example, there are the Japanese, the Buddhist era, the Hijri, the Hebrew lunar, and the Taiwan calendars. One of the major differences between calendars is that each calendar could have a different year value. For example, the Gregorian year 2000 is the twelfth year in the Japanese Heisei era and the year 1421 in the Hijri calendar. The first day of the year might not start on January 1. The Chinese New Year was on February 5 of the Gregorian year 2000. The length of the year and months might also vary, as well as ways of handling leap years. Or even within the same calendar, the first day of the week might start on another day besides Sunday, depending on the culture. For instance, in most of the European countries that use the Gregorian calendar, the start of the week is Monday. Unlike English (United States), there are other locales that use more than one calendar type, such as Korean.

Available calendar types for the Korean locale.

Available calendar types for the Korean locale.

The Regional And Language Options property sheet allows the user to:

  • Select an alternative calendar (if applicable to the selected locale).
  • Define a two-digit year range for each one of the available calendars.
  • Define a default long-date and short-date formatting for each available calendar type.

Although not all international calendars are provided for, there are many supported calendar types on Windows 2000 and Windows XP.

Supported calendar types in Windows 2000 and Windows XP.

Value Meaning
ENUM_ALL_CALENDARSAll applicable calendars for the specified locale
CAL_GREGORIANGregorian (localized)
CAL_GREGORIAN_USGregorian (English strings always)
CAL_JAPANJapanese Emperor Era
CAL_KOREAKorean Tangun Era
CAL_HIJRIHijri (Islamic lunar)
CAL_HEBREWHebrew (lunar)
CAL_GREGORIAN_ME_FRENCHGregorian Middle East French
CAL_GREGORIAN_XLIT_ENGLISHGregorian transliterated English
CAL_GREGORIAN_XLIT_FRENCHGregorian transliterated French

The interesting fact about NLS APIs and .NET support is that you don't need to know the target languages or how the names of days and months are translated into the target language. The system returns the translated values to you automatically.

Top of pageTop of page

Handling calendars in Win32

As you probably noticed in the last code sample, one of the arguments of the enumeration callback function for date formats is the calendar type (CALID). As mentioned earlier, for some locales more than one calendar type is available. For example, if the user locale is set to Hebrew, then the enumeration would return long-date formats for both Gregorian and Hebrew lunar calendars. For most of the applications, the basic functionality made available by GetDateFormat, which allows the date to be represented in the currently selected calendar and format, is enough. However, some applications might want to have more control over the way this information is presented and eventually select the calendar type in which the date is being displayed. There are several Win32 NLS APIs that allow you to manipulate calendar types.

The EnumCalendarInfoEx API can be used to enumerate all calendar information (such as names of calendars, names of days of the week, and names of months) for all applicable and available calendar types pertaining to a given ocale. The code sample enumerates the native names of all supported calendars.

// Enumerate the native calendar names for all available calendar
// types that correspond to the current user locale.
EnumCalendarInfoEx(EnumCalendarInfoProc, // enumeration callback
// fuction
LOCALE_USER_DEFAULT, // locale - any valid LCID
ENUM_ALL_CALENDARS, // does enumeration for all supported
// calendars
CAL_SCALNAME); // calendar info (return the calendar name)

// The callback function will look like:
BOOL CALLBACK EnumCalendarInfoProc(LPTSTR lpCalendarInfoString, CALID Calendar)
if (!lpCalendarInfoString)
return FALSE;
MessageBox(NULL, g_szBuf2, TEXT(&Calendars names&), MB_OK);
return TRUE;


Execution of the previous code sample would give the following result on English (United States) and Arabic (Tunisia) user locales, respectively.

Available calendar types for English (United States) and Arabic (Tunisia).

Available calendar types for English (United States) and Arabic (Tunisia).

The GetLocaleInfo API with the LOCALE_ICALENDARTYPE flag also allows you to retrieve the default calendar type currently selected by the user. Once you have retrieved the calendar you want, you can use GetCalendarInfo to retrieve specific information about that particular calendar. This information includes the following:

  • Long, short, and year/month date formats
  • Abbreviations and full names of months
  • Abbreviations and full names of days of the week
  • An integer value indicating the upper boundary of the two-digit year range
  • Native name of the calendar

In a nutshell, Win32 NLS APIs give your application full control over the way a date can be represented by letting you select a given calendar type and a given formatting type for that calendar. In fact, NLS APIs give you more flexibility than you would ever need. As stated earlier, GetDateFormat is probably enough to format dates in a way that's locale-aware.

Top of pageTop of page

Handling calendars in Web Pages

Scripting technology does not offer the same flexibility to manipulate dates and calendars as NLS APIs do in the case of Win32 programming. However, the FormatDateTime function lets you display dates in the user's preferred culture, in both short-date and long-date formats.

Top of pageTop of page

Handling calendars in .NET Framework

Similar to the Win32 paradigm - the .NET Framework handles dates in the Gregorian calendar by using data structures. Therefore, when you use the methods provided by the DateTime structure, you must be aware that the members such as the DateTime.Day property, the DateTime.Month property, the DateTime.Year property, and the DateTime.AddDays method are based on the Gregorian calendar. Even if you change the current calendar in your application's code or change date and time settings through the Regional And Language Options property sheet, the Gregorian calendar is still used to perform the calculations for these methods. This functionality prevents the arithmetic performed by these methods from being corrupted by a user's settings. If you want to perform culture-sensitive date and time operations based on the current calendar, you must use the DateTimeFormatInfo.Calendar property to call methods provided by the Calendar class such as Calendar.GetDayOfMonth, Calendar.GetMonth, Calendar.GetYear, and Calendar.AddDays.

To handle native calendar types, the .NET Framework provides the Calendar class as well as the following Calendar implementations: GregorianCalendar, HebrewCalendar, HijriCalendar, JapaneseCalendar, JulianCalendar, KoreanCalendar, TaiwanCalendar, and ThaiBuddhistCalendar. Other things you can use include the CultureInfo class, which has a CultureInfo.Calendar property that specifies a culture's default calendar. The CultureInfo.OptionalCalendars property specifies the optional calendars supported by a culture.

The following code example in C# creates CultureInfo objects for the culture "th-TH" (Thai in Thailand) and displays the default and optional calendars for each culture. The GregorianCalendar is further divided into subtypes by the GregorianCalendar.CalendarType property. In this example, each time the calendar is determined to be Gregorian, the CalendarType value is retrieved and displayed.

using System;
using System.Globalization;
public class TestClass
public static void Main()
// Create a CultureInfo object for Thai in Thailand.
CultureInfo th = new CultureInfo("th-TH");

protected static void DisplayCalendars(CultureInfo cultureinfo)
CultureInfo ci = new CultureInfo(cultureinfo.ToString());

// Display the default calendar for the culture.
if (ci.Calendar is GregorianCalendar)
Console.WriteLine ("\n\n");
Console.WriteLine (
"The default calendar for the {0} culture is: \n{1}\n\n",
ci.DisplayName.ToString(), ci.Calendar.ToString() +
" subtype " +
Console.WriteLine ("\n\n");
Console.WriteLine (
"The default calendar for the {0} culture is: \n{1}\n\n",
ci.DisplayName.ToString(), ci.Calendar.ToString());
// Display the optional calendars for the culture.
Console.WriteLine (
"The optional calendars for the {0} culture are: ",
for (int i = ci.OptionalCalendars.GetLowerBound(0); i <=
ci.OptionalCalendars.GetUpperBound(0); i++ )

if (ci.OptionalCalendars[i] is GregorianCalendar)
// Display the calendar subtype.
String CalStr = (ci.OptionalCalendars[i].ToString() +
" subtype " +
Console.WriteLine (ci.OptionalCalendars[i].ToString());

This code produces the following output:  

The default calendar for the Thai (Thailand) culture is:

The optional calendars for the Thai (Thailand) culture are:
subtype Localized

As you can see, the .NET Framework offers a UI that's extensive, yet flexible and easy to use for date and calendar formatting.

Sorting & String Comparison  Date Formatting


Top of pageTop of page Number Formatting3 of 11 Telephone Number