循序渐进全球化
日历差异
本页内容
概述和说明
Win32 中的日历处理
网页中的日历处理
.NET Framework 中的日历处理
概述和说明
虽然大多数说英语的国家/地区都使用公历,但作为全球通用产品还应考虑全球使用的其他日历系统。例如,有日本历、佛教历、回历、希伯来阴历和中国台湾历。各日历之间的一个主要差别是每种日历可能有不同的年份值。例如,公历 2000 是日本平成 12 年,是回历 1421 年。每年的第一天可能不是始于 1 月 1 日。在公历 2000 年,中国的新年是 2 月 5 日。年份和月份的长度也可能有所不同,此外还有闰年的处理方式。即使使用同样的日历,每周的第一天也并不都是始于星期日,具体要取决于文化。例如,在采用公历的大多数欧洲国家/地区中,每周的第一天是星期一。与英语(美国)不同,还有其他一些区域设置使用多种日历类型,例如韩语。
韩语区域设置的可用日历类型。
利用“区域和语言选项”属性表,用户可以:
- 选择备用日历(如果适用于所选区域设置)。
- 为每个可用日历定义一个两位数的年份范围。
- 为每个可用日历类型定义默认的长日期和短日期格式。
虽然 Windows 2000 和 Windows XP 并未提供全部的国际日历,但也提供了许多支持的日历类型。
Windows 2000 和 Windows XP 中支持的日历类型。
值 | 含义 |
ENUM_ALL_CALENDARS | 适用于指定区域设置的所有日历 |
CAL_GREGORIAN | 公历(本地化的) |
CAL_GREGORIAN_US | 公历(始终是英语字符串) |
CAL_JAPAN | 日本日历(君主纪元) |
CAL_TAIWAN | 中国台湾 |
CAL_KOREA | 朝鲜日历(檀君纪元) |
CAL_HIJRI | 回历(伊斯兰历) |
CAL_THAI | 泰国语 |
CAL_HEBREW | 希伯来日历(阴历) |
CAL_GREGORIAN_ME_FRENCH | 公历(中东法语) |
CAL_GREGORIAN_ARABIC | 公历(阿拉伯语) |
CAL_GREGORIAN_XLIT_ENGLISH | 公历(转译英语) |
CAL_GREGORIAN_XLIT_FRENCH | 公历(转译法语) |
有关 NLS API 和 .NET 支持的一个有趣事实是,您不需要知道目标语言,也不需要知道如何将日期和月份名称翻译成目标语言。系统会自动将翻译后的值返回给您。
返回页首
Win32 中的日历处理
您可能已经在上一个代码示例中注意到,日期格式的枚举回调函数的其中一个参数是日历类型 (CALID)。正如先前所述,对于某些区域设置,可以使用多个日历类型。例如,如果用户区域设置被设置为希伯来语,则无论是对于公历还是对于希伯来阴历,枚举都将返回长日期格式。对于大多数应用程序,GetDateFormat(它允许以当前所选的日历和格式显示日期)提供的基本功能已经足够。但是,一些应用程序可能希望对此信息的显示方式进行更多的控制,因此最终选择了当前显示日期所使用的日历类型。有多个 Win32 NLS API 允许您处理日历类型。
EnumCalendarInfoEx API 可用于枚举与指定区域设置相关的所有适用和可用日历类型的全部日历信息(如日历名称、一周中每一天的名称和月份名称)。下面的代码示例将枚举所有受支持日历的固有名称。
// Enumerate the native calendar names for all available calendar// types that correspond to the current user locale.EnumCalendarInfoEx(EnumCalendarInfoProc, // enumeration callback// fuctionLOCALE_USER_DEFAULT, // locale - any valid LCIDENUM_ALL_CALENDARS, // does enumeration for all supported// calendarsCAL_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;}
针对英语(美国)和阿拉伯语(突尼斯)用户区域设置执行上述代码示例将分别得到以下结果。
英语(美国)和阿拉伯语(突尼斯)的可用日历类型。
带有 LOCALE_ICALENDARTYPE 标记的 GetLocaleInfo API 还允许您检索用户当前选择的默认日历类型。检索到所需的日历之后,即可使用 GetCalendarInfo 来检索有关该特定日历的具体信息。此信息包括以下内容:
- 长/短年/月份日期格式
- 月份的缩写和全称
- 一周中每一天的缩写和全称
- 一个整数,表示两位数年份范围的上限
- 日历的固有名称
简言之,Win32 NLS API 允许您为该日历选择给定的日历类型和给定的格式类型,从而为您的应用程序提供对日期显示方式的完全控制。在实际操作中,NLS API 可为您带来空前的灵活性。如前所述,使用 GetDateFormat 即足可以通过可识别区域设置的方式来设置日期格式。
返回页首
网页中的日历处理
脚本技术在处理日期和日历时并不像 NLS API 在 Win32 编程中那样灵活。但是,FormatDateTime 函数允许您以长短两种日期格式来显示用户的首选文化中的日期。
返回页首
.NET Framework 中的日历处理
与 Win32 模式相似,.NET Framework 通过使用数据结构来处理公历日期。因此,当您使用 DateTime 结构提供的方法时,必须要意识到成员(如 DateTime.Day 属性、DateTime.Month 属性、DateTime.Year 属性和 DateTime.AddDays 方法)是基于公历的。即使您在应用程序的代码中更改了当前日历或者通过“区域和语言选项”属性表更改了日期和时间设置,仍然是采用公历来执行这些方法的计算。此功能可防止这些方法所执行的运算被用户的设置所破坏。如果您要根据当前日历来执行区分文化的日期和时间操作,则必须使用 DateTimeFormatInfo.Calendar 属性来调用由 Calendar 类提供的方法(如 Calendar.GetDayOfMonth、Calendar.GetMonth、Calendar.GetYear 和 Calendar.AddDays)。
为处理固有日历类型,.NET Framework 提供了 Calendar 类以及下列 Calendar 实现:GregorianCalendar、HebrewCalendar、HijriCalendar、JapaneseCalendar、JulianCalendar、KoreanCalendar、TaiwanCalendar 和 ThaiBuddhistCalendar。您可以使用的其他内容还包括 CultureInfo 类,它拥有 CultureInfo.Calendar 属性,可用来指定文化的默认日历。CultureInfo.OptionalCalendars 属性可指定某种文化支持的可选日历。
以下 C# 代码示例将为文化 "th-TH"(泰语,泰国)创建 CultureInfo 对象,并显示每个文化的默认和可选日历。通过 GregorianCalendar.CalendarType 属性,GregorianCalendar 被进一步划分为若干子类型。 在本例中,每当日历被确定为使用公历时,系统都会检索和显示 CalendarType 值。
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");DisplayCalendars(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 " +((GregorianCalendar)ci.Calendar).CalendarType.ToString());elseConsole.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: ",ci.DisplayName.ToString());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 " +((GregorianCalendar)ci.OptionalCalendars[i]).CalendarType.ToString());Console.WriteLine(CalStr);}elseConsole.WriteLine (ci.OptionalCalendars[i].ToString());}}}
此代码将产生以下输出:
The default calendar for the Thai (Thailand) culture is:System.Globalization.ThaiBuddhistCalendarThe optional calendars for the Thai (Thailand) culture are:System.Globalization.ThaiBuddhistCalendarSystem.Globalization.GregorianCalendarsubtype Localized
正如您所看到的,.NET Framework 为设置日期和日历格式提供了一个 UI,不但应用范围广,而且还灵活易用。
返回页首 | 第 3 页,共 11 页 |