2. System.Globalization名称空间

System.Globalization名称空间在C#中扮演关键角色,处理不同地区的日期、数字格式和日历类型。本文深入探讨Unicode问题,区域性和区域的差异,以及如何处理组合字符。还介绍了CultureInfo和RegionInfo类,以及如何根据区域设置格式化数字和日期。最后,讨论了排序的区域性依赖性,以及在国际化应用中如何进行独立于区域性的排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

System.Globalization名称空间包含了所有的区域性和区域类,以支持不同的日期格式、不同的数字格式。甚至由GregorianCalendar类、HebrewCalendar类和JapaneseCalendar类等表示的不同日历。使用这些类可以根据不同的地区显示不同的表示法。

本节将讨论使用System.Globalization名称空间时要考虑的如下问题:

  • Unicode问题
  • 区域性和区域
  • 显示所有区域性及其特征的例子
  • 排序

1. Unicode问题

因为一个Unicode字符有16位,所以共有65 536个Unicode字符。这对于当前在信息技术中使用的所有语言够用么?例如,汉语就需要80 000多个字符。但是,Unicode可以解决这个问题。使用Unicode必需区分基本字符和组合字符。可以给一个基本字符添加若干个组合字符,组成一个可显示的字符或一个文本元素。

例如,冰岛的字符Ogonek可以使用基本字符0x006F(拉丁小写字母o)、组合字符0x0328(组合Ogonek)和0x0304(组合Macron)组合而成,如下图所示。组合字符定义的范围是0x0300~0x0345,对于美国和欧洲市场,预定义字符有助于处理特殊的字符。字符Ogonek也可以用预定义字符0x01ED来定义。

对于亚洲市场,只有汉语需要80 000多个字符,但没有这么多的预定义字符。在亚洲语言中,总是要处理组合字符。其问题在于获取显示字符或文本元素的正确数字,得到基本字符而不是组合字符。System.Globalization名称空间提供的StringInfo类可以用于处理这个问题。

下表列出了StringInfo类的静态方法,这些方法有助于处理组合字符。

注意:

一个显示字符可以包含多个Unicode字符。要解决这个问题,如果编写的应用程序要在国际市场销售,就不应使用数据类型char,而应使用string。string可以包含由基本字符和组合字符组成的文本元素,而char不具备该作用。

2. 区域性和区域

世界分为多个区域性和区域,应用程序必须知道这些区域性和区域的差异。区域性是基于用户的语言和文化习惯的一组首选项。RFC 4646(www.ietf.org/rfc/rfc4646.txt)定义了区域性的名称,这些名称根据语言和国家或区域的不同在世界各地使用。例如,en-AU、en-CA、en-GB和en-US分别用于表示奥法利亚、加拿大、英国和美国的英语。

在System.Globalization名称空间中,最重要的类是CultureInfo。这个类表示区域性,定义了日历,数字和日期的格式,以及和区域性一起使用的排序字符串。

RegionInfo类表示区域设置(如货币),说明该区域是否使用米制系统。在某些区域,可以使用多种语言。例如,西班牙区域就有Basque(en-ES)、Catalan(ca-ES)、Spanish(es-ES)和Galician(gl-ES)区域性。一个区域可以有多种语言,同样,一种语言也可以在多个区域使用;例如,墨西哥、西班牙和危地马拉、阿根廷和秘鲁等都使用西班牙语。

本章后面将介绍一个示例应用程序,以说明区域性和区域的这些特征。

(1) 特定、中立和不变的区域性

在.NET Framework中使用区域性,必须区分3种类型:特定、中立和不变的区域性。特定的区域性与真正存在的区域性相关,这种区域性用RFC 4646定义。特定的区域性可以映射到中立的区域性。例如,de是特定区域性de-AT、de-DE、de-CH等的中立区域性。de是德语(German)的简写,AT、DE和CH分别是奥地利(Austria)、德国(Germany)和瑞士(Switzerland)等国家的简写。

在翻译应用程序时,通常不需要为每个区域进行翻译,因为奥地利和瑞士等国使用的德语没有太大的区别。所以可以使用中立的区域性来本地化应用程序,而不需要使用特定的区域性。

不变的区域性独立于真正的区域性。在文件中存储格式化的数字或日期,或通过网络把它们发送到服务器上时,最好使用独立于任何用户设置的区域性。

下图显示了区域性类型的相互关系。

(2) CurrentCulture和CurrentUICulture

 设置区域性时,必须区分用户界面的区域性和数字及日期格式的区域性。区域性与线程相关,通过这两种区域性类型,就可以把两种区域性设置应用于线程。CultureInfo类提供了静态属性CurrentCulture和CurrentUICulture。CurrentCulture属性用于设置与格式化和排序选项一起使用的区域性,而CurrentUICulture属性用于设置用户界面的语言。

使用Windows设置中的Time&Language,再从中选择Language选项,用户就可以在Windows 10操作系统中安装其他语言,如下图所示。配置为默认的语言是当前的UI区域性(CurrentUICulture)。

 要改变当前的区域性,可以使用对话框中的Additional date,time,&regional settings链接,如下图所示。其中,单击Change Date,Time,or Number Formats选项,查看如下图所示的对话框。格式的语言设置会影响当前的区域性。也可以改变独立于区域性的数字格式、时间格式、日期格式的默认设置。

这些设置都提供了很好的默认值,在许多情况下,不需要改变默认行为。如果需要改变区域性,只需要把线程的两个区域性改为Spalish区域性,如下面的代码片段所示:

            string time1 = DateTime.Now.ToString();
            Console.WriteLine(CultureInfo.CurrentCulture);
            Console.WriteLine(CultureInfo.CurrentUICulture);
            Console.WriteLine($"zh-CN: {time1}");
            Console.WriteLine();
            var ci = new CultureInfo("es-ES");
            CultureInfo.CurrentCulture = ci;
            CultureInfo.CurrentUICulture = ci;
            Console.WriteLine(CultureInfo.CurrentCulture);
            Console.WriteLine(CultureInfo.CurrentUICulture);
            string time2 = DateTime.Now.ToString();
            Console.WriteLine($"es-ES: {time2}");

默认的区域性为zh-CN,输出结果:

zh-CN
zh-CN
zh-CN: 2020/7/23 3:16:16

es-ES
es-ES
es-ES: 23/07/2020 3:16:16

(3) 数字格式化

System名称空间中的数字结构Int16、Int32和Int64等都有重载的ToString()方法。这个方法可以根据区域设置创建不同的数字表示法。对于Int32结构,ToString()方法由下述4个重载的版本:

        [NullableContextAttribute(1)]
        public override string ToString();

        [NullableContextAttribute(1)]
        public string ToString([NullableAttribute(2)] IFormatProvider? provider);

        [NullableContextAttribute(1)]
        public string ToString([NullableAttribute(2)] string? format);

        [NullableContextAttribute(2)]
        [return: NullableAttribute(1)]
        public string ToString(string? format, IFormatProvider? provider);

不在参数的ToString()方法返回一个没有格式化选项的字符串,也可以给ToString()方法传递一个字符串和一个实现IFormatProvider接口的类。

该字符串指定表示法的格式,而这个格式可以是标准数字格式化字符串或图形数字格式化字符串。对于标准数字格式化,字符串是预定义的,其中C表示货币符号,D表示输出为小数,E表示输出用科学计数法表示,F表示定点输出,G表示一般输出,N表示输出为数字,X表示输出为十六进制。对于图形数字格式化字符串,可以指定位数、节和组分隔符、百分号等。图形数字格式化字符串 ###,### 表示:两个三位数块被一个组分隔符分开。

IFormatProvider接口由NumberFormatInfo、DateTimeFormatInfo和CultureInfo类实现。这个接口定义了GetFormat()方法,它返回一个格式对象。

NumberFormatInfo类可以为数字定义自定义格式。使用NumberFormatInfo类的默认构造函数,可以创建独立与区域性的对象或不变的对象。使用这个类的属性,可以改变所有格式化选项,如正好、百分号、数字组分隔符和货币符号等。从静态属性InvariantInfo返回一个与区域性无关的只读NumberFormatInfo对象。NumberFormatInfo对象的格式化值取决于当前线程的CultureInfo类,该线程从静态属性CurrentInfo返回。

示例代码NumberAndDateFormating使用如下名称空间:

System

System.Globalization

下一个示例使用一个简单的控制台应用程序(.NET Core)项目。在这段代码中,第一个示例显示了在当前线程的区域性格式(这里是zh-CN,是操作系统的设置)中所显示的数字。第二个示例使用了带有IFormatProvider参数的ToString()方法。CultureInfo类实现了IFormatProvider接口,所以创建一个使用英国区域性的CultureInfo对象。第3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值